从ThinkPHP谈基于框架开发程序的安全性(从SQL注入到代码执行)

漏洞概要

缺陷编号:WooYun-2014-088251

漏洞标题:从ThinkPHP谈基于框架开发程序的安全性(从SQL注入到代码执行)

相关厂商:ThinkPHP

漏洞作者:xfkxfk

提交时间:2014-12-23 01:29

公开时间:2015-04-02 10:23

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

Tags标签:

漏洞详情

披露状态:

2014-12-23: 细节已通知厂商并且等待厂商处理中
2014-12-23: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放(绿盟科技、唐朝安全巡航、无声信息)
2015-02-16: 细节向核心白帽子及相关领域专家公开
2015-02-26: 细节向普通白帽子公开
2015-03-08: 细节向实习白帽子公开
2015-04-02: 细节向公众公开

简要描述:

从ThinkPHP谈基于框架开发程序的安全性,以ThinkPHP,ThinkSNS,大米CMS等最新版漏洞证明为例

详细说明:

从ThinkPHP谈基于框架开发程序的安全性,以ThinkPHP,ThinkSNS,大米CMS等为例之前在看ThinkPHP开发手册的时候看到这个:

这就是说当程序员使用GPC接受的值以字符串形式进入where中,此值是原生的字符换,不会进行任何检查和处理,即便是错误类型和恶意sql语句等,这样就导致sql注入的隐患存在了。我们举个例子,拿最新版的ThinkPHP为例:注意这里$role = $_POST['role'],直接将POST的值付给了变量role然后变量以role拼接字符串的形式进入了where中:

不懂安全的程序员任务,将role变量带入where中,ThinkPHP应该会自己处理,应该是安全的但事实上,这样就导致了SQL注入,不管是否加了单引号

数据库执行记录:

恶意的sql语句内容成功进入了sql语句,没有进行任何检测处理。可能大家觉的这样写很可笑,但是在实际应用和程序中,这样写的程序员很多就算使用官方推荐的I方法进行数据的获取,同样存在问题。

即使这样使用官方推荐的I方法还是存在同意的问题。

所以只要程序员在基于ThinkPHP开发应用程序时,过度相信框架本身的安全性而未自己做好安全检测处理时,会带来很多安全问题,而且都是大面积的。比如最新版的ThinkSNS两处,当然不止这两处了:第一处,文件:/apps/weiba/Lib/Action/IndexAction.class.php

这里在删除帖子时,$post_id = $_POST['post_id']然后$post_id拼接字符串形式进入where中,跟我们前面讲的问题一样,导致sql注入产生发送如下请求即可进行盲注:

第二处,文件:/apps/w3g/Lib/Action/IndexAction.class.php

注意这里的:$map="weibo_id>{$_POST['nowMaxID']} AND isdel=0";其中$_POST['nowMaxID']直接拼接到字符串中,最后map进入了where进行查询,导致注入发送如下请求即可进行盲注:

再比如最新版的大米CMS:大米CMS之前的几处漏洞:http://**.**.**.**/bugs/wooyun-2010-081510http://**.**.**.**/bugs/wooyun-2010-081519http://**.**.**.**/bugs/wooyun-2010-081842还有最新提交的两处:http://**.**.**.**/bugs/wooyun-2014-087947/trace/7880e3736bbf2c91c7c7e9dc17ec68a8http://**.**.**.**/bugs/wooyun-2014-087989/trace/876654a7a2c8fc9bae225b34ab148a6e都是因为通过GPC获取值,然后通过字符串直接进入了where中,导致的注入具体就不在列举了。再来谈谈ThinkPHP的模板解析导致的代码执行问题:在ThinkPHP中模板变量的赋值通过assign函数进行,模板变量的解析通过display函数。文件ThinkPHP\Library\Think\view.class.php:

如果传入的是数组,那么直接将数组合并,然后载赋值到到tVar

进入编译函数fetch:

