feat: add WAF + Attack Intelligence system

- class-itk-waf.php: WordPress WAF scanning GET/POST/COOKIE/UA
- class-itk-attacks-api.php: queue/flush/history client for Attack API
- config/waf-rules.conf: 9 attack categories, 60+ WP-specific rules
- class-itk-database.php: itk_attack_log table, DB version 2
- class-itk-admin.php: WAF tab (toggles, response settings, API card),
  Attack Logs tab (filterable table), attacks dispatch in AJAX handlers
- informatiq-toolkit.php: wire WAF + Attacks API into plugin bootstrap
- .gitignore: exclude attack-api/ (separate repo)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 09:37:31 +02:00
parent a8d7972ad7
commit 742047915f
7 changed files with 1093 additions and 4 deletions

124
config/waf-rules.conf Normal file
View File

@@ -0,0 +1,124 @@
# InformatiQ Toolkit — WAF Rules
# Format: category|regex_pattern|description
# Lines starting with # are comments.
# Regexes are PHP PCRE, used with preg_match().
# (?i) flag used where case-insensitive matching is needed.
# =============================================================================
# SQL INJECTION
# =============================================================================
sqli|(?i)\bunion\s+(?:all\s+)?select\b|UNION SELECT — classic column-extraction attack
sqli|(?i)\bselect\b.{0,60}\bfrom\b.{0,60}\b(?:information_schema|mysql\.user|sys\.tables|sysobjects)\b|SELECT FROM system/info tables — schema enumeration
sqli|(?i)(?:sleep|benchmark|pg_sleep|waitfor\s+delay)\s*\([\d\s,\.]+\)|Time-based blind SQLi — sleep/benchmark/waitfor
sqli|(?i)(?:\bextractvalue\s*\(|\bupdatexml\s*\(|\bexp\s*\(\s*~)|Error-based SQLi — extractvalue/updatexml/exp
sqli|(?i);\s*(?:drop|truncate|alter|create|rename|insert|update|delete)\s+(?:table|database|index)\b|Stacked query — DDL/DML after semicolon
sqli|(?i)\binto\s+(?:outfile|dumpfile)\s*['"]|INTO OUTFILE — file-write via SQLi
sqli|(?i)\bload_file\s*\(|LOAD_FILE() — read arbitrary files via SQL
sqli|(?i)(?:'\s*(?:or|and)\s*'?\d+'?\s*(?:=|<|>|like)\s*'?\d+|"\s*(?:or|and)\s*"?\d+"?\s*(?:=|<|>|like)\s*"?\d+)|Boolean-based SQLi — OR/AND equality tautology
sqli|(?i)(?:--\s*$|--\+|#\s*$|\/\*[\s\S]*?\*\/)\s*(?:union|select|drop|insert|update|delete|sleep)|SQL comment followed by keyword — comment-based injection
sqli|(?i)\b(?:char|nchar|varchar)\s*\(\s*\d{1,3}\s*(?:,\s*\d{1,3}\s*)*\)|CHAR() encoding — obfuscated SQLi payload
# =============================================================================
# CROSS-SITE SCRIPTING (XSS)
# =============================================================================
xss|(?i)<\s*script[\s>\/]|Script tag opening — classic XSS vector
xss|(?i)<\s*\/\s*script\s*>|Closing script tag — XSS payload termination
xss|(?i)<\s*(?:iframe|frame|object|embed|applet|base)\s|Dangerous HTML tag — script-execution embedding
xss|(?i)\bon(?:load|error|click|mouseover|mouseout|focus|blur|input|change|keyup|keydown|submit|reset|scroll|resize|animationend|transitionend)\s*=|DOM event handler attribute — inline JS execution
xss|(?i)javascript\s*:|JavaScript protocol — href/src/action XSS
xss|(?i)<\s*svg[\s>][^>]*>[\s\S]{0,200}(?:onload|script|alert|eval)|SVG element with script content — SVG XSS vector
xss|(?i)document\s*\.\s*(?:cookie|write|writeln|location|domain|referrer)|DOM sink access — data theft or redirect
xss|(?i)(?:alert|prompt|confirm|eval)\s*\((?:[^)]{0,100}document\.|[^)]{0,100}window\.|[^)]{0,100}location)|JS execution function with sensitive sink
xss|(?i)<\s*img\s[^>]*\bsrc\s*=\s*['"]\s*(?:javascript:|data:text\/html|vbscript:)|IMG tag with dangerous src protocol
xss|(?i)(?:expression\s*\(|behavior\s*:)|CSS expression/behavior — IE XSS execution vector
# =============================================================================
# LOCAL FILE INCLUSION & PATH TRAVERSAL (LFI)
# =============================================================================
lfi|(?:\.\.\/){2,}|Directory traversal — repeated ../ sequences (2+)
lfi|(?i)(?:%2e%2e%2f|%2e%2e\/|\.\.%2f|%252e%252e%252f){1,}|URL-encoded path traversal — encoded ../
lfi|(?i)(?:%2e%2e%5c|%2e%2e\\|\.\.%5c|%252e%252e%255c){1,}|URL-encoded Windows path traversal — encoded ..\
lfi|(?i)(?:\/|%2f)etc(?:\/|%2f)(?:passwd|shadow|group|hosts|hostname|issue|motd|crontab)|Direct /etc/ access — sensitive Unix system files
lfi|(?i)(?:\/|%2f)proc(?:\/|%2f)(?:self|version|cmdline|environ|mounts|net)|/proc/self access — process information leakage
lfi|(?i)wp-config(?:\.php(?:\.bak|\.old|\.save|\.swp|~)?|\.txt|\.bak|\.orig)|wp-config.php access/backup — credential exposure
lfi|(?i)\.env(?:\.bak|\.old|\.save|\.local|\.production|\.staging)?(?:\?|$|&|\s)|.env file access — environment variable leakage
lfi|(?i)(?:\/|%2f)(?:windows|winnt)(?:\/|%2f)(?:system32|win\.ini|boot\.ini)|Windows system path traversal — win.ini/system32
lfi|(?i)(?:php(?:://)?filter\/(?:read=)?|php:\/\/input|php:\/\/fd)|PHP stream wrapper — filter/input LFI
lfi|(?i)(?:access\.log|error\.log|debug\.log|wp-debug\.log|\.htaccess|\.htpasswd)(?:\?|$|&|\s|%)|Log/config file access — information disclosure
# =============================================================================
# REMOTE FILE INCLUSION (RFI)
# =============================================================================
rfi|(?i)(?:file|page|path|url|include|require|src|dest|redirect)\s*=\s*(?:https?|ftp|ftps):\/\/(?!(?:localhost|127\.|10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.))[\w\-\.]+\.[a-z]{2,}|Remote URL in file-inclusion parameter
rfi|(?i)(?:file|page|path|url|include|require|src)\s*=\s*(?:php:\/\/(?:input|filter|memory|temp|fd)|data:text\/(?:php|html)|expect:\/\/|zip:\/\/|phar:\/\/|glob:\/\/)|Dangerous PHP stream wrapper in param
rfi|(?i)(?:file|page|path|url|include|require|src)\s*=\s*(?:ftp|ftps):\/\/|FTP wrapper in file-inclusion parameter
rfi|(?i)(?:file|page|path|url|include)\s*=\s*(?:\.|%2e){2,}(?:\/|%2f|\\|%5c)|Path traversal in file-inclusion parameter (combined RFI/LFI)
rfi|(?i)(?:file|page|path|url|include|require)\s*=\s*\\\\[a-z0-9_\-]{1,50}\\|UNC/SMB path in include parameter — Windows RFI
rfi|(?i)=\s*(?:https?|ftp):\/\/[^\s&]{10,}\?[^\s&]{0,200}(?:exec|system|passthru|eval|assert)|RFI URL containing PHP execution function
# =============================================================================
# COMMAND INJECTION (CMDi)
# =============================================================================
cmdi|(?i)[;&|`]\s*(?:wget|curl|lwp-request|fetch)\s+(?:https?|ftp):\/\/|Shell-piped downloader — wget/curl after metacharacter
cmdi|(?i)[;&|`]\s*(?:bash|sh|ksh|zsh|dash|tcsh|csh|ash)\s+(?:-[a-z]{1,4}\s+)?['"\/\$]|Shell invocation after metacharacter
cmdi|(?i)[;&|`]\s*(?:nc|ncat|netcat)\s+(?:-[a-z]{0,5}\s+)?[\d\.]{7,}|Netcat reverse/bind shell after metacharacter
cmdi|(?i)[;&|`]\s*(?:python|python3|perl|ruby|php|lua)\s+-[ce]\s+['"]|Scripting language one-liner — code execution
cmdi|(?i)\$\((?:[^)]{0,100}(?:wget|curl|cat|id|uname|whoami|ls|bash|sh|nc|python|perl)[^)]{0,100})\)|Command substitution with dangerous command
cmdi|(?i)`[^`]{0,100}(?:wget|curl|cat|id|uname|whoami|ls|bash|sh|nc|python|perl)[^`]{0,100}`|Backtick command substitution with dangerous command
cmdi|(?i)(?:;|\|)\s*(?:cat\s+(?:\/etc\/|~\/|\.\.\/)|id\b|uname\b|whoami\b|hostname\b)|Classic command injection — system recon commands
cmdi|(?i)(?:\/bin\/|\/usr\/bin\/)(?:bash|sh|ksh|zsh|wget|curl|nc|netcat|python|perl)\b|Absolute path to shell binary — direct execution
# =============================================================================
# XML EXTERNAL ENTITY (XXE)
# =============================================================================
xxe|(?i)<!DOCTYPE\s+[^\[]{0,50}\[[\s\S]{0,500}<!ENTITY|DOCTYPE with inline DTD containing ENTITY — classic XXE
xxe|(?i)<!ENTITY\s+[%\s]*\w+\s+SYSTEM\s+['"]|ENTITY SYSTEM declaration — file disclosure or SSRF via XXE
xxe|(?i)<!ENTITY\s+[%\s]*\w+\s+PUBLIC\s+|ENTITY PUBLIC declaration — external DTD XXE
xxe|(?i)SYSTEM\s+['"](?:file|http|ftp|php|expect|gopher|dict):\/\/|XXE SYSTEM with dangerous URI scheme
xxe|(?i)<!DOCTYPE\s+[^\>]{0,100}SYSTEM\s+['"]|DOCTYPE SYSTEM — external DTD loading
xxe|(?i)(?:&\w{1,30};){3,}|Multiple entity references in sequence — entity expansion / billion-laughs DoS
# =============================================================================
# PHP OBJECT INJECTION & EVAL ABUSE
# =============================================================================
php_inject|(?i)\bunserialize\s*\(\s*(?:\$_(?:GET|POST|REQUEST|COOKIE|SERVER|FILES)|base64_decode\s*\(|gzinflate\s*\(|str_rot13\s*\()|Unserialize with tainted input — PHP object injection
php_inject|(?i)(?:base64_decode|base64decode)\s*\(\s*['"$][\s\S]{0,200}\)\s*\)|base64_decode chain — obfuscated payload decoding
php_inject|(?i)\beval\s*\(\s*(?:base64_decode|str_rot13|gzinflate|gzuncompress|str_replace|hex2bin)\s*\(|eval() wrapping decode function — multi-layer obfuscation
php_inject|(?i)\bassert\s*\(\s*(?:\$_(?:GET|POST|REQUEST|COOKIE)|base64_decode\s*\(|stripslashes\s*\()|assert() with tainted input — code execution via assertion
php_inject|(?i)preg_replace\s*\(\s*['"](?:[^'"]{0,50})\/e['"\s,]|preg_replace /e modifier — deprecated RCE vector
php_inject|(?i)(?:system|exec|shell_exec|passthru|popen|proc_open|pcntl_exec)\s*\(\s*(?:\$_(?:GET|POST|REQUEST|COOKIE)|base64_decode)|System execution function with tainted input
php_inject|(?i)(?:O:\d+:"[a-zA-Z_][a-zA-Z0-9_]*":\d+:\{)|PHP serialized object string — deserialization payload
php_inject|(?i)(?:call_user_func(?:_array)?|create_function|usort|uasort|uksort)\s*\(\s*(?:\$_(?:GET|POST|REQUEST|COOKIE)|['"][^'"]{0,50}system)|Callback function with tainted callable — code execution
# =============================================================================
# SERVER-SIDE REQUEST FORGERY (SSRF)
# =============================================================================
ssrf|(?i)(?:url|uri|endpoint|dest|redirect|path|proxy|target|src|href|feed|link|image)\s*=\s*(?:https?):\/\/(?:169\.254\.169\.254|metadata\.google\.internal|100\.100\.100\.200)|AWS/GCP/Alibaba metadata endpoint in URL parameter
ssrf|(?i)(?:url|uri|endpoint|dest|redirect|path|proxy|target|src|href|feed|link|image)\s*=\s*https?:\/\/(?:127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|localhost|0\.0\.0\.0)|Loopback address in URL parameter — SSRF localhost
ssrf|(?i)(?:url|uri|endpoint|dest|redirect|path|proxy|target|src|href|feed|link|image)\s*=\s*https?:\/\/(?:10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|172\.(?:1[6-9]|2[0-9]|3[01])\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3})|Private RFC-1918 IP range in URL parameter — internal network SSRF
ssrf|(?i)(?:url|uri|endpoint|dest|redirect|path|proxy|target)\s*=\s*(?:file|gopher|dict|ftp|ldap|sftp):\/\/|Non-HTTP scheme in URL parameter — protocol-based SSRF
ssrf|(?i)(?:url|uri|endpoint|dest|redirect|path|proxy|target)\s*=\s*(?:https?):\/\/[^\s&]{0,30}@|Credentials in URL (@ sign) — SSRF with auth bypass
ssrf|(?i)(?:url|uri|endpoint|dest|redirect|path|proxy|target)\s*=\s*(?:0x[0-9a-f]{8}|0[0-7]{9,}|(?:\d+\.){3}\d+)\b|Octal/hex IP encoding in URL parameter — SSRF filter bypass
# =============================================================================
# WORDPRESS-SPECIFIC ATTACKS
# =============================================================================
wp_specific|(?i)\/wp-json\/(?:wp\/v[12]\/)?\.\.\/|wp-json REST API path traversal — directory escape
wp_specific|(?i)\/wp-json\/[^\s?#]{0,200}(?:%2e%2e|%252e%252e|\.\.)[^\s?#]{0,100}|wp-json encoded path traversal — encoded ../ in REST API
wp_specific|(?i)xmlrpc\.php[\s\S]{0,200}(?:system\.multicall|<?xml[^>]{0,200}methodName[^>]{0,200}system\.multicall)|xmlrpc.php multicall abuse — brute-force amplification
wp_specific|(?i)\?author=\d+(?:&|$|\s)|Author ID enumeration via /?author= parameter
wp_specific|(?i)(?:\/|^)wp-config(?:\.php(?:~|\.bak|\.old|\.save|\.orig)?|\.txt|\.bak)(?:\?|#|$|\s|%)|Direct wp-config.php access or backup filename
wp_specific|(?i)(?:\/|^)(?:readme\.html|license\.txt|wp-activate\.php|wp-cron\.php|xmlrpc\.php)(?:\?|#|$|\s)|Exposure of WordPress disclosure/utility files
wp_specific|(?i)(?:\/|^)(?:debug\.log|\.debug\.log|php_error\.log|error_log)(?:\?|#|$|\s)|WordPress debug log file access — information disclosure
wp_specific|(?i)(?:timthumb|thumb)\.php[\s\S]{0,200}\bsrc\s*=\s*https?:\/\/|TimThumb exploit — remote file fetch via src parameter
wp_specific|(?i)\/wp-includes\/(?:js\/tinymce|theme-compat|class-wp-hook|class-wp-list-table)\/[^\s?#]{0,100}\.php|Direct PHP access to wp-includes subdirectories
wp_specific|(?i)\/wp-content\/uploads\/[^\s?#]{0,200}\.php(?:\d?|ml)(?:\?|#|$|\s|%)|PHP file execution in uploads directory — webshell access