CRITICAL FIXES: Scan script integrity and reliability improvements

FIXES:
- Create log/results directories before use (prevents all append operations from failing)
- Add error checking for RKHunter database/baseline updates
- Background Maldet scans with proper PID tracking and wait validation
- Add PID validation before all wait commands (ImunifyAV, ClamAV)
- Remove unused TOTAL_MALDET_HITS variable
- Rename FILES_SCANNED to context-specific names (CLAMAV/MALDET) for clarity

IMPACT:
- Fixes log file failures that were silently discarding scanner output
- Improves diagnostics with proper error logging for RKHunter initialization
- Enables parallel execution of Maldet scans across multiple paths
- Prevents wait command failures from invalid PIDs
- Eliminates variable naming confusion across scanner implementations

These fixes address all 7 critical issues found in audit pass 4.
This commit is contained in:
Developer
2026-03-20 18:32:31 -04:00
parent 7b895b9571
commit d72f824aea
+58 -23
View File
@@ -676,6 +676,9 @@ SCAN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="$SCAN_DIR/logs"
RESULTS_DIR="$SCAN_DIR/results"
# Create log and results directories
mkdir -p "$LOG_DIR" "$RESULTS_DIR"
# Session info
SESSION_LOG="$LOG_DIR/session.log"
SUMMARY_FILE="$RESULTS_DIR/summary.txt"
@@ -827,8 +830,16 @@ else
log_message "RKHunter: Installing via yum..."
if yum install -y rkhunter &>/dev/null; then
# Update definitions and initialize baseline
rkhunter --update &>/dev/null
rkhunter --propupd &>/dev/null
if rkhunter --update &>/dev/null; then
log_message "RKHunter: Database update successful"
else
log_message "WARNING: RKHunter database update failed"
fi
if rkhunter --propupd &>/dev/null; then
log_message "RKHunter: Property baseline created"
else
log_message "WARNING: RKHunter property baseline creation failed"
fi
AVAILABLE_SCANNERS+=("rkhunter")
RKHUNTER_TEMP_INSTALLED=true
@@ -842,8 +853,16 @@ else
log_message "RKHunter: Installing via apt-get..."
if apt-get update &>/dev/null && apt-get install -y rkhunter &>/dev/null; then
# Update definitions and initialize baseline
rkhunter --update &>/dev/null
rkhunter --propupd &>/dev/null
if rkhunter --update &>/dev/null; then
log_message "RKHunter: Database update successful"
else
log_message "WARNING: RKHunter database update failed"
fi
if rkhunter --propupd &>/dev/null; then
log_message "RKHunter: Property baseline created"
else
log_message "WARNING: RKHunter property baseline creation failed"
fi
AVAILABLE_SCANNERS+=("rkhunter")
RKHUNTER_TEMP_INSTALLED=true
@@ -1007,8 +1026,13 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
IMUNIFY_PID=$!
# Monitor with simple timeout (don't try to parse imunify status which hangs)
wait $IMUNIFY_PID
if [ -n "$IMUNIFY_PID" ] && kill -0 "$IMUNIFY_PID" 2>/dev/null; then
wait "$IMUNIFY_PID"
IMUNIFY_EXIT=$?
else
log_message "ERROR: ImunifyAV PID not found for $path"
IMUNIFY_EXIT=1
fi
if [ "$IMUNIFY_EXIT" -eq 124 ]; then
log_message "ERROR: ImunifyAV scan timed out after 2 hours for $path"
@@ -1127,8 +1151,13 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
done
# Wait for scan to complete and get exit code
wait $CLAM_PID
if [ -n "$CLAM_PID" ] && kill -0 "$CLAM_PID" 2>/dev/null; then
wait "$CLAM_PID"
CLAM_EXIT=$?
else
log_message "ERROR: ClamAV PID not found (scan process may have exited prematurely)"
CLAM_EXIT=1
fi
echo "" # New line after spinner
if [ "$CLAM_EXIT" -eq 124 ]; then
@@ -1153,17 +1182,17 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
grep "FOUND" "$LOG_DIR/clamav.log" 2>/dev/null | cut -d: -f1 >> "$INFECTED_LIST" 2>/dev/null || true
# Get scan stats from log (FIXED Issue 1B: robust number extraction independent of column position)
FILES_SCANNED=$(grep "Scanned files:" "$LOG_DIR/clamav.log" 2>/dev/null | tail -1 | grep -oE '[0-9]+' | head -1 || echo "0")
CLAMAV_FILES_SCANNED=$(grep "Scanned files:" "$LOG_DIR/clamav.log" 2>/dev/null | tail -1 | grep -oE '[0-9]+' | head -1 || echo "0")
CLAM_INFECTED=$(grep -c "FOUND" "$LOG_DIR/clamav.log" 2>/dev/null) || CLAM_INFECTED=0
# Validate numbers (ensure they're numeric)
if ! [[ "$FILES_SCANNED" =~ ^[0-9]+$ ]]; then
FILES_SCANNED=0
if ! [[ "$CLAMAV_FILES_SCANNED" =~ ^[0-9]+$ ]]; then
CLAMAV_FILES_SCANNED=0
fi
SCAN_END=$(date +%s)
DURATION=$((SCAN_END - SCAN_START))
echo " ✓ Scanned $FILES_SCANNED files"
echo " ✓ Scanned $CLAMAV_FILES_SCANNED files"
echo " ⏱️ Duration: ${DURATION}s"
echo ""
echo "✓ ClamAV scan complete - Found: $CLAM_INFECTED | Duration: ${DURATION}s" | tee -a "$SUMMARY_FILE"
@@ -1189,8 +1218,7 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
# Note: -a flag scans all files regardless of modification time
# Cannot combine -a with -f (file-list), so we loop through paths
MALDET_EXIT=0
TOTAL_MALDET_FILES=0
TOTAL_MALDET_HITS=0
MALDET_PIDS=()
for path in "${SCAN_PATHS[@]}"; do
if [ ! -d "$path" ]; then
@@ -1201,16 +1229,23 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
log_message "Maldet: Scanning $path with -a (all files)"
# Run with -a (scan-all) for comprehensive scanning
# Timeout after 2 hours per path
timeout 7200 maldet -b -a "$path" &>> "$LOG_DIR/maldet.log"
exit_code=$?
# Timeout after 2 hours per path, run in background for better progress tracking
timeout 7200 maldet -b -a "$path" &>> "$LOG_DIR/maldet.log" &
MALDET_PIDS+=($!)
# Give scan a moment to start
sleep 1
done
# Wait for all maldet scans to complete and collect exit codes
for pid in "${MALDET_PIDS[@]}"; do
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
wait "$pid"
exit_code=$?
if [ "$exit_code" -ne 0 ]; then
MALDET_EXIT=$exit_code
fi
# Give scan a moment to complete
sleep 2
fi
done
echo "" # New line after progress
@@ -1244,20 +1279,20 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
event_log=$(find /opt -name "*maldet*event_log" -type f 2>/dev/null | head -1)
fi
FILES_SCANNED="0"
MALDET_FILES_SCANNED="0"
MALDET_HITS="0"
if [ -f "$event_log" ]; then
# Use -E instead of -P for portability (BSD grep doesn't support -P)
# FIXED Issue 2A: Robust parsing independent of format variations
last_line=$(grep "scan completed" "$event_log" 2>/dev/null | tail -1)
FILES_SCANNED=$(echo "$last_line" | grep -oE '[0-9]+ files' 2>/dev/null | grep -oE '^[0-9]+' || echo "0")
MALDET_FILES_SCANNED=$(echo "$last_line" | grep -oE '[0-9]+ files' 2>/dev/null | grep -oE '^[0-9]+' || echo "0")
MALDET_HITS=$(echo "$last_line" | grep -oE '[0-9]+ (malware hits|malicious)' 2>/dev/null | grep -oE '^[0-9]+' || echo "0")
fi
# Validate numbers
if ! [[ "$FILES_SCANNED" =~ ^[0-9]+$ ]]; then
FILES_SCANNED=0
if ! [[ "$MALDET_FILES_SCANNED" =~ ^[0-9]+$ ]]; then
MALDET_FILES_SCANNED=0
fi
if ! [[ "$MALDET_HITS" =~ ^[0-9]+$ ]]; then
MALDET_HITS=0
@@ -1265,7 +1300,7 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
SCAN_END=$(date +%s)
DURATION=$((SCAN_END - SCAN_START))
echo " ✓ Scanned $FILES_SCANNED files"
echo " ✓ Scanned $MALDET_FILES_SCANNED files"
echo " ⏱️ Duration: ${DURATION}s"
echo ""
echo "✓ Maldet scan complete - Found: ${MALDET_HITS:-0} | Duration: ${DURATION}s" | tee -a "$SUMMARY_FILE"