# SEH

## Idea

The "JMP ESP" method that we have discussed in the "Classic" section only works for systems **older than Windows XP SP1**. Starting from SP1 onwards, the **exception handler** would zero out all the register when a crash occurs. In such case, we need develop **SEH-based exploits**.

## SEH-based Exploits

An SEH-based exploit is made of two tricks:

1. **nSEH** is always at **ESP + 8**. We place a **"pop pop ret"** gadget in EIP so that the code in nSEH will be executed.
2. We place a **"short jump"** in nSEH so that the shellcode on the stack will be executed. Typically, this short jump would be `\xeb\x06\x90\x90`, which stands for "jumping 6 bytes forward". Here we jump 6 bytes because there are two bytes for padding (`\x90\x90`) and 4 bytes for current SEH.

## Summary

1. Interact with the application and write a script to verify the existence of stack overflow. To verify that the **SEH** structure is overwritten, go to `View -> SEH chain`.
2. Fuzz the application using pattern and find the **offset**. Note that the offset we need is `offset - 4`: the last 4 bytes are for nSEH.
3. Find a **pop pop ret** gadget from a library without protection.
4. Figure out how many bytes to **jump** (typically 6 bytes forward).
5. Find all **badchars**.
6. Generate **shellcode** using msfvenom.
7. Get shell or pop calc.

## Payload

```python
payload = ""
payload += "A" * (offset - 4)
payload += "\xeb\x06\x90\x90" # nSEH => jump 6 bytes forward
payload += <pop_pop_ret> # SEH => pop pop ret
payload += nop_sled
payload += shellcode
payload += another_nop_sled
payload += padding
```

## SafeSEH

If **SafeSEH** is enabled on the target system, the system is going to check if the current SEH is pointing to a valid address in the current library. If not, the system would terminate the program. We have to bypass the SafeSEH protection so that our SEH-based exploit will still work.

If SafeSEH is enabled for **some libraries**, we just pick a pop pop ret gadget from a non-SafeSEH library. However, if SafeSEH is enabled for **all libraries**, we won't be able to find a good pop pop ret gadget. Instead, we use `pvefindaddr.py` to find a pop pop ret alternative:

```
!pvefindaddr jseh
```

Typically, you would find some gadget like `call dword ptr[ebp+30h]`. A big problem here is that the address we find would contain a **null byte** at the beginning. On Windows XP SP3, this address is `0x00280b0b` from `unicode.nls`. This null byte is an extra barrier for us because we won't be able to provide any input after it. That is, we have to store the shellcode **before** this address and do a **backward long jump** to execute the shellcode.

## Reference

1. [Structured Exception Handler (SEH) -- FuzzySecurity](https://www.fuzzysecurity.com/tutorials/expDev/3.html)
2. [Bypassing Stack Cookies, SafeSeh, SEHOP, HW DEP and ASLR](https://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-part-6-bypassing-stack-cookies-safeseh-hw-dep-and-aslr/)
