#!/usr/bin/env python3 # -*- coding: utf-8 -*- from __future__ import annotations import re # ==================== Threat Types ==================== THREAT_TYPE_JNDI_INJECTION = "jndi_injection" THREAT_TYPE_NESTED_EXPRESSION = "nested_expression" THREAT_TYPE_SQL_INJECTION = "sql_injection" THREAT_TYPE_XSS = "xss" THREAT_TYPE_PATH_TRAVERSAL = "path_traversal" THREAT_TYPE_COMMAND_INJECTION = "command_injection" # ==================== Scores ==================== SCORE_JNDI_DIRECT = 100 SCORE_JNDI_OBFUSCATED = 100 SCORE_NESTED_EXPRESSION = 80 SCORE_SQL_INJECTION = 90 SCORE_XSS = 70 SCORE_PATH_TRAVERSAL = 60 SCORE_COMMAND_INJECTION = 85 # ==================== JNDI (Log4j) ==================== # # - Direct: ${jndi:ldap://...} / ${jndi:rmi://...} => 100 # - Obfuscated: ${${xxx:-j}${xxx:-n}...:ldap://...} => detect # - Nested expression: ${${...}} => 80 JNDI_DIRECT_PATTERN = r"\$\{\s*jndi\s*:\s*(?:ldap|rmi)\s*://" # Common Log4j "default value" obfuscation variants: # ${${::-j}${::-n}${::-d}${::-i}:ldap://...} # ${${foo:-j}${bar:-n}${baz:-d}${qux:-i}:rmi://...} JNDI_OBFUSCATED_PATTERN = ( r"\$\{\s*" r"(?:\$\{[^{}]{0,50}:-j\}|\$\{::-[jJ]\})\s*" r"(?:\$\{[^{}]{0,50}:-n\}|\$\{::-[nN]\})\s*" r"(?:\$\{[^{}]{0,50}:-d\}|\$\{::-[dD]\})\s*" r"(?:\$\{[^{}]{0,50}:-i\}|\$\{::-[iI]\})\s*" r":\s*(?:ldap|rmi)\s*://" ) NESTED_EXPRESSION_PATTERN = r"\$\{\s*\$\{" # ==================== SQL Injection ==================== SQLI_UNION_SELECT_PATTERN = r"\bunion\b\s+(?:all\s+)?\bselect\b" SQLI_OR_1_EQ_1_PATTERN = r"\bor\b\s+1\s*=\s*1\b" # ==================== XSS ==================== XSS_SCRIPT_TAG_PATTERN = r"<\s*script\b" XSS_JS_PROTOCOL_PATTERN = r"javascript\s*:" XSS_INLINE_EVENT_HANDLER_PATTERN = r"\bon\w+\s*=" # ==================== Path Traversal ==================== PATH_TRAVERSAL_PATTERN = r"(?:\.\./|\.\.\\)+" # ==================== Command Injection ==================== CMD_INJECTION_OPERATOR_WITH_CMD_PATTERN = ( r"(?:;|&&|\|\||\|)\s*" r"(?:bash|sh|zsh|cmd|powershell|pwsh|curl|wget|nc|netcat|python|perl|ruby|php|node|cat|ls|id|whoami|uname|rm)\b" ) CMD_INJECTION_SUBSHELL_PATTERN = r"(?:`[^`]{1,200}`|\$\([^)]{1,200}\))" # ==================== Compiled Regex ==================== _FLAGS = re.IGNORECASE | re.MULTILINE JNDI_DIRECT_RE = re.compile(JNDI_DIRECT_PATTERN, _FLAGS) JNDI_OBFUSCATED_RE = re.compile(JNDI_OBFUSCATED_PATTERN, _FLAGS) NESTED_EXPRESSION_RE = re.compile(NESTED_EXPRESSION_PATTERN, _FLAGS) SQLI_UNION_SELECT_RE = re.compile(SQLI_UNION_SELECT_PATTERN, _FLAGS) SQLI_OR_1_EQ_1_RE = re.compile(SQLI_OR_1_EQ_1_PATTERN, _FLAGS) XSS_SCRIPT_TAG_RE = re.compile(XSS_SCRIPT_TAG_PATTERN, _FLAGS) XSS_JS_PROTOCOL_RE = re.compile(XSS_JS_PROTOCOL_PATTERN, _FLAGS) XSS_INLINE_EVENT_HANDLER_RE = re.compile(XSS_INLINE_EVENT_HANDLER_PATTERN, _FLAGS) PATH_TRAVERSAL_RE = re.compile(PATH_TRAVERSAL_PATTERN, _FLAGS) CMD_INJECTION_OPERATOR_WITH_CMD_RE = re.compile(CMD_INJECTION_OPERATOR_WITH_CMD_PATTERN, _FLAGS) CMD_INJECTION_SUBSHELL_RE = re.compile(CMD_INJECTION_SUBSHELL_PATTERN, _FLAGS)