[漏洞分析]thinkcmf 1.6.0版本从sql注入到任意代码执行

0x00 前言php

该漏洞源于某真实案例,虽然攻击没有用到该漏洞,但在分析攻击以后对该版本的cmf审计以后发现了,也算是有点机遇巧合的味道,我没去找漏洞,漏洞找上了我XDgit

thinkcmf 已经很是久远了,该版本看github上的更新时间已是4年前了,也就是2014年的时候,那时候我没学安全呢。。。github

 

0x01 前台sql注入算法

前台在登陆方法中存在注入,thinkcmf是基于thinkphp3.2写的,直接看sql

文件application\User\Controller\LoginController.class.php 方法 dologinthinkphp

很明显的注入,经过extract咱们能够注册$where数组,然后直接传入where方法,没有通过I方法过滤的引入参数是会引起表达式注入的。shell

好比这样子:数据库

 

这里因为有验证码,没法轻易的编写批量脚本。固然引入打码工具另说。数组

注入以后,咱们想到的必定是登陆后台了。安全

那么先了解一下thinkcmf的管理员密码是怎么加密的。

看到 install\index.php 文件的 sp_password 方法

解释一下,$pre就是表前缀,$pw是密码,意思是

存储在数据库的密码 =  表前缀md5的前12位+密码md5+表前缀md5的后四位

好比值为c535018ee946e10adc3949ba59abbe56e057f20f883e89af 存储在数据库的密码。

那么拆分一下就是

c535018ee946(表前缀md5的前12位)
e10adc3949ba59abbe56e057f20f883e(密码md5)
89af(表前缀md5的后四位)

知道所谓的加密算法以后,咱们就能够轻易获取到管理员密码的md5值,经过碰撞md5值的形式获取到管理员的真实密码。

如今咱们能够登陆上后台了,可登陆后台以后要怎么getshell呢?

仔细分析了一下thinkcmf的后台,彷佛没有能够getshell的地方。

 

0x02 权限验证处的任意代码执行

认真看了看代码,发现后台的一些操做会有权限验证,而跟踪权限验证代码的时候发现了一个eval的代码块。

看到权限验证处application\Common\Lib\iAuth.class.php  check 方法

使用了eval来引入变量,那么这个$command是否可控呢?

经分析其来源于sp_auth_rule表中的condition字段,备注为规则附加条件

而这些数据在安装的时候就早已经写入到数据库中了,除非咱们有办法能够来修改这里的值?

是的,前面的sql注入排上用场了。

thinkphp 自 3系列开始就使用pdo做为链接数据库的驱动,而这里这个注入不涉及到参数绑定等问题,那么咱们就能够利用它来执行多语句,插入数据或者修改数据了。

简单测试一下,好比修改一下后台管理员的user_email字段。

 

 查看数据库,成功修改

 

多语句执行能够为咱们省下不少事,好比密码过于复杂没法猜解出明文时,咱们能够直接修改密码的hash值为咱们想要的。

分析一下权限验证的代码,它是怎么触发的?

随便找了个须要登陆后台的文件好比 application\Portal\Controller\AdminPageController.class.php

该controller继承于AdminbaseController,跟踪下去

而在AdminbaseController初始化的函数中,发现了检测权限的代码,跟进

 

发现若是$uid是1的话就直接返回了,这个$uid其实就是数据库里面的id字段值,也就是说要触发权限验证就必须是一个低权限的用户。

继续走,若是访问的不是url为admin/index/index 就会进行鉴权,跟进sp_auth_check方法

最终来到了咱们的check方法。

具体意思都写在解释里面了,看到eval代码块,咱们只要闭合掉左括号,便可引入咱们的恶意代码。

 那么整个利用过程就是登陆一个低权限的用户,经过sql注入写入代码到咱们能够访问的url的condition字段中。

好比我填加了一个低权限的用户hack,他拥有内容管理的权限

 

 对应他可以访问的url有

那么咱们只要在sp_auth_rule表中对应的url的condition字段插入代码,而后登录该用户访问该url便可触发代码执行。

好比咱们经过sql注入插入一段执行phpinfo的代码

payload:

where[id][0]=exp&where[id][1]=in (1);update sp_auth_rules set `condition`='1);phpinfo();die();//' where id=30#

请求

 

查看一下表sp_auth_rule,成功插入

 

 那么后台登录用户hack以后,访问url

http://127.0.0.1/index.php?g=Portal&m=AdminPage&a=add

便可看到phpinfo执行了

 

 

而在以后的研究中,我发现此处权限验证的代码来自于thinkphp 自身。

看到文件simplewind\Core\Library\Think\Auth.class.php  getAuthList方法的代码

是否是有种似曾相识的感受,是的就是thinkcmf根据tp的改写的。

那么这里就引伸出来一个审计点:

tp3框架中若是使用了auth类来验证权限,且有注入点,那么是能够尝试去审计一下任意代码执行。

 相似的例子,暂时没看到,之后看到了更新上来。

 

0x03 总结

总结一下利用:

经过前台的sql注入,获取到后台权限(获取管理员密码,或者修改管理员hash值),登录进后台,添加低权限用户,再经过sql注入来注入代码。登录低权限用户,访问注入了代码的url,便可触发任意代码执行。

而在实际中,每每是已经有了低权限的用户,咱们只须要观察用户可以访问的URL,直接注入代码便可,免去了添加低权限用户的步骤。

整个利用构造下来仍是比较有趣的,不完美的是仍是须要登陆后台,由于不少网站或许会把后台隐藏掉,可是也有可能会由于不理解tp支持的url模式而致使绕过 ,这里就不细说了,懂的人天然懂。

打完收工~

相关文章
相关标签/搜索