当使用PHP原生模板时,会调用extract把tVar导入到变量表里,然后会检测$content变量是否存在,如果存在就使用eval执行,否则include $templateFile。可以看到这里使用了extract函数,extract作用是从数组中把变量导入到当前的符号表中,而第二个参数表示如果有冲突,就覆盖已有变量。因此此处如果$this->tVar可控的话,那么就可以覆盖掉$templateFile变量造成任意文件包含,或者覆盖$content造成任意代码执行。所以当程序员把GPC接受的值传给assign,导致$this->tVar可控,这是就导致文件包含或者代码执行漏洞了,直接getshell。举个例子:

这里将$_GET赋值给$var,然后进入assign,最后导致漏洞产生:

这里最好的例子就是ThinkSNS了:http://**.**.**.**/bugs/wooyun-2014-056641http://**.**.**.**/bugs/wooyun-2014-081755当然,按照这里的方法,可找到ThinkSNS不下10处这里的问题直接getshell也是很轻松的。=======================================================================以上漏洞都是从最新版的ThinkPHP中分析得到虽然说ThinkPHP现在做的很不错,用户量很大所以很多新手,很多安全意识差的程序员就过于相信框架本身的安全性在开发时就免去了自身的处理再加上开发人员的低安全意识和大意,产生漏洞的几率就更大了既然作为框架这样的基础型的东西,根基一样要打好,否则像上面这样的问题都是很严重的定时炸弹,总会有爆发的时候,杀伤力还是很大的。

漏洞证明:

sql注入

代码执行

修复方案:

I函数也不是万能的,要么说明为什么不处理,自行该如何处理,要么全部处理好。

漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2015-04-0210:23

厂商回复:

框架有推荐的安全防范机制 至于用不用完全看开发者了,就算是原生PHP开发,这个漏洞也有可能,从框架的层面来说,开发者可以用框架写出任何代码,包括好的代码和不安全的代码,框架只是工具,不是原罪!忽略该漏洞的用意,也正好告诉开发者引起重视,尽量按照官方推荐的方式进行安全开发。官方从来没说过字符串方式的条件可以防止SQL注入,而且手册中也特意给出了安全章节:http:///manual_3_#safety

漏洞Rank:10 (WooYun评价)

最新状态:

暂无

评价

  1. 2010-01-01 00:00 秋风 白帽子 | Rank:372 漏洞数:32)

    NB!

  2. 2010-01-01 00:00 子非海绵宝宝 白帽子 | Rank:1220 漏洞数:113)

    关注

  3. 2010-01-01 00:00 phith0n 白帽子 | Rank:644 漏洞数:62)

    打出这波浪潮。

  4. 2010-01-01 00:00 猪猪侠 白帽子 | Rank:2932 漏洞数:249)

    流行大礼包

  5. 2010-01-01 00:00 泳少 白帽子 | Rank:158 漏洞数:20)

    别这样好吗?来个分析的

  6. 2010-01-01 00:00 xfkxfk 白帽子 | Rank:1829 漏洞数:172)

    好吧

  7. 2010-01-01 00:00 寂寞的瘦子 白帽子 | Rank:160 漏洞数:15)

    强行先甩锅

  8. 2010-01-01 00:00 用来怀念 白帽子 | Rank:0 漏洞数:1)

    厂商回复好霸气~~!

  9. 2010-01-01 00:00 GrayTrack 白帽子 | Rank:59 漏洞数:7)

    牛逼

  10. 2010-01-01 00:00 Coner 白帽子 | Rank:3 漏洞数:1)

    赞一下厂商的恢复态度,

  11. 2010-01-01 00:00 马丁 白帽子 | Rank:0 漏洞数:1)

    霸气

  12. 2010-01-01 00:00 进击的zjx 白帽子 | Rank:259 漏洞数:20)

  13. 2010-01-01 00:00 secer 白帽子 | Rank:3 漏洞数:1)

    公开时间: 1970-01-01 08:33

  14. 2010-01-01 00:00 wooshal 白帽子 | Rank:0 漏洞数:0)

    除非有安全团队,一般人员很难避免

  • N/A