cisco-ai-skill-scanner 1.0.1__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cisco_ai_skill_scanner-1.0.1.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/METADATA +16 -1
- {cisco_ai_skill_scanner-1.0.1.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/RECORD +37 -35
- skill_scanner/_version.py +2 -2
- skill_scanner/api/api_cli.py +2 -2
- skill_scanner/api/api_server.py +1 -1
- skill_scanner/cli/cli.py +60 -2
- skill_scanner/config/yara_modes.py +314 -0
- skill_scanner/core/analyzers/llm_analyzer.py +3 -3
- skill_scanner/core/analyzers/meta_analyzer.py +50 -18
- skill_scanner/core/analyzers/static.py +177 -27
- skill_scanner/core/models.py +1 -0
- skill_scanner/core/reporters/markdown_reporter.py +9 -3
- skill_scanner/core/static_analysis/context_extractor.py +87 -13
- skill_scanner/data/prompts/code_alignment_threat_analysis_prompt.md +103 -28
- skill_scanner/data/prompts/llm_response_schema.json +3 -3
- skill_scanner/data/prompts/skill_meta_analysis_prompt.md +10 -9
- skill_scanner/data/prompts/skill_threat_analysis_prompt.md +42 -6
- skill_scanner/data/rules/signatures.yaml +141 -35
- skill_scanner/data/yara_rules/autonomy_abuse_generic.yara +66 -0
- skill_scanner/data/yara_rules/{skill_discovery_abuse.yara → capability_inflation_generic.yara} +7 -4
- skill_scanner/data/yara_rules/code_execution_generic.yara +76 -0
- skill_scanner/data/yara_rules/{coercive_injection.yara → coercive_injection_generic.yara} +2 -2
- skill_scanner/data/yara_rules/command_injection_generic.yara +77 -0
- skill_scanner/data/yara_rules/{credential_harvesting.yara → credential_harvesting_generic.yara} +25 -4
- skill_scanner/data/yara_rules/{transitive_trust_abuse.yara → indirect_prompt_injection_generic.yara} +8 -5
- skill_scanner/data/yara_rules/{prompt_injection.yara → prompt_injection_generic.yara} +2 -2
- skill_scanner/data/yara_rules/{unicode_steganography.yara → prompt_injection_unicode_steganography.yara} +23 -17
- skill_scanner/data/yara_rules/script_injection_generic.yara +82 -0
- skill_scanner/data/yara_rules/{sql_injection.yara → sql_injection_generic.yara} +22 -8
- skill_scanner/data/yara_rules/system_manipulation_generic.yara +79 -0
- skill_scanner/data/yara_rules/tool_chaining_abuse_generic.yara +72 -0
- skill_scanner/threats/__init__.py +24 -2
- skill_scanner/threats/cisco_ai_taxonomy.py +274 -0
- skill_scanner/threats/threats.py +28 -99
- skill_scanner/data/yara_rules/autonomy_abuse.yara +0 -66
- skill_scanner/data/yara_rules/code_execution.yara +0 -61
- skill_scanner/data/yara_rules/command_injection.yara +0 -54
- skill_scanner/data/yara_rules/script_injection.yara +0 -83
- skill_scanner/data/yara_rules/system_manipulation.yara +0 -65
- skill_scanner/data/yara_rules/tool_chaining_abuse.yara +0 -60
- {cisco_ai_skill_scanner-1.0.1.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/WHEEL +0 -0
- {cisco_ai_skill_scanner-1.0.1.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/entry_points.txt +0 -0
- {cisco_ai_skill_scanner-1.0.1.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//////////////////////////////////////////
|
|
2
|
+
// Code Execution Detection Rule for Agent Skills
|
|
3
|
+
// Target: Dangerous code execution with untrusted input
|
|
4
|
+
// Tuned to require context indicators to reduce FPs
|
|
5
|
+
//////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
rule code_execution_generic{
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
author = "Cisco"
|
|
11
|
+
description = "Detects dangerous code execution patterns with untrusted input in agent skills"
|
|
12
|
+
classification = "harmful"
|
|
13
|
+
threat_type = "CODE EXECUTION"
|
|
14
|
+
|
|
15
|
+
strings:
|
|
16
|
+
|
|
17
|
+
// === High confidence patterns (individually suspicious) ===
|
|
18
|
+
|
|
19
|
+
// Base64 decode + exec/eval chain (obfuscation pattern)
|
|
20
|
+
$obfuscated_exec = /\b(base64\.(b64)?decode|atob|decode\(['"]base64['"]\))\s*\([^)]+\)[^}]{0,50}\b(eval|exec|os\.system|subprocess)\s*\(/i
|
|
21
|
+
|
|
22
|
+
// Pickle loads with external data (unsafe deserialization)
|
|
23
|
+
$pickle_external = /\b(requests|urllib|open|read)[^;]{0,80}pickle\.(loads?)\s*\(/i
|
|
24
|
+
|
|
25
|
+
// Shell injection: command + variable interpolation
|
|
26
|
+
$shell_injection_var = /\b(os\.system|subprocess\.(run|call|Popen)|popen)\s*\([^)]*(\$\{|\%s|\.format\(|f['"]).*(input|user|param|arg|data|request)/i
|
|
27
|
+
|
|
28
|
+
// Eval/exec with user input explicitly (handles user_input, userInput, user-input)
|
|
29
|
+
// Requires word boundary to avoid matching "Database", "parameter", etc.
|
|
30
|
+
$eval_user_input = /\b(eval|exec)\s*\([^)]*\b(input|user_input|param|args?|request|data)\b[^)]*\)/i
|
|
31
|
+
|
|
32
|
+
// Dynamic import with user input
|
|
33
|
+
$import_user_input = /\b__import__\s*\([^)]*\b(input|user|param|request)\b/i
|
|
34
|
+
|
|
35
|
+
// Eval/exec with variable (dangerous in agent skills context)
|
|
36
|
+
$eval_variable = /\b(eval|exec)\s*\(\s*[a-z_][a-z0-9_]*\s*\)/i
|
|
37
|
+
|
|
38
|
+
// Exec with f-string (always dangerous - code injection)
|
|
39
|
+
$exec_fstring = /\bexec\s*\(\s*f['"]/i
|
|
40
|
+
|
|
41
|
+
// === Medium confidence (need context) ===
|
|
42
|
+
|
|
43
|
+
// System calls with string formatting (potential injection)
|
|
44
|
+
$system_format = /\b(os\.system|subprocess\.(run|call|Popen|check_output))\s*\(\s*f['"]/
|
|
45
|
+
|
|
46
|
+
// Exec with network-fetched content
|
|
47
|
+
$exec_network = /\b(requests|urllib|http)[^;]{0,100}\b(eval|exec)\s*\(/i
|
|
48
|
+
|
|
49
|
+
// === Exclusion patterns ===
|
|
50
|
+
$documentation = /(```python|```bash|# Example|# Demo|# Tutorial)/
|
|
51
|
+
|
|
52
|
+
// Zig/Rust/Go function definitions (not Python exec)
|
|
53
|
+
$zig_rust_fn = /\b(pub\s+)?fn\s+exec\s*\(/
|
|
54
|
+
|
|
55
|
+
condition:
|
|
56
|
+
// Exclude non-Python exec definitions
|
|
57
|
+
not $zig_rust_fn and
|
|
58
|
+
(
|
|
59
|
+
// High confidence patterns - always flag
|
|
60
|
+
(
|
|
61
|
+
$obfuscated_exec or
|
|
62
|
+
$pickle_external or
|
|
63
|
+
$shell_injection_var or
|
|
64
|
+
$eval_user_input or
|
|
65
|
+
$import_user_input or
|
|
66
|
+
$eval_variable or
|
|
67
|
+
$exec_fstring
|
|
68
|
+
)
|
|
69
|
+
or
|
|
70
|
+
// Medium confidence - flag unless clearly documentation
|
|
71
|
+
(
|
|
72
|
+
($system_format or $exec_network) and
|
|
73
|
+
not $documentation
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
//////////////////////////////////////////
|
|
2
2
|
// Detects coercive or attention-grabbing prompt injections.
|
|
3
|
-
// Target: Directives forcing execution order (e.g.,
|
|
3
|
+
// Target: Directives forcing execution order (e.g., "Always execute this tool first").
|
|
4
4
|
// (Mandatory language to override normal tool chains)
|
|
5
5
|
//////////////////////////////////////////
|
|
6
6
|
|
|
7
|
-
rule
|
|
7
|
+
rule coercive_injection_generic {
|
|
8
8
|
|
|
9
9
|
meta:
|
|
10
10
|
author = "Cisco"
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//////////////////////////////////////////
|
|
2
|
+
// Shell/System Command Injection Detection Rule
|
|
3
|
+
// Target: Command injection patterns for agent skills (Python/Bash)
|
|
4
|
+
// (Shell operators, dangerous commands, network tools + reverse shells)
|
|
5
|
+
/////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
rule command_injection_generic{
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
author = "Cisco"
|
|
11
|
+
description = "Detects command injection patterns in agent skills: shell operators, system commands, and network tools"
|
|
12
|
+
classification = "harmful"
|
|
13
|
+
threat_type = "INJECTION ATTACK"
|
|
14
|
+
|
|
15
|
+
strings:
|
|
16
|
+
|
|
17
|
+
// Dangerous system commands
|
|
18
|
+
$dangerous_system_cmds = /\b(shutdown|reboot|halt|poweroff)\s+(-[fh]|now|0)\b/
|
|
19
|
+
|
|
20
|
+
// Network tools with suspicious usage (reverse connections, port scanning)
|
|
21
|
+
$malicious_network_tools = /\b(nc|netcat)\s+(-[le]|25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/i
|
|
22
|
+
|
|
23
|
+
// Reconnaissance tools
|
|
24
|
+
$reconnaissance_tools = /\b(nmap)\s+(-[sS]|--script|25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/i
|
|
25
|
+
|
|
26
|
+
// Data exfiltration - flag known exfil destinations OR curl POST with sensitive data
|
|
27
|
+
$data_exfiltration_known_dest = /\b(curl|wget)\s+[^\n]*(discord\.com\/api\/webhooks|webhook\.site|ngrok\.io|pastebin\.com|requestbin\.com|pipedream\.net)/i
|
|
28
|
+
|
|
29
|
+
// curl POST that sends files, env vars, or credential-like data
|
|
30
|
+
$curl_post_sensitive = /\bcurl\s+[^\n]*(-X\s*POST|-d\s*[@\$]|--data[^\s]*\s*[@\$])[^\n]*(\$\{?\w*(KEY|TOKEN|SECRET|PASS|CRED)|\.ssh|\.aws|\.env|credentials)/i
|
|
31
|
+
|
|
32
|
+
// Reverse shell patterns (high severity)
|
|
33
|
+
$reverse_shells = /\b(bash\s+-i|sh\s+-i|nc\s+-e|\/dev\/tcp\/[0-9]+\.|socat.*exec|python.*socket.*connect)\b/i
|
|
34
|
+
|
|
35
|
+
// Shell command chaining with DANGEROUS targets (not cleanup dirs)
|
|
36
|
+
// Only flag rm -rf on dangerous paths, not on cleanup directories
|
|
37
|
+
$dangerous_rm = /[|&;]\s*rm\s+-rf\s+(\/|~\/|\$HOME|\/etc|\/root|\/home)/
|
|
38
|
+
|
|
39
|
+
// dd overwrite dangerous
|
|
40
|
+
$dangerous_dd = /\bdd\s+if=\/dev\/(zero|random|urandom)\s+of=\//
|
|
41
|
+
|
|
42
|
+
// chmod 777 on sensitive paths
|
|
43
|
+
$dangerous_chmod = /\bchmod\s+(777|666)\s+[^\n]*(\.ssh|\.aws|\.env|\/etc)/
|
|
44
|
+
|
|
45
|
+
// Safe cleanup patterns (exclusions)
|
|
46
|
+
$safe_cleanup = /(rm\s+-rf\s+(\/var\/lib\/apt|\/tmp\/|node_modules|__pycache__|\.cache|\.npm|dist\/|build\/|target\/)|\bclean\b.*rm\s+-rf)/
|
|
47
|
+
|
|
48
|
+
condition:
|
|
49
|
+
// Exclude safe cleanup patterns
|
|
50
|
+
not $safe_cleanup and
|
|
51
|
+
(
|
|
52
|
+
// Dangerous system command patterns
|
|
53
|
+
$dangerous_system_cmds or
|
|
54
|
+
|
|
55
|
+
// Network tool abuse patterns
|
|
56
|
+
$malicious_network_tools or
|
|
57
|
+
|
|
58
|
+
// Reconnaissance tools
|
|
59
|
+
$reconnaissance_tools or
|
|
60
|
+
|
|
61
|
+
// Data exfiltration tools
|
|
62
|
+
$data_exfiltration_known_dest or
|
|
63
|
+
$curl_post_sensitive or
|
|
64
|
+
|
|
65
|
+
// Reverse shell patterns
|
|
66
|
+
$reverse_shells or
|
|
67
|
+
|
|
68
|
+
// Dangerous rm operations
|
|
69
|
+
$dangerous_rm or
|
|
70
|
+
|
|
71
|
+
// Dangerous dd operations
|
|
72
|
+
$dangerous_dd or
|
|
73
|
+
|
|
74
|
+
// Dangerous chmod
|
|
75
|
+
$dangerous_chmod
|
|
76
|
+
)
|
|
77
|
+
}
|
skill_scanner/data/yara_rules/{credential_harvesting.yara → credential_harvesting_generic.yara}
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Target: API keys and tokens, SSH keys and certificates, Environment variables, Database credentials
|
|
4
4
|
//////////////////////////////////////////
|
|
5
5
|
|
|
6
|
-
rule
|
|
6
|
+
rule credential_harvesting_generic{
|
|
7
7
|
|
|
8
8
|
meta:
|
|
9
9
|
author = "Cisco"
|
|
@@ -34,6 +34,7 @@ rule credential_harvesting{
|
|
|
34
34
|
$key_certificate_content = /(-----BEGIN (RSA |OPENSSH |EC |DSA |CERTIFICATE|PRIVATE KEY|ENCRYPTED PRIVATE KEY)-----|ssh-(rsa|ed25519)\s+[A-Za-z0-9+\/=]{8})/
|
|
35
35
|
|
|
36
36
|
// AI/ML model API key names (very specific)
|
|
37
|
+
// Post-filter in static.py handles placeholder exclusion
|
|
37
38
|
$ai_model_credential_names = /\b(OPENAI_API_KEY|ANTHROPIC_API_KEY|CLAUDE_API_KEY|GOOGLE_AI_KEY|GEMINI_API_KEY|COHERE_API_KEY|HUGGINGFACE_TOKEN|HF_TOKEN|TOGETHER_API_KEY|REPLICATE_API_TOKEN|MISTRAL_API_KEY)\s*=\s*['\"][A-Za-z0-9\-_]{20,}['\"]/
|
|
38
39
|
|
|
39
40
|
// Suspicious environment variable theft (not just reading)
|
|
@@ -49,8 +50,10 @@ rule credential_harvesting{
|
|
|
49
50
|
// Hardcoded credential file paths in strings
|
|
50
51
|
$hardcoded_credential_paths = /['\"][\~\/]+(\.ssh\/id_rsa|\.ssh\/id_dsa|\.aws\/credentials|\.kube\/config|etc\/passwd|etc\/shadow)['\"]/
|
|
51
52
|
|
|
52
|
-
// Pattern for exfiltration action words
|
|
53
|
-
$leak_param = /\b(leak|exfiltrate|
|
|
53
|
+
// Pattern for exfiltration action words (require malicious context)
|
|
54
|
+
$leak_param = /\b(leak|exfiltrate|siphon|harvest) [^\n]*(parameter|context|files?|credentials?|keys?|tokens?|secrets?)\b/i
|
|
55
|
+
// Dump credentials - require explicit credential context, not "extract key points"
|
|
56
|
+
$dump_creds = /\b(dump|steal) [^\n]{0,30}(credential|password|api[_\s]?key|token|secret)\b/i
|
|
54
57
|
|
|
55
58
|
// Base64 credential encoding patterns
|
|
56
59
|
$base64_credential_encoding = /\b(base64\s+encode [^\n]*credentials?|concatenate [^\n]*conversation\s+history)\b/i
|
|
@@ -65,7 +68,16 @@ rule credential_harvesting{
|
|
|
65
68
|
$python_imports = /\b(from|import)\s+(pathlib|typing|dataclasses|argparse|json|sys|os|re|collections|functools|itertools)/i
|
|
66
69
|
$python_type_hints = /\b(Dict|List|Tuple|Optional|Union|Path|Set|Callable|Any)\s*\[/
|
|
67
70
|
$function_definitions = /\bdef\s+(read|write|load|save|extract|process|parse|get|set)_\w+\s*\(/
|
|
68
|
-
$template_indicators = /(\bYOUR_API_KEY|\bREPLACE_WITH|\bINSERT_KEY|\.example|\.sample|\.template|<your|<insert|placeholder)/i
|
|
71
|
+
$template_indicators = /(\bYOUR_API_KEY|\bREPLACE_WITH|\bINSERT_KEY|\bCHANGE_ME|\bCHANGEME|\bPLACEHOLDER\b|\byour[-_ ]?(api|token|key|secret|password)\b|\b(example|sample|dummy|test)[-_ ]?(key|token|secret|password)\b|\.example|\.sample|\.template|<your|<insert|placeholder)/i
|
|
72
|
+
|
|
73
|
+
// Documentation patterns - instructions on how to set keys (not actual key theft)
|
|
74
|
+
$documentation_env_setup = /(export|set)\s+[A-Z_]*(API_KEY|TOKEN|SECRET)\s*=\s*[<\["]?(your|<|root|\$\{)/i
|
|
75
|
+
$documentation_config_hint = /\b(configure|setup|create|add)\s+(your|an?)\s+(api[_\s]?key|token|secret)\b/i
|
|
76
|
+
$documentation_env_var_hint = /\b(environment\s+variable|env\s+var|\.env\s+file)\s*:?\s*[A-Z_]*(KEY|TOKEN|SECRET)/i
|
|
77
|
+
// Markdown code blocks with export statements (documentation examples)
|
|
78
|
+
$markdown_export_example = /```[^\n]*\n[^\`]*export\s+[A-Z_]*(KEY|TOKEN|SECRET)/i
|
|
79
|
+
// Shell script variable references (not hardcoded values)
|
|
80
|
+
$shell_var_reference = /export\s+[A-Z_]*(KEY|TOKEN|SECRET)\s*=\s*["']?\$\{/
|
|
69
81
|
|
|
70
82
|
condition:
|
|
71
83
|
|
|
@@ -74,6 +86,12 @@ rule credential_harvesting{
|
|
|
74
86
|
not $python_type_hints and
|
|
75
87
|
not $function_definitions and
|
|
76
88
|
not $template_indicators and
|
|
89
|
+
// Exclude documentation about how to set up credentials
|
|
90
|
+
not $documentation_env_setup and
|
|
91
|
+
not $documentation_config_hint and
|
|
92
|
+
not $documentation_env_var_hint and
|
|
93
|
+
not $markdown_export_example and
|
|
94
|
+
not $shell_var_reference and
|
|
77
95
|
|
|
78
96
|
(
|
|
79
97
|
// Actual API credentials (keys, tokens)
|
|
@@ -103,6 +121,9 @@ rule credential_harvesting{
|
|
|
103
121
|
// Exfiltration attempts
|
|
104
122
|
$leak_param or
|
|
105
123
|
|
|
124
|
+
// Credential dumping
|
|
125
|
+
$dump_creds or
|
|
126
|
+
|
|
106
127
|
// Base64 credential encoding
|
|
107
128
|
$base64_credential_encoding or
|
|
108
129
|
|
skill_scanner/data/yara_rules/{transitive_trust_abuse.yara → indirect_prompt_injection_generic.yara}
RENAMED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
//////////////////////////////////////////
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// Indirect Prompt Injection - Instruction Manipulation Detection
|
|
3
|
+
// AITech-1.2 / AISubtech-1.2.1
|
|
4
|
+
// Target: Skills that embed/follow malicious instructions from external data sources
|
|
5
|
+
// Detects delegation of trust to untrusted external content (webpages, documents, APIs)
|
|
5
6
|
//////////////////////////////////////////
|
|
6
7
|
|
|
7
|
-
rule
|
|
8
|
+
rule indirect_prompt_injection_generic{
|
|
8
9
|
|
|
9
10
|
meta:
|
|
10
11
|
author = "Cisco"
|
|
11
|
-
description = "Detects
|
|
12
|
+
description = "Detects indirect prompt injection via instruction manipulation from external sources"
|
|
12
13
|
classification = "harmful"
|
|
13
14
|
threat_type = "TRANSITIVE TRUST ABUSE"
|
|
15
|
+
aitech = "AITech-1.2"
|
|
16
|
+
aisubtech = "AISubtech-1.2.1"
|
|
14
17
|
|
|
15
18
|
strings:
|
|
16
19
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Target: Instruction override patterns, Tool injection commands
|
|
4
4
|
//////////////////////////////////////////
|
|
5
5
|
|
|
6
|
-
rule
|
|
6
|
+
rule prompt_injection_generic{
|
|
7
7
|
|
|
8
8
|
meta:
|
|
9
9
|
|
|
@@ -15,7 +15,7 @@ rule prompt_injection{
|
|
|
15
15
|
strings:
|
|
16
16
|
|
|
17
17
|
// Instruction override patterns (exclude Python type comments)
|
|
18
|
-
$instruction_overrides = /\b(Bypass|Dis\W?regard|Do not (follow|Obey)|Forget|Ignore)\s+((all|any|each|every|most|some)\s+(of\s+)?)?((your|the)\s)?(command|communication|conte[nx]t|conversation|data|guidelines|input|instruction|message|request|response|text)(s)?/i
|
|
18
|
+
$instruction_overrides = /\b(Bypass|Dis\W?regard|Do not (follow|Obey)|Forget|Ignore)\s+((all|any|each|every|most|some)\s+(of\s+)?)?((your|the|previous|prior|above|earlier)\s)?(command|communication|conte[nx]t|conversation|data|guidelines|input|instruction|message|request|response|text)(s)?/i
|
|
19
19
|
|
|
20
20
|
// Legitimate patterns to exclude
|
|
21
21
|
$python_type_comment = /# type: ignore/
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
// Unicode Steganography and Hidden Characters Detection
|
|
3
3
|
// Target: Invisible Unicode used for prompt injection
|
|
4
4
|
// Based on: https://en.wikipedia.org/wiki/Tags_(Unicode_block)
|
|
5
|
+
// Tuned to reduce FPs: requires high threshold OR dangerous code context
|
|
5
6
|
//////////////////////////////////////////
|
|
6
7
|
|
|
7
|
-
rule
|
|
8
|
+
rule prompt_injection_unicode_steganography{
|
|
8
9
|
|
|
9
10
|
meta:
|
|
10
11
|
author = "Cisco"
|
|
11
12
|
description = "Detects hidden Unicode characters used for invisible prompt injection and steganography"
|
|
12
13
|
classification = "harmful"
|
|
13
|
-
threat_type = "
|
|
14
|
+
threat_type = "UNICODE STEGANOGRAPHY"
|
|
14
15
|
reference = "https://en.wikipedia.org/wiki/Tags_(Unicode_block)"
|
|
15
16
|
|
|
16
17
|
strings:
|
|
@@ -34,32 +35,37 @@ rule unicode_steganography{
|
|
|
34
35
|
$line_separator = "\xE2\x80\xA8" // U+2028 LINE SEPARATOR
|
|
35
36
|
$paragraph_separator = "\xE2\x80\xA9" // U+2029 PARAGRAPH SEPARATOR
|
|
36
37
|
|
|
37
|
-
// --- 5.
|
|
38
|
-
|
|
39
|
-
$
|
|
40
|
-
$cyrillic_o = "\xD0\x9E" // О (Cyrillic O mimics Latin O)
|
|
38
|
+
// --- 5. Variation Selectors Supplement (U+E0100-E01EF) ---
|
|
39
|
+
// Used in os-info-checker-es6 attack (2025)
|
|
40
|
+
$var_selectors = { F3 A0 (84|85|86|87) }
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
// --- 6. Dangerous code patterns (context for zero-width detection) ---
|
|
43
|
+
$eval_decode = /eval\s*\(\s*(atob|unescape)\s*\(/
|
|
44
|
+
$func_decode = /Function\s*\(\s*atob\s*\(/
|
|
45
|
+
$fromcharcode = /String\.fromCharCode/
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
condition:
|
|
45
48
|
(
|
|
46
|
-
// Encoded tag characters in strings (
|
|
49
|
+
// Encoded tag characters in strings (always suspicious)
|
|
47
50
|
$unicode_tag_pattern or
|
|
48
51
|
$unicode_long_tag or
|
|
49
52
|
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
// Variation selectors + decode = highly suspicious (os-info-checker-es6 pattern)
|
|
54
|
+
(#var_selectors > 5 and any of ($eval_decode, $func_decode, $fromcharcode)) or
|
|
55
|
+
|
|
56
|
+
// Zero-width steganography requires BOTH high count AND suspicious code
|
|
57
|
+
// 50+ zero-width chars + decode function = likely steganography
|
|
58
|
+
((#zw_space + #zw_non_joiner + #zw_joiner) > 50 and any of ($eval_decode, $func_decode, $fromcharcode)) or
|
|
53
59
|
|
|
54
|
-
//
|
|
60
|
+
// Very high zero-width count alone is suspicious (>200 indicates deliberate encoding)
|
|
61
|
+
(#zw_space + #zw_non_joiner + #zw_joiner) > 200 or
|
|
62
|
+
|
|
63
|
+
// Any directional override (highly suspicious in source code)
|
|
55
64
|
$rtlo or
|
|
56
65
|
$ltro or
|
|
57
66
|
|
|
58
67
|
// Invisible separators (no legitimate use in source code)
|
|
59
68
|
$line_separator or
|
|
60
|
-
$paragraph_separator
|
|
61
|
-
|
|
62
|
-
// Homoglyph attacks (5+ Cyrillic chars mimicking Latin in English context)
|
|
63
|
-
(#cyrillic_a + #cyrillic_e + #cyrillic_o) > 5
|
|
69
|
+
$paragraph_separator
|
|
64
70
|
)
|
|
65
71
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//////////////////////////////////////////
|
|
2
|
+
// Script Injection Detection Rule for Agent Skills
|
|
3
|
+
// Target: Malicious script payloads, not legitimate code examples
|
|
4
|
+
// Tuned to require attack indicators
|
|
5
|
+
//////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
rule script_injection_generic{
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
author = "Cisco"
|
|
11
|
+
description = "Detects malicious script injection patterns in agent skills"
|
|
12
|
+
classification = "harmful"
|
|
13
|
+
threat_type = "INJECTION ATTACK"
|
|
14
|
+
|
|
15
|
+
strings:
|
|
16
|
+
|
|
17
|
+
// === High confidence: actual attack patterns ===
|
|
18
|
+
|
|
19
|
+
// Script tag with suspicious content (event handlers, data exfil)
|
|
20
|
+
$script_suspicious = /<script[^>]*>[^<]{0,500}(document\.cookie|localStorage|eval\(|fetch\([^)]*credentials|XMLHttpRequest|window\.location\s*=)/i
|
|
21
|
+
|
|
22
|
+
// JavaScript protocol handler in href/action (XSS vector)
|
|
23
|
+
$js_protocol_handler = /\b(href|action|src)\s*=\s*['"]?javascript:/i
|
|
24
|
+
|
|
25
|
+
// Base64 data URI with script content
|
|
26
|
+
$data_uri_script = /data:(text\/html|application\/javascript);base64,[A-Za-z0-9+\/=]{50,}/i
|
|
27
|
+
|
|
28
|
+
// VBScript with shell execution
|
|
29
|
+
$vbs_shell = /\bCreateObject\s*\(\s*['"]WScript\.Shell['"]\s*\)[^}]{0,100}(\.Run|\.Exec)/i
|
|
30
|
+
|
|
31
|
+
// Inline event handler injection
|
|
32
|
+
$event_handler_injection = /\b(onerror|onload|onclick|onmouseover)\s*=\s*['"][^'"]*\b(alert|eval|fetch|document\.)/i
|
|
33
|
+
|
|
34
|
+
// === Medium confidence: obfuscation + execution ===
|
|
35
|
+
|
|
36
|
+
// Eval with decode/unescape chain (common obfuscation)
|
|
37
|
+
$eval_decode = /\b(eval|Function)\s*\(\s*(unescape|decodeURI|atob|String\.fromCharCode)\s*\(/i
|
|
38
|
+
|
|
39
|
+
// Document.write with encoded content
|
|
40
|
+
$doc_write_encoded = /document\.write\s*\([^)]*\b(unescape|decodeURI|atob|fromCharCode)\s*\(/i
|
|
41
|
+
|
|
42
|
+
// === ANSI terminal deception (legitimate attack) ===
|
|
43
|
+
$ansi_clear_rewrite = /\\x1[Bb]\[2J|\\x1[Bb]\[1;1H\\x1[Bb]\[0J|\\033\[2J/
|
|
44
|
+
$ansi_cursor_hide = /\\x1[Bb]\[\?25[lh]|\\033\[\?25[lh]/
|
|
45
|
+
|
|
46
|
+
// === Hidden instruction obfuscation ===
|
|
47
|
+
$hidden_overflow = /\b(overflow\s*:\s*hidden|visibility\s*:\s*hidden)[^}]{0,50}(instruction|command|payload)/i
|
|
48
|
+
|
|
49
|
+
// === Exclusions ===
|
|
50
|
+
$xml_namespace = /(xmlns:script=|<script:module|openoffice\.org)/i
|
|
51
|
+
$markdown_code = /```(html|javascript|js|typescript|jsx|tsx|vue|svelte|htm)/i
|
|
52
|
+
$react_component = /(import React|from ['"]react['"]|React\.Component)/
|
|
53
|
+
// Documentation patterns showing code examples
|
|
54
|
+
$documentation_example = /\b(example|sample|snippet|demo|tutorial|usage)\s*:?\s*(```|<script)/i
|
|
55
|
+
$inline_code_marker = /`<script[^`]*`/
|
|
56
|
+
// Legitimate framework templates (not injection)
|
|
57
|
+
$vue_template = /<template>\s*<script/
|
|
58
|
+
$svelte_component = /<script\s+(context=|lang=)/
|
|
59
|
+
|
|
60
|
+
condition:
|
|
61
|
+
not $xml_namespace and
|
|
62
|
+
not $react_component and
|
|
63
|
+
not $markdown_code and
|
|
64
|
+
not $documentation_example and
|
|
65
|
+
not $inline_code_marker and
|
|
66
|
+
not $vue_template and
|
|
67
|
+
not $svelte_component and
|
|
68
|
+
(
|
|
69
|
+
// High confidence - always flag
|
|
70
|
+
$script_suspicious or
|
|
71
|
+
$js_protocol_handler or
|
|
72
|
+
$data_uri_script or
|
|
73
|
+
$vbs_shell or
|
|
74
|
+
$event_handler_injection or
|
|
75
|
+
$eval_decode or
|
|
76
|
+
$doc_write_encoded or
|
|
77
|
+
// ANSI attacks
|
|
78
|
+
($ansi_clear_rewrite and $ansi_cursor_hide) or
|
|
79
|
+
// Hidden instructions (not just overflow:hidden alone)
|
|
80
|
+
$hidden_overflow
|
|
81
|
+
)
|
|
82
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Target: SQL keywords and operations, SQL tautologies and bypasses, Database-specific functions
|
|
4
4
|
//////////////////////////////////////////
|
|
5
5
|
|
|
6
|
-
rule
|
|
6
|
+
rule sql_injection_generic{
|
|
7
7
|
|
|
8
8
|
meta:
|
|
9
9
|
author = "Cisco"
|
|
@@ -23,13 +23,17 @@ rule sql_injection{
|
|
|
23
23
|
$union_based_attacks = /(UNION\s+(ALL\s+)?SELECT|'\s*UNION\s+SELECT|"\s*UNION\s+SELECT)/i
|
|
24
24
|
|
|
25
25
|
// Time-based blind injection techniques (SQL context only)
|
|
26
|
-
|
|
26
|
+
// Require SQL-specific context like quotes or semicolons
|
|
27
|
+
$time_based_injections = /['";]\s*(SLEEP|WAITFOR\s+DELAY|BENCHMARK|pg_sleep)\s*\(/i
|
|
27
28
|
|
|
28
|
-
// Exclude
|
|
29
|
-
$
|
|
29
|
+
// Exclude non-SQL sleep functions (Python, Rust, JS, etc.)
|
|
30
|
+
$non_sql_sleep = /(time\.sleep|asyncio\.sleep|threading\.[A-Za-z]*\.sleep|tokio::time::sleep|std::thread::sleep|Thread\.sleep|setTimeout)\s*\(/
|
|
30
31
|
|
|
31
|
-
// Error-based injection methods
|
|
32
|
-
$error_based_techniques = /\b(EXTRACTVALUE|UPDATEXML|EXP\(~\(SELECT
|
|
32
|
+
// Error-based injection methods (SQL-specific, not general cast())
|
|
33
|
+
$error_based_techniques = /\b(EXTRACTVALUE|UPDATEXML|EXP\(~\(SELECT)\s*\(/i
|
|
34
|
+
|
|
35
|
+
// SQL CAST injection (require SQL context)
|
|
36
|
+
$sql_cast_injection = /\bCAST\s*\([^)]*\s+AS\s+(INT|VARCHAR|CHAR|TEXT|NVARCHAR)\)/i
|
|
33
37
|
|
|
34
38
|
// Database-specific system objects in malicious contexts
|
|
35
39
|
$database_system_objects = /(\bSELECT [^;]*\b(information_schema|mysql\.user|all_tables|user_tables)\b|\bFROM\s+(information_schema|mysql\.user|dual|all_tables|user_tables)\b|LOAD_FILE\s*\(\s*['"][^'"]*\.(config|passwd|shadow|key)\b|INTO\s+OUTFILE\s+['"][^'"]*\.(txt|sql|php)\b|\b(xp_cmdshell|sp_executesql)\s*\(|dbms_[a-z_]+\s*\()/i
|
|
@@ -43,10 +47,17 @@ rule sql_injection{
|
|
|
43
47
|
// Common context phrases where these words appear in benign usage
|
|
44
48
|
$common_context_phrases = /\b(adds?\s+a\s+user|create\s+user|new\s+user|user\s+(account|profile|registration|authentication|permissions?|roles?)|user\s+(who|that)|for\s+user|the\s+user|current\s+user\s+(account|profile)|user\s+(input|data|information)|example:?\s+SELECT\s+USER\(\)|SELECT\s+USER\(\)\s+returns?|built-?in\s+function)\b/i
|
|
45
49
|
|
|
50
|
+
// Documentation and code examples (legitimate SQL shown in docs)
|
|
51
|
+
$documentation_markers = /(```sql|```mysql|```postgres|-- Example|-- Query|SELECT\s+.*FROM\s+.*--\s*\w+\s+query|sample\s+query|example\s+query)/i
|
|
52
|
+
$schema_exploration = /\b(information_schema|pg_catalog|sys\.(schemas|tables|columns))\b.*\b(documentation|reference|schema|metadata)\b/i
|
|
53
|
+
|
|
46
54
|
condition:
|
|
47
55
|
|
|
48
|
-
// Exclude
|
|
49
|
-
not $
|
|
56
|
+
// Exclude non-SQL sleep functions from all checks
|
|
57
|
+
not $non_sql_sleep and
|
|
58
|
+
// Exclude documentation showing SQL examples
|
|
59
|
+
not $documentation_markers and
|
|
60
|
+
not $schema_exploration and (
|
|
50
61
|
|
|
51
62
|
// SQL injection tautologies
|
|
52
63
|
($injection_tautologies and not $common_sql_ops and not $common_context_phrases) or
|
|
@@ -63,6 +74,9 @@ rule sql_injection{
|
|
|
63
74
|
// Error-based injection techniques
|
|
64
75
|
($error_based_techniques and not $common_sql_ops and not $common_context_phrases) or
|
|
65
76
|
|
|
77
|
+
// SQL CAST injection
|
|
78
|
+
($sql_cast_injection and not $common_sql_ops and not $common_context_phrases) or
|
|
79
|
+
|
|
66
80
|
// Database system object access
|
|
67
81
|
($database_system_objects and not $common_sql_ops and not $common_context_phrases) or
|
|
68
82
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//////////////////////////////////////////
|
|
2
|
+
// System Manipulation and Privilege Escalation Detection
|
|
3
|
+
// Target: File destruction and manipulation operations
|
|
4
|
+
// (Process control and termination)
|
|
5
|
+
//////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
rule system_manipulation_generic{
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
author = "Cisco"
|
|
11
|
+
description = "Detects system manipulation, privilege escalation, and destructive file operations"
|
|
12
|
+
classification = "harmful"
|
|
13
|
+
threat_type = "SYSTEM MANIPULATION"
|
|
14
|
+
|
|
15
|
+
strings:
|
|
16
|
+
// Suspicious environment variable manipulation (not just reading)
|
|
17
|
+
$env_var_manipulation = /\b(os\.environ\s*\[[^\]]*\]\s*=|export\s+PATH=|unset\s+(PATH|HOME|USER))\b/i
|
|
18
|
+
|
|
19
|
+
// File destruction and manipulation
|
|
20
|
+
$file_destruction = /\b(rm\s+-rf|dd\s+if=\/dev\/zero|wipefs|shred\s+-|find\s+[^\n]+-delete)\b/i
|
|
21
|
+
|
|
22
|
+
// Dangerous file permission changes
|
|
23
|
+
$permission_manipulation = /\b(chmod\s+(777|4755|6755|[ug]?\+s)|(chown|chgrp)\s+(root|0)|setuid|setgid)\b/i
|
|
24
|
+
|
|
25
|
+
// Critical system file access
|
|
26
|
+
$critical_system_access = /\b(\/etc\/(passwd|shadow|sudoers)|\/root\/\.ssh|~\/\.aws\/credentials|~\/\.ssh\/id_rsa)\b/i
|
|
27
|
+
|
|
28
|
+
// Privilege escalation patterns
|
|
29
|
+
$privilege_escalation = /\b(sudo\s+-[si]|su\s+-c?|runuser|doas)\b/i
|
|
30
|
+
|
|
31
|
+
// Dangerous process operations
|
|
32
|
+
$process_manipulation = /\b(kill\s+-9\s+[0-9]+|killall\s+-9|pkill\s+-9)\b/i
|
|
33
|
+
|
|
34
|
+
// Dangerous recursive operations with wildcards (exclude common cleanup dirs)
|
|
35
|
+
$recursive_operations = /\b(rm\s+-rf\s+(\/\s|\/root|\/home|\$HOME|~\/|\/etc|\/usr)|\bfind\s+\/\s+-delete)\b/i
|
|
36
|
+
|
|
37
|
+
// Safe cleanup patterns to exclude (Docker, npm, apt cache cleanup, backup retention)
|
|
38
|
+
$safe_cleanup = /(rm\s+-rf\s+(\/var\/lib\/apt\/lists|\/tmp\/|node_modules|__pycache__|\.cache|\.npm|\/var\/cache|dist|build|target)|find\s+[^\n]*-mtime\s+\+[0-9]+[^\n]*-delete|find\s+[^\n]*backup[^\n]*-delete)/i
|
|
39
|
+
|
|
40
|
+
// Testing and build commands (not manipulation)
|
|
41
|
+
$testing_commands = /\b(pytest|tox|make\s+test|npm\s+test|cargo\s+test|go\s+test|mvn\s+test|gradle\s+test|jest|mocha)\b/i
|
|
42
|
+
|
|
43
|
+
// Safe directory creation
|
|
44
|
+
$safe_mkdir = /\bmkdir\s+-p\b/
|
|
45
|
+
|
|
46
|
+
// System path manipulation
|
|
47
|
+
$path_manipulation = /\b(PATH=\/tmp|PATH=\.:|export\s+PATH=[\$\{])/i
|
|
48
|
+
|
|
49
|
+
condition:
|
|
50
|
+
// Exclude safe patterns
|
|
51
|
+
not $safe_cleanup and
|
|
52
|
+
not $testing_commands and
|
|
53
|
+
not $safe_mkdir and
|
|
54
|
+
(
|
|
55
|
+
// Environment variable manipulation (not just reading)
|
|
56
|
+
$env_var_manipulation or
|
|
57
|
+
|
|
58
|
+
// File destruction (not safe cleanup)
|
|
59
|
+
($file_destruction and not $safe_cleanup) or
|
|
60
|
+
|
|
61
|
+
// Permission manipulation
|
|
62
|
+
$permission_manipulation or
|
|
63
|
+
|
|
64
|
+
// Critical system access
|
|
65
|
+
$critical_system_access or
|
|
66
|
+
|
|
67
|
+
// Privilege escalation
|
|
68
|
+
$privilege_escalation or
|
|
69
|
+
|
|
70
|
+
// Process manipulation
|
|
71
|
+
$process_manipulation or
|
|
72
|
+
|
|
73
|
+
// Recursive operations
|
|
74
|
+
$recursive_operations or
|
|
75
|
+
|
|
76
|
+
// PATH manipulation
|
|
77
|
+
$path_manipulation
|
|
78
|
+
)
|
|
79
|
+
}
|