前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从受限的代码执行到任意代码执行

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

作者头像
信安之路
发布2020-04-22 11:20:21
9320
发布2020-04-22 11:20:21
举报
文章被收录于专栏:信安之路信安之路信安之路

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

受限的代码执行

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

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

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

寻找输入可控的地方

问题一:输入点有哪些?

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

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

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

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

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

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

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

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

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

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

最后的效果就是如下:

最后

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 受限的代码执行
  • 寻找输入可控的地方
    • 问题一:输入点有哪些?
      • 问题二:那控制了输入,那如何把控制的输入获取到并传入我们想要执行的函数里呢?
        • 问题三:apache_request_headers 返回的数组下标为字符串,而 POST 不可以输入字符串怎么办?
        • 最后
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档