diff --git a/lib/attack-patterns.sh b/lib/attack-patterns.sh index bd26b83..c755664 100644 --- a/lib/attack-patterns.sh +++ b/lib/attack-patterns.sh @@ -205,13 +205,102 @@ detect_encoding_bypass() { return 1 } +# Suspicious User-Agent Detection +detect_suspicious_ua() { + local user_agent="$1" + local ua_lower=$(echo "$user_agent" | tr '[:upper:]' '[:lower:]') + + # Empty or missing UA (common in automated attacks) + if [ -z "$user_agent" ] || [ "$user_agent" = "-" ]; then + return 0 + fi + + # Common attack tools and scanners + if [[ "$ua_lower" =~ (nikto|nmap|masscan|nessus|acunetix|burp|sqlmap|metasploit) ]] || + [[ "$ua_lower" =~ (havij|pangolin|w3af|skipfish|dirbuster|gobuster|wpscan|joomla) ]] || + [[ "$ua_lower" =~ (nuclei|jaeles|ffuf|hydra|medusa|zgrab|shodan|censys) ]] || + [[ "$ua_lower" =~ (python-requests|curl/|wget/|libwww-perl|go-http-client) ]] || + [[ "$ua_lower" =~ (scrapy|mechanize|httpclient|okhttp|urllib|axios) ]]; then + return 0 + fi + + # Suspicious patterns + if [[ "$ua_lower" =~ (bot|crawler|spider|scraper) ]] && + [[ ! "$ua_lower" =~ (googlebot|bingbot|slurp|duckduckbot|baiduspider|yandexbot|facebookexternalhit) ]]; then + return 0 + fi + + # Very short UA (< 10 chars, likely fake) + if [ ${#user_agent} -lt 10 ]; then + return 0 + fi + + # Generic/suspicious patterns + if [[ "$ua_lower" =~ ^(mozilla/[45]\.0|test|scanner|exploit|attack|shell) ]]; then + return 0 + fi + + return 1 +} + +# Tor/VPN/Proxy Detection (IP-based patterns) +detect_anonymizer() { + local ip="$1" + + # Known Tor exit node patterns (common ranges - not exhaustive) + # Note: For production, should use actual Tor exit node lists + # This is a simplified detection based on common patterns + + # VPN/Proxy indicators in IP behavior require historical analysis + # This function is a placeholder for IP reputation integration + # Real implementation would check against: + # - Tor exit node lists (https://check.torproject.org/exit-addresses) + # - VPN provider IP ranges + # - Known proxy/datacenter ranges + + # For now, we'll flag datacenter/hosting IPs which are common for VPNs + # This requires external IP reputation data + + return 1 # Placeholder - requires external data integration +} + +# Advanced Bot Fingerprinting (behavior-based) +detect_bot_fingerprint() { + local user_agent="$1" + local ua_lower=$(echo "$user_agent" | tr '[:upper:]' '[:lower:]') + + # Headless browser detection + if [[ "$ua_lower" =~ (headless|phantom|selenium|puppeteer|playwright|chromium.*headless) ]] || + [[ "$ua_lower" =~ (chrome/.*headless|firefox.*headless) ]]; then + return 0 + fi + + # Automated browser frameworks + if [[ "$ua_lower" =~ (webdriver|automation|bot\.html|slimer|casper) ]]; then + return 0 + fi + + # Missing common browser components (suspicious) + # Real browsers include: Mozilla, AppleWebKit, Chrome/Firefox/Safari + if [[ "$ua_lower" =~ mozilla ]] && + [[ ! "$ua_lower" =~ (applewebkit|gecko|chrome|firefox|safari|edge) ]]; then + return 0 + fi + + return 1 +} + # Detect all attack vectors for a URL # Returns: attack_type1,attack_type2,... or empty if none +# Parameters: url method user_agent ip detect_all_attacks() { local url="$1" local method="${2:-GET}" + local user_agent="${3:-}" + local ip="${4:-}" local attacks=() + # URL-based detection detect_sql_injection "$url" && attacks+=("SQL_INJECTION") detect_xss "$url" && attacks+=("XSS") detect_path_traversal "$url" && attacks+=("PATH_TRAVERSAL") @@ -225,6 +314,17 @@ detect_all_attacks() { detect_template_injection "$url" && attacks+=("TEMPLATE_INJECTION") detect_encoding_bypass "$url" && attacks+=("ENCODING_BYPASS") + # User-Agent based detection + if [ -n "$user_agent" ]; then + detect_suspicious_ua "$user_agent" && attacks+=("SUSPICIOUS_UA") + detect_bot_fingerprint "$user_agent" && attacks+=("BOT_FINGERPRINT") + fi + + # IP-based detection + if [ -n "$ip" ]; then + detect_anonymizer "$ip" && attacks+=("ANONYMIZER") + fi + if [ ${#attacks[@]} -gt 0 ]; then IFS=','; echo "${attacks[*]}" else @@ -253,6 +353,9 @@ calculate_attack_score() { [[ "$attacks" =~ (^|,)NOSQL_INJECTION(,|$) ]] && score=$((score + 15)) [[ "$attacks" =~ (^|,)TEMPLATE_INJECTION(,|$) ]] && score=$((score + 20)) [[ "$attacks" =~ (^|,)ENCODING_BYPASS(,|$) ]] && score=$((score + 12)) + [[ "$attacks" =~ (^|,)SUSPICIOUS_UA(,|$) ]] && score=$((score + 10)) + [[ "$attacks" =~ (^|,)BOT_FINGERPRINT(,|$) ]] && score=$((score + 8)) + [[ "$attacks" =~ (^|,)ANONYMIZER(,|$) ]] && score=$((score + 15)) echo "$score" } @@ -275,6 +378,9 @@ get_attack_icon() { NOSQL_INJECTION) echo "🗄️ " ;; TEMPLATE_INJECTION) echo "📝" ;; ENCODING_BYPASS) echo "🔀" ;; + SUSPICIOUS_UA) echo "🎭" ;; + BOT_FINGERPRINT) echo "🤖" ;; + ANONYMIZER) echo "🕶️ " ;; BOT) echo "🤖" ;; SCANNER) echo "🔎" ;; *) echo "❓" ;; @@ -287,8 +393,8 @@ get_attack_color() { case "$attack_type" in SQL_INJECTION|RCE|TEMPLATE_INJECTION) echo '\033[1;41;97m' ;; # White on Red (CRITICAL) - XSS|PATH_TRAVERSAL|BRUTEFORCE|XXE|SSRF|NOSQL_INJECTION) echo '\033[1;31m' ;; # Bold Red (HIGH) - INFO_DISCLOSURE|ADMIN_PROBE|ENCODING_BYPASS) echo '\033[1;33m' ;; # Bold Yellow (MEDIUM) + XSS|PATH_TRAVERSAL|BRUTEFORCE|XXE|SSRF|NOSQL_INJECTION|ANONYMIZER) echo '\033[1;31m' ;; # Bold Red (HIGH) + INFO_DISCLOSURE|ADMIN_PROBE|ENCODING_BYPASS|SUSPICIOUS_UA|BOT_FINGERPRINT) echo '\033[1;33m' ;; # Bold Yellow (MEDIUM) *) echo '\033[0;36m' ;; # Cyan (LOW) esac } @@ -305,6 +411,9 @@ export -f detect_ssrf export -f detect_nosql_injection export -f detect_template_injection export -f detect_encoding_bypass +export -f detect_suspicious_ua +export -f detect_anonymizer +export -f detect_bot_fingerprint export -f detect_all_attacks export -f calculate_attack_score export -f get_attack_icon