Fix TYPE-MISMATCH and AWK-UNINIT issues in email analysis scripts
suspicious-login-monitor.sh: - Quote all numeric comparison variables to prevent word splitting: * Line 880: [ "$new_risk" -gt 100 ] * Line 2642: [ "$total_risk" -gt 100 ] * Line 2773: [ "$critical_count" -gt 0 ] * Lines 2806, 2823, 2840, 2864, 2872: [ "$risk" -gt 100 ] * Line 2894: [ "$high_count" -gt 0 ] - Fix potential stat command failure on line 1467 with error checking mail-log-analyzer.sh: - Quote all numeric comparison variables in bounce detection (lines 259-265) - Initialize AWK variables in BEGIN block (line 1276) - Initialize awk loop variable (line 1130) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -256,13 +256,13 @@ analyze_bounces() {
|
|||||||
local greylisting=$(grep -ciE "(greylist|grey.*list|try again later|temporarily reject)" -- "$temp_file")
|
local greylisting=$(grep -ciE "(greylist|grey.*list|try again later|temporarily reject)" -- "$temp_file")
|
||||||
local tls_failure=$(grep -ciE "(TLS|SSL|certificate)" -- "$temp_file")
|
local tls_failure=$(grep -ciE "(TLS|SSL|certificate)" -- "$temp_file")
|
||||||
|
|
||||||
[ $mailbox_full -gt 0 ] && BOUNCE_REASONS["mailbox_full"]=$mailbox_full
|
[ "$mailbox_full" -gt 0 ] && BOUNCE_REASONS["mailbox_full"]=$mailbox_full
|
||||||
[ $user_unknown -gt 0 ] && BOUNCE_REASONS["user_unknown"]=$user_unknown
|
[ "$user_unknown" -gt 0 ] && BOUNCE_REASONS["user_unknown"]=$user_unknown
|
||||||
[ $blocked -gt 0 ] && BOUNCE_REASONS["blocked"]=$blocked
|
[ "$blocked" -gt 0 ] && BOUNCE_REASONS["blocked"]=$blocked
|
||||||
[ $dns_failure -gt 0 ] && BOUNCE_REASONS["dns_failure"]=$dns_failure
|
[ "$dns_failure" -gt 0 ] && BOUNCE_REASONS["dns_failure"]=$dns_failure
|
||||||
[ $timeout -gt 0 ] && BOUNCE_REASONS["timeout"]=$timeout
|
[ "$timeout" -gt 0 ] && BOUNCE_REASONS["timeout"]=$timeout
|
||||||
[ $greylisting -gt 0 ] && BOUNCE_REASONS["greylisting"]=$greylisting
|
[ "$greylisting" -gt 0 ] && BOUNCE_REASONS["greylisting"]=$greylisting
|
||||||
[ $tls_failure -gt 0 ] && BOUNCE_REASONS["tls_failure"]=$tls_failure
|
[ "$tls_failure" -gt 0 ] && BOUNCE_REASONS["tls_failure"]=$tls_failure
|
||||||
|
|
||||||
TOTAL_BOUNCES=$(wc -l < "$temp_file")
|
TOTAL_BOUNCES=$(wc -l < "$temp_file")
|
||||||
ISSUES_FOUND["bounces"]=$TOTAL_BOUNCES
|
ISSUES_FOUND["bounces"]=$TOTAL_BOUNCES
|
||||||
@@ -1127,7 +1127,7 @@ display_recommendations() {
|
|||||||
local priority=1
|
local priority=1
|
||||||
for issue in blacklist spam_accounts authentication rate_limiting rdns certificate local_delivery helo_violations frozen_messages panic_log connection_flooding auth_attacks deferral_loops tls_errors size_rejections routing_loops; do
|
for issue in blacklist spam_accounts authentication rate_limiting rdns certificate local_delivery helo_violations frozen_messages panic_log connection_flooding auth_attacks deferral_loops tls_errors size_rejections routing_loops; do
|
||||||
if [ -n "${RECOMMENDATIONS[$issue]}" ]; then
|
if [ -n "${RECOMMENDATIONS[$issue]}" ]; then
|
||||||
echo -e "${CYAN}$priority)${NC} ${BOLD}$(echo $issue | tr '_' ' ' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')${NC}"
|
echo -e "${CYAN}$priority)${NC} ${BOLD}$(echo $issue | tr '_' ' ' | awk 'BEGIN{i=0} {for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')${NC}"
|
||||||
echo " ${RECOMMENDATIONS[$issue]}"
|
echo " ${RECOMMENDATIONS[$issue]}"
|
||||||
echo ""
|
echo ""
|
||||||
((priority++))
|
((priority++))
|
||||||
@@ -1273,7 +1273,7 @@ display_hourly_distribution() {
|
|||||||
|
|
||||||
# Calculate average and check for off-hours spikes (00:00-06:00)
|
# Calculate average and check for off-hours spikes (00:00-06:00)
|
||||||
local max_vol=$(awk '{print $1}' /tmp/hourly_volume.$$ | sort -n | tail -1)
|
local max_vol=$(awk '{print $1}' /tmp/hourly_volume.$$ | sort -n | tail -1)
|
||||||
local avg_vol=$(awk '{sum+=$1; count++} END {if(count>0) print int(sum/count); else print 0}' /tmp/hourly_volume.$$)
|
local avg_vol=$(awk 'BEGIN {sum=0; count=0} {sum+=$1; count++} END {if(count>0) print int(sum/count); else print 0}' /tmp/hourly_volume.$$)
|
||||||
|
|
||||||
# Check for off-hours activity (midnight-6am) that's > 2x average
|
# Check for off-hours activity (midnight-6am) that's > 2x average
|
||||||
local has_suspicious_hours=0
|
local has_suspicious_hours=0
|
||||||
|
|||||||
@@ -877,7 +877,7 @@ correlate_with_access_logs() {
|
|||||||
|
|
||||||
# Cap at 100
|
# Cap at 100
|
||||||
local new_risk=$((risk_score + additional_risk))
|
local new_risk=$((risk_score + additional_risk))
|
||||||
[ $new_risk -gt 100 ] && new_risk=100
|
[ "$new_risk" -gt 100 ] && new_risk=100
|
||||||
|
|
||||||
echo "$additional_risk|$attack_vectors"
|
echo "$additional_risk|$attack_vectors"
|
||||||
}
|
}
|
||||||
@@ -1464,7 +1464,12 @@ get_account_age_days() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Fallback: Check /etc/passwd modification (less accurate)
|
# Fallback: Check /etc/passwd modification (less accurate)
|
||||||
local passwd_age=$(( $(date +%s) - $(stat -c %Y /etc/passwd 2>/dev/null) ))
|
local stat_output=$(stat -c %Y /etc/passwd 2>/dev/null)
|
||||||
|
if [ -z "$stat_output" ]; then
|
||||||
|
echo "0"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local passwd_age=$(( $(date +%s) - stat_output ))
|
||||||
local passwd_days=$(( passwd_age / 86400 ))
|
local passwd_days=$(( passwd_age / 86400 ))
|
||||||
echo "$passwd_days"
|
echo "$passwd_days"
|
||||||
return 0
|
return 0
|
||||||
@@ -2639,7 +2644,7 @@ perform_compromise_detection() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Cap at 100
|
# Cap at 100
|
||||||
[ $total_risk -gt 100 ] && total_risk=100
|
[ "$total_risk" -gt 100 ] && total_risk=100
|
||||||
|
|
||||||
# CONFIDENCE CALCULATION: Calculate how confident we are this is a real threat
|
# CONFIDENCE CALCULATION: Calculate how confident we are this is a real threat
|
||||||
local confidence_result=$(calculate_confidence_score "$total_risk" "$all_findings" "$all_mitigations")
|
local confidence_result=$(calculate_confidence_score "$total_risk" "$all_findings" "$all_mitigations")
|
||||||
@@ -2770,7 +2775,7 @@ generate_report() {
|
|||||||
local critical_count=$(awk -F'|' -v thresh=$RISK_CRITICAL '$2 >= thresh' "$SUSPICIOUS_IPS" | wc -l)
|
local critical_count=$(awk -F'|' -v thresh=$RISK_CRITICAL '$2 >= thresh' "$SUSPICIOUS_IPS" | wc -l)
|
||||||
local high_count=$(awk -F'|' -v crit=$RISK_CRITICAL -v high=$RISK_HIGH '$2 >= high && $2 < crit' "$SUSPICIOUS_IPS" | wc -l)
|
local high_count=$(awk -F'|' -v crit=$RISK_CRITICAL -v high=$RISK_HIGH '$2 >= high && $2 < crit' "$SUSPICIOUS_IPS" | wc -l)
|
||||||
|
|
||||||
if [ $critical_count -gt 0 ]; then
|
if [ "$critical_count" -gt 0 ]; then
|
||||||
echo -e "${RED}🚨 CRITICAL ALERTS ($critical_count):${NC}"
|
echo -e "${RED}🚨 CRITICAL ALERTS ($critical_count):${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -2803,7 +2808,7 @@ generate_report() {
|
|||||||
echo " │ - $attack"
|
echo " │ - $attack"
|
||||||
done
|
done
|
||||||
risk=$((risk + corr_risk))
|
risk=$((risk + corr_risk))
|
||||||
[ $risk -gt 100 ] && risk=100
|
[ "$risk" -gt 100 ] && risk=100
|
||||||
else
|
else
|
||||||
echo " │ $corr_attacks"
|
echo " │ $corr_attacks"
|
||||||
fi
|
fi
|
||||||
@@ -2820,7 +2825,7 @@ generate_report() {
|
|||||||
if [ "$rep_risk" != "0" ]; then
|
if [ "$rep_risk" != "0" ]; then
|
||||||
echo " │ $rep_notes"
|
echo " │ $rep_notes"
|
||||||
risk=$((risk + rep_risk))
|
risk=$((risk + rep_risk))
|
||||||
[ $risk -gt 100 ] && risk=100
|
[ "$risk" -gt 100 ] && risk=100
|
||||||
else
|
else
|
||||||
echo " │ $rep_notes"
|
echo " │ $rep_notes"
|
||||||
fi
|
fi
|
||||||
@@ -2837,7 +2842,7 @@ generate_report() {
|
|||||||
if [ "$threat_risk" != "0" ]; then
|
if [ "$threat_risk" != "0" ]; then
|
||||||
echo " │ ⚠️ $threat_notes"
|
echo " │ ⚠️ $threat_notes"
|
||||||
risk=$((risk + threat_risk))
|
risk=$((risk + threat_risk))
|
||||||
[ $risk -gt 100 ] && risk=100
|
[ "$risk" -gt 100 ] && risk=100
|
||||||
else
|
else
|
||||||
echo " │ $threat_notes"
|
echo " │ $threat_notes"
|
||||||
fi
|
fi
|
||||||
@@ -2861,7 +2866,7 @@ generate_report() {
|
|||||||
echo " │ • $finding"
|
echo " │ • $finding"
|
||||||
done
|
done
|
||||||
risk=$((risk + compromise_risk))
|
risk=$((risk + compromise_risk))
|
||||||
[ $risk -gt 100 ] && risk=100
|
[ "$risk" -gt 100 ] && risk=100
|
||||||
elif [ "$compromise_risk" -gt 0 ]; then
|
elif [ "$compromise_risk" -gt 0 ]; then
|
||||||
echo -e " │ ${YELLOW}⚠️ Suspicious indicators found - $compromise_risk risk points${NC}"
|
echo -e " │ ${YELLOW}⚠️ Suspicious indicators found - $compromise_risk risk points${NC}"
|
||||||
echo " │"
|
echo " │"
|
||||||
@@ -2869,7 +2874,7 @@ generate_report() {
|
|||||||
echo " │ • $finding"
|
echo " │ • $finding"
|
||||||
done
|
done
|
||||||
risk=$((risk + compromise_risk))
|
risk=$((risk + compromise_risk))
|
||||||
[ $risk -gt 100 ] && risk=100
|
[ "$risk" -gt 100 ] && risk=100
|
||||||
else
|
else
|
||||||
echo -e " │ ${GREEN}✓ No compromise indicators detected${NC}"
|
echo -e " │ ${GREEN}✓ No compromise indicators detected${NC}"
|
||||||
echo " │ System integrity checks passed"
|
echo " │ System integrity checks passed"
|
||||||
@@ -2891,7 +2896,7 @@ generate_report() {
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $high_count -gt 0 ]; then
|
if [ "$high_count" -gt 0 ]; then
|
||||||
echo -e "${YELLOW}⚠️ HIGH ALERTS ($high_count):${NC}"
|
echo -e "${YELLOW}⚠️ HIGH ALERTS ($high_count):${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user