Files
Linux-Server-Management-Too…/lib/attack-patterns.sh
T
cschantz 12b013eae1 Enhance attack detection with 5 modern attack patterns
ATTACK DETECTION ENHANCEMENTS:
Added detection for critical modern attack vectors not in OWASP Top 10:

1. XXE (XML External Entity) Detection - detect_xxe()
   - XML entity patterns (<!ENTITY, <!DOCTYPE)
   - External entity references (SYSTEM, file://, php://, expect://)
   - URL-encoded variants (%3c!entity)
   - XML-specific patterns (jar:, .dtd)
   - Threat Score: 18 (HIGH)
   - Icon: 📄

2. SSRF (Server-Side Request Forgery) Detection - detect_ssrf()
   - Internal network targeting (localhost, 127.0.0.1, 169.254.x.x)
   - Private IP ranges (10.x.x.x, 192.168.x.x, 172.16-31.x.x)
   - Cloud metadata endpoints (metadata.google, 169.254.169.254, metadata.aws)
   - Protocol abuse (file://, gopher://, dict://, ftp://localhost)
   - URL parameter patterns (url=http, redirect.*http, proxy.*http)
   - Threat Score: 18 (HIGH)
   - Icon: 🌐

3. NoSQL Injection Detection - detect_nosql_injection()
   - MongoDB operators ($ne, $gt, $lt, $regex, $where, $in, $nin)
   - URL-encoded variants (%24ne, %24gt, %24where)
   - NoSQL-specific patterns (sleep(), this., function(), javascript:)
   - Threat Score: 15 (HIGH)
   - Icon: 🗄️

4. Template Injection (SSTI) Detection - detect_template_injection()
   - Jinja2/Twig patterns ({{ }}, {% %})
   - FreeMarker patterns (${ })
   - JSP patterns (<% %>)
   - URL-encoded variants (%7b%7b, %7b%25, %24%7b)
   - SSTI probe patterns (7*7, config., self., request., env.)
   - Threat Score: 20 (CRITICAL)
   - Icon: 📝
   - Color: White on Red (highest severity)

5. Encoding Bypass Detection - detect_encoding_bypass()
   - Double/triple URL encoding (%25XX, %252X, %2525)
   - WAF bypass attempts (%c0%af, %e0%80%af)
   - Unicode/UTF-8 bypass (%uXXXX, \uXXXX)
   - Threat Score: 12 (MEDIUM)
   - Icon: 🔀

CHANGES TO lib/attack-patterns.sh:
- Added 5 new detection functions (lines 128-206)
- Updated detect_all_attacks() to call new detections (lines 222-226)
- Updated calculate_attack_score() with new scoring (lines 251-255)
- Added icons for new attack types (lines 273-277)
- Added color coding (CRITICAL/HIGH/MEDIUM) (lines 289-291)
- Exported all new functions (lines 303-307)

IMPACT:
- Detection coverage expanded from 7 to 12 attack types
- Now covers modern attack vectors (API attacks, cloud exploits, WAF bypasses)
- Better threat scoring with 3-tier severity (CRITICAL/HIGH/MEDIUM)
- Real-time detection in live-attack-monitor
- Historical detection in bot-analyzer

NEXT STEPS:
- Consider User-Agent rotation detection (bot fingerprinting)
- Consider Tor/VPN/Proxy detection (anonymizer identification)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 18:58:16 -05:00

312 lines
10 KiB
Bash

#!/bin/bash
################################################################################
# Attack Pattern Detection Library
################################################################################
# Purpose: Shared attack vector detection for bot-analyzer and live-monitor
# Features: SQL injection, XSS, Path traversal, RCE, Info disclosure, Bruteforce
################################################################################
# SQL Injection Detection
# Returns: 0 (true) if SQL injection detected, 1 (false) if not
detect_sql_injection() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
# Enhanced SQL injection patterns
if [[ "$url_lower" =~ (union.*select|concat\(|benchmark\(|sleep\(|waitfor|cast\(|exec\() ]] ||
[[ "$url_lower" =~ (information_schema|drop table|insert into|update.*set|delete from) ]] ||
[[ "$url_lower" =~ (%27|0x[0-9a-f]+|hex\(|unhex\(|load_file\() ]]; then
return 0
fi
return 1
}
# XSS (Cross-Site Scripting) Detection
detect_xss() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
if [[ "$url_lower" =~ (<script|javascript:|onerror=|onload=|<iframe|eval\(|alert\() ]] ||
[[ "$url_lower" =~ (document\.cookie|document\.write|\.innerhtml) ]]; then
return 0
fi
return 1
}
# Path Traversal / LFI Detection
detect_path_traversal() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
if [[ "$url_lower" =~ (\.\.\/|\.\.\\|etc\/passwd|etc\/shadow|boot\.ini|win\.ini) ]] ||
[[ "$url_lower" =~ (proc\/self|\/etc\/|c:\\|windows\/system32) ]]; then
return 0
fi
return 1
}
# RCE (Remote Code Execution) / Shell Upload Detection
detect_rce() {
local url="$1"
local method="${2:-GET}"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
# Command execution patterns
if [[ "$url_lower" =~ (cmd\.exe|\/bin\/bash|\/bin\/sh|phpinfo\(|system\(|exec\(|passthru\(|shell_exec\(|popen\() ]] ||
[[ "$url_lower" =~ (proc_open|pcntl_exec|eval\(|assert\(|base64_decode\(|gzinflate\() ]]; then
return 0
fi
# Shell/backdoor files (common webshell names)
if [[ "$url_lower" =~ (shell\.php|c99\.php|r57\.php|backdoor|webshell|wso\.php|b374k) ]] ||
[[ "$url_lower" =~ (shell_exec|1337|defac|index\.php\?|cmd|evil) ]]; then
return 0
fi
# Suspicious POST to script files
if [[ "$url_lower" =~ \.(php|jsp|asp|aspx)$ ]] && [[ "$method" == "POST" ]]; then
return 0
fi
# PHP shell probing - random .php files (common scanner behavior)
# Detect short/random PHP filenames that are typical webshell probes
if [[ "$url_lower" =~ ^/[a-z0-9]{1,15}\.php$ ]] && [[ "$method" == "GET" ]]; then
# Whitelist common legitimate PHP files
if [[ ! "$url_lower" =~ (index\.php|wp-login\.php|xmlrpc\.php|admin\.php|contact\.php|search\.php) ]]; then
return 0
fi
fi
return 1
}
# Info Disclosure Detection
detect_info_disclosure() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
if [[ "$url_lower" =~ (phpinfo|server-status|server-info|\.git\/|\.env|\.htaccess) ]] ||
[[ "$url_lower" =~ (\.sql|\.dump|backup\.zip|database\.sql|wp-config\.php\.bak) ]] ||
[[ "$url_lower" =~ (\.log$|error_log|debug\.log|access\.log) ]]; then
return 0
fi
return 1
}
# Login Bruteforce Detection (URL-based)
detect_login_bruteforce_url() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
if [[ "$url_lower" =~ (wp-login\.php|wp-admin|xmlrpc\.php) ]] ||
[[ "$url_lower" =~ (\/admin|\/login|\/signin|\/auth) ]]; then
return 0
fi
return 1
}
# Admin Path Probing Detection
detect_admin_probe() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
if [[ "$url_lower" =~ (\/admin|\/administrator|\/wp-admin|\/phpmyadmin) ]] ||
[[ "$url_lower" =~ (\/manager|\/controlpanel|\/cpanel|\/webmin) ]] ||
[[ "$url_lower" =~ (wp-content\/uploads.*\.php|wp-includes.*\.php|wp-admin\/includes) ]]; then
return 0
fi
return 1
}
# XXE (XML External Entity) Detection
detect_xxe() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
# XML entity patterns and external entity references
if [[ "$url_lower" =~ (<!entity|<!doctype|system|file://|php://|expect://) ]] ||
[[ "$url_lower" =~ (%3c!entity|%3c!doctype|%3centity|jar:) ]] ||
[[ "$url_lower" =~ (xml.*<!|\.xml.*entity|\.dtd) ]]; then
return 0
fi
return 1
}
# SSRF (Server-Side Request Forgery) Detection
detect_ssrf() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
# Internal network targeting
if [[ "$url_lower" =~ (localhost|127\.0\.0\.|169\.254\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.) ]] ||
[[ "$url_lower" =~ (metadata\.google|169\.254\.169\.254|metadata\.aws|metadata) ]] ||
[[ "$url_lower" =~ (file://|gopher://|dict://|ftp://localhost|http://127|http://0\.0\.0\.0) ]] ||
[[ "$url_lower" =~ (url=http|redirect.*http|fetch.*http|proxy.*http) ]]; then
return 0
fi
return 1
}
# NoSQL Injection Detection
detect_nosql_injection() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
# MongoDB and NoSQL patterns
if [[ "$url_lower" =~ (\$ne|\$gt|\$lt|\$regex|\$where|\$in|\$nin) ]] ||
[[ "$url_lower" =~ (%24ne|%24gt|%24regex|%24where) ]] ||
[[ "$url_lower" =~ (sleep\(.*\)|this\.|function\(|javascript:) ]]; then
return 0
fi
return 1
}
# Template Injection (SSTI) Detection
detect_template_injection() {
local url="$1"
local url_lower=$(echo "$url" | tr '[:upper:]' '[:lower:]')
# Jinja2, Twig, FreeMarker, etc.
if [[ "$url_lower" =~ (\{\{.*\}\}|\{%.*%\}|\$\{.*\}|<%.*%>) ]] ||
[[ "$url_lower" =~ (%7b%7b|%7b%25|%24%7b) ]] ||
[[ "$url_lower" =~ (7\*7|config\.|self\.|request\.|env\.) ]]; then
return 0
fi
return 1
}
# Encoding Bypass Detection (Multiple layers of encoding)
detect_encoding_bypass() {
local url="$1"
# Double/triple URL encoding (bypass WAF)
if [[ "$url" =~ %25[0-9a-fA-F]{2} ]] ||
[[ "$url" =~ (%252[0-9a-fA-F]|%25%32|%2525) ]]; then
return 0
fi
# Unicode/UTF-8 bypass attempts
if [[ "$url" =~ (%u[0-9a-fA-F]{4}|\\u[0-9a-fA-F]{4}) ]] ||
[[ "$url" =~ (%c0%af|%e0%80%af) ]]; then
return 0
fi
return 1
}
# Detect all attack vectors for a URL
# Returns: attack_type1,attack_type2,... or empty if none
detect_all_attacks() {
local url="$1"
local method="${2:-GET}"
local attacks=()
detect_sql_injection "$url" && attacks+=("SQL_INJECTION")
detect_xss "$url" && attacks+=("XSS")
detect_path_traversal "$url" && attacks+=("PATH_TRAVERSAL")
detect_rce "$url" "$method" && attacks+=("RCE")
detect_info_disclosure "$url" && attacks+=("INFO_DISCLOSURE")
detect_login_bruteforce_url "$url" && attacks+=("BRUTEFORCE")
detect_admin_probe "$url" && attacks+=("ADMIN_PROBE")
detect_xxe "$url" && attacks+=("XXE")
detect_ssrf "$url" && attacks+=("SSRF")
detect_nosql_injection "$url" && attacks+=("NOSQL_INJECTION")
detect_template_injection "$url" && attacks+=("TEMPLATE_INJECTION")
detect_encoding_bypass "$url" && attacks+=("ENCODING_BYPASS")
if [ ${#attacks[@]} -gt 0 ]; then
IFS=','; echo "${attacks[*]}"
else
echo ""
fi
}
# Calculate threat score based on attack types
# Returns: score (0-100)
calculate_attack_score() {
local attacks="$1"
local score=0
# Use word boundaries to avoid false matches (e.g., RCE in BRUTEFORCE)
[[ "$attacks" =~ (^|,)SQL_INJECTION(,|$) ]] && score=$((score + 15))
[[ "$attacks" =~ (^|,)XSS(,|$) ]] && score=$((score + 12))
[[ "$attacks" =~ (^|,)PATH_TRAVERSAL(,|$) ]] && score=$((score + 15))
[[ "$attacks" =~ (^|,)RCE(,|$) ]] && score=$((score + 20))
[[ "$attacks" =~ (^|,)INFO_DISCLOSURE(,|$) ]] && score=$((score + 8))
[[ "$attacks" =~ (^|,)BRUTEFORCE(,|$) ]] && score=$((score + 10))
[[ "$attacks" =~ (^|,)ADMIN_PROBE(,|$) ]] && score=$((score + 5))
[[ "$attacks" =~ (^|,)DDOS(,|$) ]] && score=$((score + 25))
[[ "$attacks" =~ (^|,)XXE(,|$) ]] && score=$((score + 18))
[[ "$attacks" =~ (^|,)SSRF(,|$) ]] && score=$((score + 18))
[[ "$attacks" =~ (^|,)NOSQL_INJECTION(,|$) ]] && score=$((score + 15))
[[ "$attacks" =~ (^|,)TEMPLATE_INJECTION(,|$) ]] && score=$((score + 20))
[[ "$attacks" =~ (^|,)ENCODING_BYPASS(,|$) ]] && score=$((score + 12))
echo "$score"
}
# Get attack icon for display
get_attack_icon() {
local attack_type="$1"
case "$attack_type" in
SQL_INJECTION) echo "💉" ;;
XSS) echo "⚠️ " ;;
PATH_TRAVERSAL) echo "📁" ;;
RCE) echo "☠️ " ;;
INFO_DISCLOSURE) echo "🔓" ;;
BRUTEFORCE) echo "🔐" ;;
ADMIN_PROBE) echo "🔍" ;;
DDOS) echo "💥" ;;
XXE) echo "📄" ;;
SSRF) echo "🌐" ;;
NOSQL_INJECTION) echo "🗄️ " ;;
TEMPLATE_INJECTION) echo "📝" ;;
ENCODING_BYPASS) echo "🔀" ;;
BOT) echo "🤖" ;;
SCANNER) echo "🔎" ;;
*) echo "❓" ;;
esac
}
# Get attack color for display
get_attack_color() {
local attack_type="$1"
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)
*) echo '\033[0;36m' ;; # Cyan (LOW)
esac
}
export -f detect_sql_injection
export -f detect_xss
export -f detect_path_traversal
export -f detect_rce
export -f detect_info_disclosure
export -f detect_login_bruteforce_url
export -f detect_admin_probe
export -f detect_xxe
export -f detect_ssrf
export -f detect_nosql_injection
export -f detect_template_injection
export -f detect_encoding_bypass
export -f detect_all_attacks
export -f calculate_attack_score
export -f get_attack_icon
export -f get_attack_color