从受限的代码执行到任意代码执行

  • A+
所属分类:安全文章

看到信安之路发了一篇关于某 CMS 的审计,之前对这个 CMS 也算是有一点了解吧,看到里面的一处 RCE 提起了我一点兴趣,于是有了下文。

受限的代码执行

如下,一处刺眼的 eval 代码。

从受限的代码执行到任意代码执行

这个利用点在信安之路上一篇文章已经有分析到了,所以不做过多流程上的分析,只关注如何 Bypass,完成 RCE。问题的关键是要绕过 danger_key 的处理,具体的代码如下


//过滤危险字符,保留正常字符
function danger_key($s,$type='') {
  $s=empty($type) ? htmlspecialchars($s) : $s;
        $danger=array('php','preg','server','chr','decode','html','md5','post','get','file','cookie','session','sql','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep');
  $s = str_ireplace($danger,"*",$s);
  $key=array('php','preg','decode','post','get','cookie','session','$','exec','ascii','eval','replace');
   foreach ($key as $val){
     if(strpos($s,$val) !==false){
    error('很抱歉,执行出错,发现危险字符【'.$val.'】');
    }
   }
  return $s;
}

比较棘手的是 $type 值写死传入为 1,所以单双引号都会被实体编码,这导致就算我们传入的函数也难以传入一个字符串作为函数参数。再看下面被过滤的函数,虽然过滤了很多常用的函数,但只要是参数类型为 callback 的函数都可以作为绕过的方法。所以最先需要解决的是如何突破单双引号的限制,完成字符串的传入

寻找输入可控的地方

问题一:输入点有哪些?

一开始总是受于思维的限制,老是认为输入点就是 GPC,可真的是这样吗?并非如此,HTTP 传输的数据不只是 GPC,而是整个协议的格式,如下图,除了 GPC 之外,HTTP 头部都是我们可控的。而且这里并不会被过滤函数处理,是理想的控制输入的地方。

从受限的代码执行到任意代码执行

问题二:那控制了输入,那如何把控制的输入获取到并传入我们想要执行的函数里呢?

我已经可以通过上面受限的代码执行来执行一些函数,于是我的思路是寻找一个函数可以返回头部信息,而这个函数的要求是不需要参数。可往往不需要参数的函数返回大多是个数组,不过这没关系,在 PHP5.4 版本就新增支持对函数返回数组的成员访问解析的特性,例如 foo()[0] 。翻了翻手册发现了一个函数满足我的要求。



getallheaders
(PHP 4, PHP 5, PHP 7)
getallheaders  获取全部 HTTP 请求头信息
说明
getallheaders ( void ) : array

但我忽略的一个点,get 被替换成 * 所以会导致执行不成功。

从受限的代码执行到任意代码执行

这个好解决手册的下一句就是

此函数是 apache_request_headers() 的别名。请阅读 apache_request_headers() 文档获得更多信息。

所以直接使用 apache_request_headers() 的效果是一样的。

问题三:apache_request_headers 返回的数组下标为字符串,而 POST 不可以输入字符串怎么办?

学习一门语言或多或少都会学习数组的切割操作,所以 array_slice 可以切割获得任意一个元素的值。

到此,我们可以控制输入,同时绕过了过滤,并且把输入作为参数带入到想要执行的函数里。我选了 array_filter 函数来执行任意代码。

最后的效果就是如下:

从受限的代码执行到任意代码执行

最后

还是蛮有意思的一个绕过,加深理解了一切输入皆有害!花了一两个小时绕这个,还是蛮有趣的。文章没写太细,更多细节就留给各位调试啦。

从受限的代码执行到任意代码执行

本文始发于微信公众号(信安之路):从受限的代码执行到任意代码执行

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: