shellmate-cli 3.0.0__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.
- shellmate/__init__.py +0 -0
- shellmate/adapters/__init__.py +67 -0
- shellmate/adapters/bash_adapter.sh +7 -0
- shellmate/adapters/ble_adapter.sh +350 -0
- shellmate/adapters/powershell_adapter.ps1 +417 -0
- shellmate/adapters/powershell_predictor.ps1 +97 -0
- shellmate/adapters/zsh_adapter.zsh +8 -0
- shellmate/agents/__init__.py +23 -0
- shellmate/agents/base.py +248 -0
- shellmate/agents/chain_patterns.yaml +98 -0
- shellmate/agents/command_chain.py +322 -0
- shellmate/agents/context_gatherer.py +175 -0
- shellmate/agents/environment.py +363 -0
- shellmate/agents/librarian.py +502 -0
- shellmate/agents/query.py +415 -0
- shellmate/agents/repomix_backend.py +171 -0
- shellmate/agents/watcher.py +266 -0
- shellmate/cache/__init__.py +0 -0
- shellmate/cache/semantic_cache.py +41 -0
- shellmate/cli/__init__.py +0 -0
- shellmate/cli/commands/__init__.py +27 -0
- shellmate/cli/commands/analyze.py +5 -0
- shellmate/cli/commands/config.py +319 -0
- shellmate/cli/commands/configure.py +118 -0
- shellmate/cli/commands/disable.py +11 -0
- shellmate/cli/commands/enable.py +49 -0
- shellmate/cli/commands/init.py +412 -0
- shellmate/cli/commands/install.py +242 -0
- shellmate/cli/commands/migrate.py +147 -0
- shellmate/cli/commands/status.py +31 -0
- shellmate/cli/commands/uninstall.py +78 -0
- shellmate/cli/main.py +114 -0
- shellmate/cli/parser.py +184 -0
- shellmate/cli/version.py +1 -0
- shellmate/completion/__init__.py +4 -0
- shellmate/completion/bash_adapter.py +145 -0
- shellmate/config/__init__.py +33 -0
- shellmate/config/credentials.py +120 -0
- shellmate/config/defaults.py +88 -0
- shellmate/config/manager.py +94 -0
- shellmate/config/paths.py +77 -0
- shellmate/config/secrets.py +66 -0
- shellmate/daemon/__init__.py +0 -0
- shellmate/daemon/lifecycle.py +308 -0
- shellmate/daemon/observability.py +82 -0
- shellmate/daemon/pipeline.py +119 -0
- shellmate/daemon/server.py +605 -0
- shellmate/daemon/session.py +170 -0
- shellmate/daemon/startup_ui.py +43 -0
- shellmate/environment/__init__.py +0 -0
- shellmate/environment/detector.py +130 -0
- shellmate/ipc/__init__.py +0 -0
- shellmate/ipc/client.py +210 -0
- shellmate/ipc/ps_client.py +190 -0
- shellmate/orchestration/__init__.py +3 -0
- shellmate/orchestration/analysis_graph.py +1274 -0
- shellmate/orchestration/state.py +35 -0
- shellmate/parser/__init__.py +0 -0
- shellmate/parser/command_parser.py +111 -0
- shellmate/plugins/__init__.py +0 -0
- shellmate/plugins/base.py +80 -0
- shellmate/plugins/loader.py +41 -0
- shellmate/providers/__init__.py +0 -0
- shellmate/providers/base.py +97 -0
- shellmate/providers/groq_command_guide.py +108 -0
- shellmate/providers/groq_provider.py +127 -0
- shellmate/providers/groq_supervisor.py +78 -0
- shellmate/providers/openrouter_provider.py +149 -0
- shellmate/providers/router.py +272 -0
- shellmate/providers/validate_keys.py +98 -0
- shellmate/providers/xai_provider.py +142 -0
- shellmate/rules/__init__.py +0 -0
- shellmate/rules/catastrophic.yaml +96 -0
- shellmate/rules/catastrophic_matcher.py +167 -0
- shellmate/rules/definitions/__init__.py +0 -0
- shellmate/rules/definitions/file_deletion.yaml +54 -0
- shellmate/rules/definitions/filesystem.yaml +43 -0
- shellmate/rules/definitions/network_execution.yaml +46 -0
- shellmate/rules/definitions/permissions.yaml +54 -0
- shellmate/rules/definitions/process_control.yaml +37 -0
- shellmate/rules/definitions/system_destruction.yaml +67 -0
- shellmate/rules/engine.py +200 -0
- shellmate/sanitizer/__init__.py +0 -0
- shellmate/sanitizer/typo_detector.py +114 -0
- shellmate/ui/__init__.py +10 -0
- shellmate/ui/analysis.py +164 -0
- shellmate/ui/annotations.py +232 -0
- shellmate/ui/banner.py +49 -0
- shellmate/ui/progress.py +126 -0
- shellmate/ui/runtime/__init__.py +15 -0
- shellmate/ui/runtime/console_factory.py +65 -0
- shellmate/ui/runtime/live_scene.py +116 -0
- shellmate/ui/runtime/motion_policy.py +69 -0
- shellmate/ui/runtime/tokens.py +47 -0
- shellmate/ui/scenes/__init__.py +24 -0
- shellmate/ui/scenes/enable.py +316 -0
- shellmate/ui/scenes/help.py +53 -0
- shellmate/ui/scenes/stages.py +128 -0
- shellmate/ui/scenes/status.py +181 -0
- shellmate/ui/status.py +3 -0
- shellmate_cli-3.0.0.dist-info/METADATA +352 -0
- shellmate_cli-3.0.0.dist-info/RECORD +106 -0
- shellmate_cli-3.0.0.dist-info/WHEEL +5 -0
- shellmate_cli-3.0.0.dist-info/entry_points.txt +3 -0
- shellmate_cli-3.0.0.dist-info/licenses/LICENSE +21 -0
- shellmate_cli-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Catastrophic commands requiring confirmation (NO API dependency)
|
|
2
|
+
- id: "rm_rf_root"
|
|
3
|
+
category: "catastrophic"
|
|
4
|
+
instant: true
|
|
5
|
+
severity: "CRITICAL"
|
|
6
|
+
program: "rm"
|
|
7
|
+
flags: ["-rf", "-fr"]
|
|
8
|
+
arguments: ["^/$", "^/\\*$", "^~/$"]
|
|
9
|
+
message: "⚠️ DANGER: Deletes entire filesystem"
|
|
10
|
+
confirm_required: true
|
|
11
|
+
|
|
12
|
+
- id: "git_push_force"
|
|
13
|
+
category: "catastrophic"
|
|
14
|
+
instant: true
|
|
15
|
+
severity: "CRITICAL"
|
|
16
|
+
program: "git"
|
|
17
|
+
subcommand: "push"
|
|
18
|
+
flags: ["--force", "-f"]
|
|
19
|
+
message: "⚠️ Rewrites remote history"
|
|
20
|
+
confirm_required: true
|
|
21
|
+
|
|
22
|
+
- id: "dd_to_device"
|
|
23
|
+
category: "catastrophic"
|
|
24
|
+
instant: true
|
|
25
|
+
severity: "CRITICAL"
|
|
26
|
+
program: "dd"
|
|
27
|
+
arguments: ["of=/dev/sd", "of=/dev/nvme", "of=/dev/vd"]
|
|
28
|
+
message: "⚠️ Writes raw data to disk"
|
|
29
|
+
confirm_required: true
|
|
30
|
+
|
|
31
|
+
- id: "drop_database"
|
|
32
|
+
category: "catastrophic"
|
|
33
|
+
instant: true
|
|
34
|
+
severity: "CRITICAL"
|
|
35
|
+
program: "mysql"
|
|
36
|
+
arguments: ["DROP\\s+DATABASE"]
|
|
37
|
+
message: "⚠️ Deletes entire database"
|
|
38
|
+
confirm_required: true
|
|
39
|
+
|
|
40
|
+
- id: "chmod_777_recursive"
|
|
41
|
+
category: "catastrophic"
|
|
42
|
+
instant: true
|
|
43
|
+
severity: "HIGH"
|
|
44
|
+
program: "chmod"
|
|
45
|
+
flags: ["-R"]
|
|
46
|
+
arguments: ["777"]
|
|
47
|
+
message: "⚠️ Removes all security protections"
|
|
48
|
+
confirm_required: true
|
|
49
|
+
|
|
50
|
+
- id: "git_reset_hard"
|
|
51
|
+
category: "catastrophic"
|
|
52
|
+
instant: true
|
|
53
|
+
severity: "HIGH"
|
|
54
|
+
program: "git"
|
|
55
|
+
subcommand: "reset"
|
|
56
|
+
flags: ["--hard"]
|
|
57
|
+
message: "⚠️ Discards all uncommitted changes"
|
|
58
|
+
confirm_required: true
|
|
59
|
+
|
|
60
|
+
- id: "docker_rm_all"
|
|
61
|
+
category: "catastrophic"
|
|
62
|
+
instant: true
|
|
63
|
+
severity: "HIGH"
|
|
64
|
+
program: "docker"
|
|
65
|
+
subcommand: "rm"
|
|
66
|
+
flags: ["-f"]
|
|
67
|
+
arguments: ["\\$\\(docker ps", "\\$\\(docker container"]
|
|
68
|
+
message: "⚠️ Deletes all containers"
|
|
69
|
+
confirm_required: true
|
|
70
|
+
|
|
71
|
+
- id: "kill_all_processes"
|
|
72
|
+
category: "catastrophic"
|
|
73
|
+
instant: true
|
|
74
|
+
severity: "HIGH"
|
|
75
|
+
program: "kill"
|
|
76
|
+
arguments: ["-9 -1", "-9 1"]
|
|
77
|
+
message: "⚠️ Kills all user processes"
|
|
78
|
+
confirm_required: true
|
|
79
|
+
|
|
80
|
+
- id: "mkfs_on_device"
|
|
81
|
+
category: "catastrophic"
|
|
82
|
+
instant: true
|
|
83
|
+
severity: "CRITICAL"
|
|
84
|
+
program: "mkfs"
|
|
85
|
+
arguments: ["/dev/sd", "/dev/nvme", "/dev/vd"]
|
|
86
|
+
message: "⚠️ Formats disk device"
|
|
87
|
+
confirm_required: true
|
|
88
|
+
|
|
89
|
+
- id: "curl_pipe_bash"
|
|
90
|
+
category: "catastrophic"
|
|
91
|
+
instant: true
|
|
92
|
+
severity: "HIGH"
|
|
93
|
+
program: "curl"
|
|
94
|
+
arguments: ["\\|\\s*bash", "\\|\\s*sh"]
|
|
95
|
+
message: "⚠️ Executes remote script"
|
|
96
|
+
confirm_required: true
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import yaml
|
|
4
|
+
from shellmate.parser.command_parser import parse_command
|
|
5
|
+
|
|
6
|
+
CATASTROPHIC_FILE = os.path.join(os.path.dirname(__file__), "catastrophic.yaml")
|
|
7
|
+
|
|
8
|
+
# In-memory cache — YAML reload every keystroke blew past the <5–10ms budget (~11ms P99).
|
|
9
|
+
# Do NOT call getmtime on every match: on WSL /mnt/* mounts that alone can be 5–8ms.
|
|
10
|
+
_CACHED_RULES = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_catastrophic_rules(force_reload: bool = False):
|
|
14
|
+
"""Load instant-match catastrophic rules (no API dependency).
|
|
15
|
+
|
|
16
|
+
Rules are cached in-process. Pass force_reload=True after editing YAML.
|
|
17
|
+
"""
|
|
18
|
+
global _CACHED_RULES
|
|
19
|
+
|
|
20
|
+
if not force_reload and _CACHED_RULES is not None:
|
|
21
|
+
return _CACHED_RULES
|
|
22
|
+
|
|
23
|
+
if not os.path.exists(CATASTROPHIC_FILE):
|
|
24
|
+
_CACHED_RULES = []
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
with open(CATASTROPHIC_FILE, "r", encoding="utf-8") as f:
|
|
28
|
+
rules = yaml.safe_load(f) or []
|
|
29
|
+
_CACHED_RULES = [r for r in rules if r.get("instant")]
|
|
30
|
+
return _CACHED_RULES
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def match_catastrophic(command_string):
|
|
34
|
+
"""
|
|
35
|
+
Instant match against catastrophic commands.
|
|
36
|
+
Returns: {"matched": bool, "rule": dict, "message": str}
|
|
37
|
+
"""
|
|
38
|
+
rules = load_catastrophic_rules()
|
|
39
|
+
parsed = parse_command(command_string)
|
|
40
|
+
|
|
41
|
+
for rule in rules:
|
|
42
|
+
# Handle both single commands and pipelines
|
|
43
|
+
if isinstance(parsed, dict) and parsed.get("pipeline"):
|
|
44
|
+
# For pipelines, check all segments
|
|
45
|
+
for segment_type, segment_data in parsed.get("segments", []):
|
|
46
|
+
if segment_type == "command" and _match_rule(segment_data, command_string, rule):
|
|
47
|
+
return {
|
|
48
|
+
"matched": True,
|
|
49
|
+
"rule_id": rule["id"],
|
|
50
|
+
"category": rule["category"],
|
|
51
|
+
"severity": rule["severity"],
|
|
52
|
+
"message": rule["message"],
|
|
53
|
+
"confirm_required": rule.get("confirm_required", True),
|
|
54
|
+
}
|
|
55
|
+
elif _match_rule(parsed, command_string, rule):
|
|
56
|
+
return {
|
|
57
|
+
"matched": True,
|
|
58
|
+
"rule_id": rule["id"],
|
|
59
|
+
"category": rule["category"],
|
|
60
|
+
"severity": rule["severity"],
|
|
61
|
+
"message": rule["message"],
|
|
62
|
+
"confirm_required": rule.get("confirm_required", True),
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {"matched": False}
|
|
66
|
+
|
|
67
|
+
def _match_rule(parsed, command_string, rule):
|
|
68
|
+
"""Match single rule using existing engine logic"""
|
|
69
|
+
if isinstance(parsed, dict):
|
|
70
|
+
cmd_program = parsed.get("program")
|
|
71
|
+
else:
|
|
72
|
+
import shlex
|
|
73
|
+
try:
|
|
74
|
+
tokens = shlex.split(str(command_string))
|
|
75
|
+
cmd_program = tokens[0] if tokens else None
|
|
76
|
+
except ValueError:
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
# Check program match (handle variants like mkfs.ext4 matching mkfs)
|
|
80
|
+
rule_program = rule.get("program")
|
|
81
|
+
if cmd_program != rule_program:
|
|
82
|
+
# Try prefix match for programs like mkfs.ext4
|
|
83
|
+
if not (cmd_program and cmd_program.startswith(rule_program + ".")):
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
# Check subcommand (for git push, git reset, docker rm, etc.)
|
|
87
|
+
expected_subcommand = rule.get("subcommand")
|
|
88
|
+
if expected_subcommand:
|
|
89
|
+
if isinstance(parsed, dict):
|
|
90
|
+
actual_subcommand = parsed.get("subcommand")
|
|
91
|
+
if actual_subcommand != expected_subcommand:
|
|
92
|
+
return False
|
|
93
|
+
else:
|
|
94
|
+
import shlex
|
|
95
|
+
try:
|
|
96
|
+
tokens = shlex.split(command_string)
|
|
97
|
+
if len(tokens) < 2 or tokens[1] != expected_subcommand:
|
|
98
|
+
return False
|
|
99
|
+
except ValueError:
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
# Check flags
|
|
103
|
+
expected_flags = rule.get("flags", [])
|
|
104
|
+
if expected_flags:
|
|
105
|
+
cmd_flags = parsed.get("flags", []) if isinstance(parsed, dict) else []
|
|
106
|
+
flag_values = {f["flag"] for f in cmd_flags} if cmd_flags else set()
|
|
107
|
+
|
|
108
|
+
# Check if any expected flag is present (handle combined flags like -rf)
|
|
109
|
+
found_flag = False
|
|
110
|
+
for expected_flag in expected_flags:
|
|
111
|
+
# Direct match
|
|
112
|
+
if expected_flag in flag_values or expected_flag in command_string:
|
|
113
|
+
found_flag = True
|
|
114
|
+
break
|
|
115
|
+
# Check for combined flags (e.g., "-rf" contains both "-r" and "-f")
|
|
116
|
+
if expected_flag.startswith("-") and not expected_flag.startswith("--"):
|
|
117
|
+
# Single dash flags can be combined
|
|
118
|
+
expected_letters = set(expected_flag.lstrip("-"))
|
|
119
|
+
for actual_flag in flag_values:
|
|
120
|
+
if actual_flag.startswith("-") and not actual_flag.startswith("--"):
|
|
121
|
+
actual_letters = set(actual_flag.lstrip("-"))
|
|
122
|
+
if expected_letters.issubset(actual_letters):
|
|
123
|
+
found_flag = True
|
|
124
|
+
break
|
|
125
|
+
if found_flag:
|
|
126
|
+
break
|
|
127
|
+
|
|
128
|
+
if not found_flag:
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
# Check arguments
|
|
132
|
+
expected_args = rule.get("arguments", [])
|
|
133
|
+
if expected_args:
|
|
134
|
+
cmd_args = parsed.get("arguments", []) if isinstance(parsed, dict) else []
|
|
135
|
+
arg_str = " ".join(cmd_args) if cmd_args else ""
|
|
136
|
+
|
|
137
|
+
# Try matching against arguments first, then full command (for pipes)
|
|
138
|
+
found_arg = False
|
|
139
|
+
for pat in expected_args:
|
|
140
|
+
# Try matching individual arguments for patterns like ^/$
|
|
141
|
+
if arg_str and re.search(pat, arg_str):
|
|
142
|
+
found_arg = True
|
|
143
|
+
break
|
|
144
|
+
# Also check each argument individually
|
|
145
|
+
for arg in cmd_args:
|
|
146
|
+
if re.search(pat, arg):
|
|
147
|
+
found_arg = True
|
|
148
|
+
break
|
|
149
|
+
if found_arg:
|
|
150
|
+
break
|
|
151
|
+
# Fallback: check full command string for patterns like pipes
|
|
152
|
+
if re.search(pat, command_string):
|
|
153
|
+
found_arg = True
|
|
154
|
+
break
|
|
155
|
+
|
|
156
|
+
if not found_arg:
|
|
157
|
+
return False
|
|
158
|
+
|
|
159
|
+
return True
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
import json
|
|
164
|
+
import sys
|
|
165
|
+
|
|
166
|
+
cmd = sys.argv[1] if len(sys.argv) > 1 else ""
|
|
167
|
+
print(json.dumps(match_catastrophic(cmd)))
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
- id: "rm_force_recursive_root"
|
|
2
|
+
category: "file_deletion"
|
|
3
|
+
severity: "CRITICAL"
|
|
4
|
+
description: "Force recursive delete on root directory"
|
|
5
|
+
program: "rm"
|
|
6
|
+
flags:
|
|
7
|
+
- "-rf"
|
|
8
|
+
- "-fr"
|
|
9
|
+
arguments:
|
|
10
|
+
- "^/$"
|
|
11
|
+
message: "This will recursively delete all files on the system without confirmation."
|
|
12
|
+
confidence: 0.98
|
|
13
|
+
|
|
14
|
+
- id: "rm_force_recursive"
|
|
15
|
+
category: "file_deletion"
|
|
16
|
+
severity: "HIGH"
|
|
17
|
+
description: "Force recursive delete without confirmation"
|
|
18
|
+
program: "rm"
|
|
19
|
+
flags:
|
|
20
|
+
- "-rf"
|
|
21
|
+
- "-fr"
|
|
22
|
+
message: "Recursively deletes files without confirmation. Consider using -ri for interactive deletion."
|
|
23
|
+
confidence: 0.85
|
|
24
|
+
|
|
25
|
+
- id: "rm_force"
|
|
26
|
+
category: "file_deletion"
|
|
27
|
+
severity: "HIGH"
|
|
28
|
+
description: "Force delete without confirmation"
|
|
29
|
+
program: "rm"
|
|
30
|
+
flags:
|
|
31
|
+
- "-f"
|
|
32
|
+
message: "Force deletes files without confirmation. Use -i for interactive mode."
|
|
33
|
+
confidence: 0.80
|
|
34
|
+
|
|
35
|
+
- id: "shred_command"
|
|
36
|
+
category: "file_deletion"
|
|
37
|
+
severity: "HIGH"
|
|
38
|
+
description: "Secure file deletion with shred"
|
|
39
|
+
program: "shred"
|
|
40
|
+
message: "Permanently deletes files making recovery difficult."
|
|
41
|
+
confidence: 0.90
|
|
42
|
+
|
|
43
|
+
- id: "rm_rf_var_log"
|
|
44
|
+
category: "file_deletion"
|
|
45
|
+
severity: "CRITICAL"
|
|
46
|
+
description: "Delete critical system log directory"
|
|
47
|
+
program: "rm"
|
|
48
|
+
flags:
|
|
49
|
+
- "-rf"
|
|
50
|
+
- "-fr"
|
|
51
|
+
arguments:
|
|
52
|
+
- "^/var/log"
|
|
53
|
+
message: "Deleting /var/log will remove all system logs."
|
|
54
|
+
confidence: 0.95
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
- id: "mkfs_command"
|
|
2
|
+
category: "filesystem"
|
|
3
|
+
severity: "CRITICAL"
|
|
4
|
+
description: "Create a filesystem (format a partition)"
|
|
5
|
+
program: "mkfs"
|
|
6
|
+
message: "This will format the target device, destroying all data on it."
|
|
7
|
+
confidence: 0.97
|
|
8
|
+
|
|
9
|
+
- id: "fdisk_write"
|
|
10
|
+
category: "filesystem"
|
|
11
|
+
severity: "CRITICAL"
|
|
12
|
+
description: "Write partition table changes"
|
|
13
|
+
program: "fdisk"
|
|
14
|
+
flags:
|
|
15
|
+
- "-w"
|
|
16
|
+
message: "Writing partition table changes can destroy data on disk."
|
|
17
|
+
confidence: 0.95
|
|
18
|
+
|
|
19
|
+
- id: "dd_command"
|
|
20
|
+
category: "filesystem"
|
|
21
|
+
severity: "CRITICAL"
|
|
22
|
+
description: "Raw disk copy/wipe operation"
|
|
23
|
+
program: "dd"
|
|
24
|
+
message: "dd can overwrite disks and partitions directly, potentially destroying data."
|
|
25
|
+
confidence: 0.95
|
|
26
|
+
|
|
27
|
+
- id: "parted_mklabel"
|
|
28
|
+
category: "filesystem"
|
|
29
|
+
severity: "CRITICAL"
|
|
30
|
+
description: "Create partition table label"
|
|
31
|
+
program: "parted"
|
|
32
|
+
arguments:
|
|
33
|
+
- "mklabel"
|
|
34
|
+
message: "Creating a new partition table will destroy existing partitions."
|
|
35
|
+
confidence: 0.96
|
|
36
|
+
|
|
37
|
+
- id: "mkswap"
|
|
38
|
+
category: "filesystem"
|
|
39
|
+
severity: "HIGH"
|
|
40
|
+
description: "Set up swap area on device"
|
|
41
|
+
program: "mkswap"
|
|
42
|
+
message: "Setting up a swap area on the wrong device can destroy data."
|
|
43
|
+
confidence: 0.85
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
- id: "curl_pipe_bash"
|
|
2
|
+
category: "network_execution"
|
|
3
|
+
severity: "HIGH"
|
|
4
|
+
description: "Pipe curl output to bash (remote code execution)"
|
|
5
|
+
pipeline: true
|
|
6
|
+
pattern:
|
|
7
|
+
- program: "curl"
|
|
8
|
+
- operator: "pipe"
|
|
9
|
+
- program: "bash"
|
|
10
|
+
message: "Piping a remote script directly to bash is a security risk. Review the script before executing."
|
|
11
|
+
confidence: 0.92
|
|
12
|
+
|
|
13
|
+
- id: "wget_pipe_sh"
|
|
14
|
+
category: "network_execution"
|
|
15
|
+
severity: "HIGH"
|
|
16
|
+
description: "Pipe wget output to sh (remote code execution)"
|
|
17
|
+
pipeline: true
|
|
18
|
+
pattern:
|
|
19
|
+
- program: "wget"
|
|
20
|
+
- operator: "pipe"
|
|
21
|
+
- program: "sh"
|
|
22
|
+
message: "Piping a remote script directly to sh is a security risk. Review the script before executing."
|
|
23
|
+
confidence: 0.92
|
|
24
|
+
|
|
25
|
+
- id: "curl_pipe_sh"
|
|
26
|
+
category: "network_execution"
|
|
27
|
+
severity: "HIGH"
|
|
28
|
+
description: "Pipe curl output to sh (remote code execution)"
|
|
29
|
+
pipeline: true
|
|
30
|
+
pattern:
|
|
31
|
+
- program: "curl"
|
|
32
|
+
- operator: "pipe"
|
|
33
|
+
- program: "sh"
|
|
34
|
+
message: "Piping a remote script directly to sh is a security risk. Review the script before executing."
|
|
35
|
+
confidence: 0.92
|
|
36
|
+
|
|
37
|
+
- id: "curl_insecure"
|
|
38
|
+
category: "network_execution"
|
|
39
|
+
severity: "MEDIUM"
|
|
40
|
+
description: "Skip SSL certificate verification"
|
|
41
|
+
program: "curl"
|
|
42
|
+
flags:
|
|
43
|
+
- "-k"
|
|
44
|
+
- "--insecure"
|
|
45
|
+
message: "Skipping SSL verification exposes the connection to MITM attacks."
|
|
46
|
+
confidence: 0.80
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
- id: "chmod_recursive_777_root"
|
|
2
|
+
category: "permissions"
|
|
3
|
+
severity: "CRITICAL"
|
|
4
|
+
description: "Recursively set world-writable permissions on root"
|
|
5
|
+
program: "chmod"
|
|
6
|
+
flags:
|
|
7
|
+
- "-R"
|
|
8
|
+
arguments:
|
|
9
|
+
- "777"
|
|
10
|
+
- "^/$"
|
|
11
|
+
message: "Makes all files world-writable. This is a severe security risk."
|
|
12
|
+
confidence: 0.98
|
|
13
|
+
|
|
14
|
+
- id: "chmod_777"
|
|
15
|
+
category: "permissions"
|
|
16
|
+
severity: "HIGH"
|
|
17
|
+
description: "Set world-writable permissions"
|
|
18
|
+
program: "chmod"
|
|
19
|
+
arguments:
|
|
20
|
+
- "777"
|
|
21
|
+
message: "Makes files world-writable. Consider using more restrictive permissions."
|
|
22
|
+
confidence: 0.90
|
|
23
|
+
|
|
24
|
+
- id: "chmod_recursive_777"
|
|
25
|
+
category: "permissions"
|
|
26
|
+
severity: "HIGH"
|
|
27
|
+
description: "Recursively set world-writable permissions"
|
|
28
|
+
program: "chmod"
|
|
29
|
+
flags:
|
|
30
|
+
- "-R"
|
|
31
|
+
arguments:
|
|
32
|
+
- "777"
|
|
33
|
+
message: "Recursively makes files world-writable. This is a security risk."
|
|
34
|
+
confidence: 0.95
|
|
35
|
+
|
|
36
|
+
- id: "chown_recursive"
|
|
37
|
+
category: "permissions"
|
|
38
|
+
severity: "MEDIUM"
|
|
39
|
+
description: "Recursively change ownership"
|
|
40
|
+
program: "chown"
|
|
41
|
+
flags:
|
|
42
|
+
- "-R"
|
|
43
|
+
message: "Recursively changing ownership can affect many files."
|
|
44
|
+
confidence: 0.75
|
|
45
|
+
|
|
46
|
+
- id: "chmod_000"
|
|
47
|
+
category: "permissions"
|
|
48
|
+
severity: "HIGH"
|
|
49
|
+
description: "Remove all permissions from files"
|
|
50
|
+
program: "chmod"
|
|
51
|
+
arguments:
|
|
52
|
+
- "000"
|
|
53
|
+
message: "Removes all permissions, making files inaccessible."
|
|
54
|
+
confidence: 0.90
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
- id: "kill_9"
|
|
2
|
+
category: "process_control"
|
|
3
|
+
severity: "HIGH"
|
|
4
|
+
description: "Force kill a process (SIGKILL)"
|
|
5
|
+
program: "kill"
|
|
6
|
+
flags:
|
|
7
|
+
- "-9"
|
|
8
|
+
- "-KILL"
|
|
9
|
+
- "--signal"
|
|
10
|
+
message: "Force kills a process without allowing cleanup. Use -15 (SIGTERM) for graceful shutdown."
|
|
11
|
+
confidence: 0.85
|
|
12
|
+
|
|
13
|
+
- id: "killall_command"
|
|
14
|
+
category: "process_control"
|
|
15
|
+
severity: "MEDIUM"
|
|
16
|
+
description: "Kill all processes by name"
|
|
17
|
+
program: "killall"
|
|
18
|
+
message: "Kills all processes with the given name. Use with caution."
|
|
19
|
+
confidence: 0.80
|
|
20
|
+
|
|
21
|
+
- id: "pkill_command"
|
|
22
|
+
category: "process_control"
|
|
23
|
+
severity: "MEDIUM"
|
|
24
|
+
description: "Kill processes by name pattern"
|
|
25
|
+
program: "pkill"
|
|
26
|
+
message: "Kills processes matching a pattern. May affect unintended processes."
|
|
27
|
+
confidence: 0.75
|
|
28
|
+
|
|
29
|
+
- id: "xargs_kill"
|
|
30
|
+
category: "process_control"
|
|
31
|
+
severity: "HIGH"
|
|
32
|
+
description: "Pipe to xargs kill"
|
|
33
|
+
program: "xargs"
|
|
34
|
+
arguments:
|
|
35
|
+
- "kill"
|
|
36
|
+
message: "This pattern can mass-kill processes. Verify the process list first."
|
|
37
|
+
confidence: 0.80
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
- id: "dd_of_dev_sda"
|
|
2
|
+
category: "system_destruction"
|
|
3
|
+
severity: "CRITICAL"
|
|
4
|
+
description: "Write directly to disk device"
|
|
5
|
+
program: "dd"
|
|
6
|
+
arguments:
|
|
7
|
+
- "of=/?dev/sd"
|
|
8
|
+
- "of=/?dev/nvme"
|
|
9
|
+
- "of=/?dev/vd"
|
|
10
|
+
message: "Writing directly to a disk device will destroy the partition table and all data."
|
|
11
|
+
confidence: 0.99
|
|
12
|
+
|
|
13
|
+
- id: "fork_bomb"
|
|
14
|
+
category: "system_destruction"
|
|
15
|
+
severity: "CRITICAL"
|
|
16
|
+
description: "Fork bomb pattern detected"
|
|
17
|
+
program: ":(){"
|
|
18
|
+
message: "This is a fork bomb that will crash your system by exhausting all processes."
|
|
19
|
+
confidence: 0.99
|
|
20
|
+
|
|
21
|
+
- id: "reboot_command"
|
|
22
|
+
category: "system_destruction"
|
|
23
|
+
severity: "HIGH"
|
|
24
|
+
description: "System reboot"
|
|
25
|
+
program: "reboot"
|
|
26
|
+
message: "This will reboot the system. Ensure all work is saved."
|
|
27
|
+
confidence: 0.90
|
|
28
|
+
|
|
29
|
+
- id: "shutdown_now"
|
|
30
|
+
category: "system_destruction"
|
|
31
|
+
severity: "HIGH"
|
|
32
|
+
description: "Immediate system shutdown"
|
|
33
|
+
program: "shutdown"
|
|
34
|
+
flags:
|
|
35
|
+
- "-h"
|
|
36
|
+
- "-r"
|
|
37
|
+
- "-P"
|
|
38
|
+
arguments:
|
|
39
|
+
- "^now$"
|
|
40
|
+
message: "This will shut down the system immediately."
|
|
41
|
+
confidence: 0.90
|
|
42
|
+
|
|
43
|
+
- id: "poweroff"
|
|
44
|
+
category: "system_destruction"
|
|
45
|
+
severity: "HIGH"
|
|
46
|
+
description: "Power off system"
|
|
47
|
+
program: "poweroff"
|
|
48
|
+
message: "This will power off the system."
|
|
49
|
+
confidence: 0.90
|
|
50
|
+
|
|
51
|
+
- id: "halt_command"
|
|
52
|
+
category: "system_destruction"
|
|
53
|
+
severity: "HIGH"
|
|
54
|
+
description: "Halt the system"
|
|
55
|
+
program: "halt"
|
|
56
|
+
message: "This will halt the system."
|
|
57
|
+
confidence: 0.85
|
|
58
|
+
|
|
59
|
+
- id: "passwd_root"
|
|
60
|
+
category: "system_destruction"
|
|
61
|
+
severity: "HIGH"
|
|
62
|
+
description: "Change root password"
|
|
63
|
+
program: "passwd"
|
|
64
|
+
arguments:
|
|
65
|
+
- "^root$"
|
|
66
|
+
message: "Changing the root password can lock you out of the system if not done carefully."
|
|
67
|
+
confidence: 0.80
|