Selam millet, BlueTornado burada.
Command Injection (OS komut enjeksiyonu), uygulamanın kullanıcı girdisini işletim sistemi kabuğuna güvensiz biçimde iletmesiyle oluşur. SQL Injection veritabanını hedeflerken, command injection doğrudan sunucu sürecini hedefler; etki çoğu zaman kritiktir. Bu yazıda CWE-78 bağlamında teori, DVWA/lab gözlemi ve güvenli kodlama odaklı korunma anlatılır.
Konuda Anlatılacaklar
- Command injection nedir?
- Kodlama hataları: shell=True, string birleştirme
- Lab ortamı ve güvenli gözlem
- Metacharacter'lar ve çıktı yorumlama
- Korunma: API'ler, allowlist, least privilege
- İleri seviye: argument injection, kör enjeksiyon
- Kaynakça ve yasal uyarı
1) Teori
Birçok uygulama ping, traceroute, görüntü işleme, yedekleme gibi işler için dış komut çağırır. Girdi kabuğa birleşirse saldırgan ek komut zincirleyebilir.
# Tehlikeli Python kalıbı
import os
ip = request.args["ip"]
os.system("ping -c 1 " + ip)
# ip = 127.0.0.1; id -> kabuk ; ile ikinci komutu çalıştırabilir# Tehlikeli PHP kalıbı
system("ping -c 1 " . $_GET["ip"]);OWASP Top 10 2021'de Injection (A03) ailesindedir. CWE: CWE-78 (OS Command Injection). Argument injection (CWE-88) yakından ilişkilidir: kabuk olmasa bile program argümanları kötüye kullanılabilir.
2) Lab Kurulumu
DVWA Command Injection sayfası klasik bir örnektir.
cd DVWA && docker compose up -d
# Security: LowAlternatif: kendi izole VM'inizde bilerek zayıf küçük bir Flask uygulaması (internete açmayın).
[center][/center]
3) Kavram Referansı
Kabuk metacharacter örnekleri (bilgi amaçlı):
# Komut ayırıcı / zincir (Unix)
; && || |
# Yerine koyma
`...` $(...)
# Yönlendirme
> >>Güvenli çağrı: Kabuğu devre dışı bırakıp argüman listesi geçmek.
import subprocess
subprocess.run(["ping", "-c", "1", ip], check=False)
# shell=False (varsayılan) — ip artık yeni komut başlatamaz
# AMA ip'nin ping'e özel zararlı argüman olup olmadığı ayrı konudurAllowlist:
import ipaddress
def validate_ip(s: str) -> str:
return str(ipaddress.ip_address(s)) # geçersizse exception4) DVWA Low: Adım Adım Gözlem
Yalnızca kendi DVWA'nızda:
Adım 1 - Normal:
127.0.0.1
# Beklenen: ping çıktısıAdım 2 - Zincir gözlemi (lab):
127.0.0.1; uname -a[center][/center]
Adım 3 - Filtreli seviyeler: Medium'da
&&;%0a# Not şablonu
Seviye: Medium
Payload: 127.0.0.1; id
Sonuç: ; silindi / komut çalışmadı / hata
Çıkarım: blacklistAdım 4 - Çıktıyı yorumlama:
- Ek komut çıktısı görünüyorsa RCE etkisi vardır
- Çıktı görünmese bile time-based kör enjeksiyon mümkün olabilir
- Uygulama hangi OS kullanıcısı ile çalışıyor? (www-data vb.) — least privilege kritik
5) Güvenli Kodlama
- Mümkünse hiç dış komut çağırmayın; dilin kendi kütüphanesini kullanın
- Çağrı zorunluysa /Kod:
subprocessargüman dizisi;Kod:execveyasakKod:shell=True - Girdiyi allowlist ile doğrulayın (IP, enum, sabit seçenekler)
- Kullanıcı girdisini asla komut şablonuna birleştirmeyin
- Uygulamayı düşük yetkili kullanıcı ile çalıştırın; container'da root'tan kaçının
- Gerekli binary'lere filesystem izni sınırlayın
# İyi: IP doğrulama + argüman listesi
import ipaddress, subprocess
ip = str(ipaddress.ip_address(user_input))
subprocess.run(["ping", "-c", "1", ip], capture_output=True, text=True, timeout=5)# Kötü
subprocess.run(f"ping -c 1 {user_input}", shell=True)# Node.js kötü
const { exec } = require("child_process");
exec("ping -c 1 " + ip);
# Daha iyi yönde: execFile / spawn ile argüman dizisi + doğrulama
const { execFile } = require("child_process");
execFile("ping", ["-c", "1", ip]);[center][/center]
6) İleri Seviye
Argument injection:
tarffmpegsendmail-o----# Kavramsal
subprocess.run(["some-tool", "--", user_path])Blind command injection: Çıktı sayfaya basılmaz;
sleepŞablon motorları / CI: Build script'lerine kullanıcı kontrollü alan enjekte etmek de aynı sınıftır.
# Rapor
Bulgu: OS Command Injection (CWE-78)
Konum: /vulnerabilities/exec/ ip parametresi
Kanıt: Labda ; uname -a çıktısı
Öneri: subprocess argüman listesi + IP allowlist + düşük yetki7) Sonuç
Command injection, kabuğa güvenilmeyen veri vermektir. Kara liste değil, güvenli API + allowlist + least privilege ile kapatılır. DVWA'da Low'da görün, Impossible'da doğru kodu okuyun.
Ek: Tespit, Loglama ve Kod İnceleme İpuçları
Mavi takım / kod inceleme perspektifinden şunlara bakın:
# Grep ile tehlike işaretleri (kendi repo'nuz)
rg -n "os\\.system|shell=True|exec\\(|popen\\(|child_process\\.exec" .# Uygulama logunda (kavramsal)
{"event":"extcmd","bin":"ping","args":["-c","1","127.0.0.1"],"user":"www-data"}
# Argümanlar ayrık loglanmalı; kabuk satırı tek string olarak loglanıyorsa tasarım zayıf olabilirWAF ve filtre yanılgısı:
;$IFSKonteyner sertleştirme:
- Distroless veya minimal imaj; /Kod:
bashyoksa etki azalır (yine de binary çalıştırma mümkün olabilir)Kod:curl - Read-only kök dosya sistemi + tmpfs
- Capability drop, seccomp, non-root user
# Dockerfile parçası
USER nobody
# HEALTHCHECK ve minimal paket seti[center][/center]
Kod incelemesinde "bu girdi allowlist'ten mi geçiyor?" sorusu, "filtre yeterli mi?" sorusundan daha değerlidir.
Kaynakça
Yasal Uyarı
Komut enjeksiyonu testleri yalnızca kendi sistemleriniz veya yazılı izinli lab/pentest içindir. İzinsiz RCE denemesi TCK 243-245 kapsamında ağır suç olabilir. Sorumluluk uygulayana aittir.
Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).