RCE via Tool Arguments
OpsBot exposes a ping(host) tool implemented as sh -c "ping -c1 " + host. To stop injection it runs a blocklist that strips ; and && from your argument. Everything else passes straight to the shell.
Supply a host argument that breaks out of the ping command and runs your own command (e.g. id or cat /etc/passwd) using a metacharacter the blocklist does not strip.
# awaiting command — type a payload and press Enter
No leads yet. Declassify intel one step at a time when you’re stuck.
How this attack works
The argument was concatenated into a shell string and the blocklist only removed two tokens. Command substitution $(…), backticks, pipes, a newline, or ${IFS} all reach the shell untouched and execute. A blocklist enumerates bad inputs; the shell grammar is far larger than any blocklist.
Why it's dangerous
Agents are increasingly wired to real tools (shells, HTTP, files). If a tool builds a shell command from model- or user-controlled text, one missed metacharacter is remote code execution on the host. SkillTotal flags shell-building sinks as ST-CMDI-PY.
OWASP mapping
Maps to OWASP Top 10 for LLM Applications (2025): LLM06: Excessive Agency (a tool with more power than it can safely be given untrusted input). SkillTotal’s ST-CMDI-PY flags command-injection sinks statically.
Related framework entries
- OWASP Agentic Skills Top 10 (2026): AST03: Over-Privileged Skills
- OWASP Agentic Skills Top 10 (2026): AST06: Weak Isolation
- MITRE ATLAS: AML.T0050 Command and Scripting Interpreter
- MITRE ATLAS: AML.T0053 AI Agent Tool Invocation
These show which published techniques the level exercises. SkillTotal is not affiliated with OWASP or MITRE, and they do not endorse the labs.
How to defend
- Never build a shell string from untrusted input — pass an argv array (no
sh -c). - Validate against a strict allowlist (e.g. a hostname/IP regex), not a blocklist.
- Drop the shell entirely; call the library/syscall directly.
- Run tools with least privilege in a sandbox so a breakout has nothing to reach.
SkillTotal catches this class of issue deterministically (rule ST-CMDI-PY).
FAQ
- Why is a blocklist the wrong control here?
- The shell metacharacter space is large and composable. Stripping ; and && leaves $(), backticks, pipes, redirects, newlines, and ${IFS}. Allowlisting the expected shape is the only robust option.
- How does SkillTotal detect this?
- ST-CMDI-PY statically flags code paths that pass untrusted data into a shell-executing sink (os.system, subprocess with shell=True, sh -c), so the dangerous tool is caught before it ships.