Java代码审计-XMI注入(XXE)

这篇具有很好参考价值的文章主要介绍了Java代码审计-XMI注入(XXE)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 XML 注入攻击

1.1 XML漏洞攻击原理

1.1.1 什么是XML

XML 指可扩展标记语言(EXtensible Markup Language)。

XML 是一种很像HTML的标记语言。

XML 的设计宗旨是传输数据,而不是显示数据。

XML 标签没有被预定义。您需要自行定义标签。

XML 被设计为具有自我描述性。

XML 是 W3C 的推荐标准。

1.1.2 XML注入漏洞原理

使用不可信数据来构造XML会导致XML注入漏洞也成称为XXE漏洞。一个用户,如果他被允许输入结构化的XML片段,且输入的片段未做任何防御措施,则他可以在XML的数据域中注入XML标签来改写目标XML文档的结构与内容。XML解析器会对注入的标签进行识别和解释。

1.2 XML注入基础知识

1.2.1 DTD

首先先来了解一下DTD含义。DTD(文档类型定义,Document Type Definition)的作用是定义 XML
文档的合法构建模块。它使用一系列的合法元素来定义文档结构。DTD可被成行的声明于XML文档中,也可作为一个外部引用

1.2.2 实体ENTITY

XML中的实体类型,一般有下面几种:字符实体、命名实体(或内部实体)、外部普通实体、外部参数实体。除外部参数实体外,其它实体都以字符(&)开始,以字符(;)结束。

  • 字符实体

字符实体类似html中的实体编码,形如:a(十进制)或者a(十六进制)。

  • 命名实体(内部实体)

内部实体又称为命名实体。命名实体可以说成是变量声明,命名实体只能声明在DTD或者XML文件开始部分(<!DOCTYPE>语句中)。

命名实体(或内部实体)语法:

<!ENTITY 实体名称 "实体的值">

如:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE root [

<!ENTITY x "xxe1">

<!ENTITY y "xxe2">

]>

<root><x>&x;</x><y>&y;</y></root>

定义实体名称x和y 值为xxe1和xxe2!

&x; 引用实体x;&y引用实体y

  • 外部普通实体

外部实体用于加载外部文件的内容。(显式XXE攻击主要利用外部普通实体)

外部普通实体语法:

<!ENTITY 实体名称 SYSTEM "URI/URL">

如:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPe root [

<!ENTITY outfile SYSTEM "outfile.xml">

]>

<root><outfile>&outfile;</outfile></root>
  • 外部参数实体

参数实体用于DTD和文档的内部子集中。与一般实体不同,是以字符(%)开始,以字符(;)结束。只有在DTD文件中才能在参数实体声明的时候引用其他实体。(Blind
XXE攻击常利用参数实体进行数据回显)

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE root [

<!ENTITY % p1"hello">

<!ENTITY % p2 " ">

<!ENTITY % p3 "jj">

<!ENTITY dtd SYSTEM "combine.dtd">

%dtd;

]>

<root><foo>&content</foo></root>

combine.dtd中的内容为:

<!ENTITY content "%param1;%param2;%param3;">

上面combine.dtd中定义了一个基本实体,引用了3个参数实体:%p1;,%p2;,%p3;。

解析后…中的内容为hello jj。

1.3 XML注入审计函数

一般在传输数据接口和导入配置等场景可能会用到XML解析,若涉及到XML文件处理的场景要查看是否禁用DTD外部实体,来判断是否存在XXE。常用XML审计函数如下,可搜索如下关键字:

javax.xml.parsers.DocumentBuilderFactory;

javax.xml.parsers.SAXParser

javax.xml.transform.TransformerFactory

javax.xml.validation.Validator

javax.xml.validation.SchemaFactory

javax.xml.transform.sax.SAXTransformerFactory

javax.xml.transform.sax.SAXSource

org.xml.sax.XMLReader

org.xml.sax.helpers.XMLReaderFactory

org.dom4j.io.SAXReader

org.jdom.input.SAXBuilder

org.jdom2.input.SAXBuilder

javax.xml.bind.Unmarshaller

javax.xml.xpath.XpathExpression

javax.xml.stream.XMLStreamReader

org.apache.commons.digester3.Digester


1.4 XML注入漏洞危害

读取任意文件

执行系统命令

探查内网端口

攻击内网网站

1.5 XML注入漏洞代码示例

1.5.1 DocumentBuilder ( ** DOM Read XML** )

DocumentBuilder类是JDK自带的类,在该类解析产生的XXE漏洞是有回显的。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String result="";

try {

//DOM Read XML

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

Document doc = db.parse(request.getInputStream());




String username = getValueByTagName(doc,"username");

String password = getValueByTagName(doc,"password");

if(username.equals(USERNAME) && password.equals(PASSWORD)){

result = String.format("<result><code>%d</code><msg>%s</msg></result>",1,username);

}else{

result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,username);

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());

} catch (SAXException 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);

}

1.5.2 saxReader ( DOM4J Read XML )

saxReader是第三方的库,该类是无回显的

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String result="";

try {

//DOM4J Read XML

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(request.getInputStream());

String username = getValueByTagName2(document,"username");

String password = getValueByTagName2(document,"password");

if(username.equals(USERNAME) && password.equals(PASSWORD)){

result = String.format("<result><code>%d</code><msg>%s</msg></result>",1,username);

}else{

result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,username);

}

} catch (DocumentException  e) {

System.out.println(e.getMessage());

}

response.setContentType("text/xml;charset=UTF-8");

response.getWriter().append(result);

}

1.5.3 SAXBuilder ( ** JDOM2 Read XML** )

无回显

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String result="";

try {

//JDOM2 Read XML

SAXBuilder builder = new SAXBuilder();

Document document = builder.build(request.getInputStream());

String username = getValueByTagName3(document,"username");

String password = getValueByTagName3(document,"password");

if(username.equals(USERNAME) && password.equals(PASSWORD)){

result = String.format("<result><code>%d</code><msg>%s</msg></result>",1,username);

}else{

result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,username);

}

} catch (JDOMException  e) {

System.out.println(e.getMessage());

}

response.setContentType("text/xml;charset=UTF-8");

response.getWriter().append(result);

}

1.5.4 SAXParserFactory

该类也是JDK内置的类,但他不可回显内容,可借助dnslog平台

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//https://blog.csdn.net/u011024652/article/details/51516220

String result="";

try {

//SAX Read XML

SAXParserFactory factory  = SAXParserFactory.newInstance();

SAXParser saxparser = factory.newSAXParser();

SAXHandler handler = new SAXHandler();

saxparser.parse(request.getInputStream(), handler);

//为简单,没有提取子元素中的数据,只要调用parse()解析xml就已经触发xxe漏洞了

//没有回显  blind xxe

result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,1);




} catch (ParserConfigurationException e) {

e.printStackTrace();

result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());

} catch (SAXException 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);

}

1.5.5 XMLReaderFactory

public String xmlReaderVuln(HttpServletRequest request) {

try {

String body = WebUtils.getRequestBody(request);

logger.info(body);

XMLReader xmlReader = XMLReaderFactory.createXMLReader();

xmlReader.parse(new InputSource(new StringReader(body)));  // parse xml

return "xmlReader xxe vuln code";

} catch (Exception e) {

logger.error(e.toString());

return EXCEPT;

}

1.5.6 Digester

public String DigesterVuln(HttpServletRequest request) {

try {

String body = WebUtils.getRequestBody(request);

logger.info(body);


Digester digester = new Digester();

digester.parse(new StringReader(body));  // parse xml

} catch (Exception e) {

logger.error(e.toString());

return EXCEPT;

}

return "Digester xxe vuln code";

1.5.7 XMLReader

public String XMLReaderVuln(HttpServletRequest request) {

try {

String body = WebUtils.getRequestBody(request);

logger.info(body);




SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser saxParser = spf.newSAXParser();

XMLReader xmlReader = saxParser.getXMLReader();

xmlReader.parse(new InputSource(new StringReader(body)));

} catch (Exception e) {

logger.error(e.toString());

return EXCEPT;

}

return "XMLReader xxe vuln code";

}

1.6 XML注入实战案例

这里借用JOYChou老师的Java Sec Code项目做一个演示。

存在漏洞代码示例:

public String xxeDocumentBuilderReturn(HttpServletRequest request) {

try {

String xml_con = WebUtils.getRequestBody(request);

System.out.println(xml_con);

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

StringReader sr = new StringReader(xml_con);

InputSource is = new InputSource(sr);

Document document = db.parse(is);  // parse xml

// 遍历xml节点name和value

StringBuffer buf = new StringBuffer();

NodeList rootNodeList = document.getChildNodes();

for (int i = 0; i < rootNodeList.getLength(); i++) {

Node rootNode = rootNodeList.item(i);

NodeList child = rootNode.getChildNodes();

for (int j = 0; j < child.getLength(); j++) {

Node node = child.item(j);

buf.append(node.getNodeName() + ": " + node.getTextContent() + "\n");

}

}

sr.close();

System.out.println(buf.toString());

return buf.toString();

} catch (Exception e) {

System.out.println(e);

return "except";

}

}

上述代码示例中的漏洞爆发行为 Document document =
db.parse(is),参数“is”直接从request中获取为用户可控参数,且未做任何过滤措施,直接进行解析,造成了XXE漏洞

要想清楚Java解析XML机制,就要明白以下几行代码意思

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

StringReader sr = new StringReader(xml_con);

InputSource is = new InputSource(sr);

Document document = db.parse(is);

DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法
,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。如图所示

java xml 注入,java,安全,开发语言

使用Burp进行抓包验证,将Content-Type: application/x-www-form-urlencoded修改成Content-Type:
application/xml,输入payload进行文件读取。

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE joychou [

<!ENTITY xxe SYSTEM "file:///d://1.txt">

]>

<root>&xxe;</root>

可成功读取xml文件,漏洞利用成功。

java xml 注入,java,安全,开发语言

浏览器显示。

java xml 注入,java,安全,开发语言

1.7 XML注入漏洞防御

使用XML解析器时需要设置其属性,禁用DTDs或者禁止使用外部实体。

以上例中DOM - DocumentBuilderFactory为例,防御代码如下:

dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //禁用DTDs (doctypes),几乎可以防御所有xml实体攻击

//如果不能禁用DTDs,可以使用下两项,必须两项同时存在

dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);      //防止外部普通实体POC 攻击

dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);   //防止外部参数实体POC攻击

防御代码如下:

java xml 注入,java,安全,开发语言

Bhnr3v-1675647810068)]

1.7 XML注入漏洞防御

使用XML解析器时需要设置其属性,禁用DTDs或者禁止使用外部实体。

以上例中DOM - DocumentBuilderFactory为例,防御代码如下:

dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //禁用DTDs (doctypes),几乎可以防御所有xml实体攻击

//如果不能禁用DTDs,可以使用下两项,必须两项同时存在

dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);      //防止外部普通实体POC 攻击

dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);   //防止外部参数实体POC攻击

防御代码如下:

[外链图片转存中…(img-RgQn0mZQ-1675647810068)]

最后

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
java xml 注入,java,安全,开发语言
同时每个成长路线对应的板块都有配套的视频提供:
java xml 注入,java,安全,开发语言
java xml 注入,java,安全,开发语言
当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。
java xml 注入,java,安全,开发语言
因篇幅有限,仅展示部分资料,有需要的小伙伴,可以【扫下方二维码】免费领取:
文章来源地址https://www.toymoban.com/news/detail-757722.html

到了这里,关于Java代码审计-XMI注入(XXE)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • XXE-XML实体注入漏洞

    目录 1.xml基础 1.1什么是xml 1.2xml文档结构 1.3  什么是DTD 1.4 什么是实体 1.5 什么是外部实体 2.xxe漏洞 2.1xxe漏洞基本介绍 2.2xxe漏洞的危害 经典漏洞案例分析 3.xxe漏洞挖掘和利用 3.1. 识别潜在的XML入口 3.2. 检查XML处理逻辑 3.3. 构造试探Payload 常见的一般payload  xxe盲注 xxe报错注入

    2024年03月14日
    浏览(79)
  • XML External Entity-XXE-XML实体注入

    概念 本课程介绍如何执行 XML 外部实体攻击以及如何滥用和防范该攻击。 目标 用户应该具备 XML 的基本知识 用户将了解 XML 解析器的工作原理 用户将学习如何执行 XXE 攻击以及如何防范它。 XML 实体允许定义标签,在解析 XML 文档时这些标签将被内容替换。一般来说,实体分

    2024年02月06日
    浏览(40)
  • Web攻防--Java_SQL注入--XXE注入-- SSTI模板注入--SPEL表达式注入

    编译器在编译sql语句时,会依次进行词法分析、语法分析、语义分析等操作, 预编译技术会让数据库跳过编译阶段,也就无法就进行词法分析,不会被拆开,注入语句也就不会被识别为SQL的,从而防止恶意注入语句改变原有SQL语句本身逻辑。 在使用JDBC进行数据

    2024年02月09日
    浏览(60)
  • 【Java代码审计】失效认证及不安全随机数篇

    根据密码学原理,随机数生成器分为以下三类: 1、统计学伪随机数生成器(PRNG):伪随机数生成器从一个初始化的种子值开始计算得到序列,从种子开始,然后从种子中计算出后续值,当种子确定后生成的随机数也是确定的,但其输出结果很容易预测,因此容易复制数值流

    2024年01月16日
    浏览(39)
  • Spring-1-深入理解Spring XML中的依赖注入(DI):简化Java应用程序开发

    前两篇文章我们介绍了什么是Spring,以及Spring的一些核心概念,并且快速快发一个Spring项目,以及详细讲解IOC,今天详细介绍一些DI(依赖注入) 能够配置setter方式注入属性值 能够配置构造方式注入属性值 能够理解什么是自动装配 思考:向一个类中传递数据的方式有几种?(给类

    2024年02月13日
    浏览(50)
  • 代码审计-java项目-组件漏洞审计

    代码审计必备知识点: 1、代码审计开始前准备: 环境搭建使用,工具插件安装使用,掌握各种漏洞原理及利用,代码开发类知识点。 2、代码审计前信息收集: 审计目标的程序名,版本,当前环境(系统,中间件,脚本语言等信息),各种插件等。 3、代码审计挖掘漏洞根本: 可控

    2024年02月12日
    浏览(39)
  • Java代码审计

    本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 代码审计是一种安全测试方法,它通过对软件应用程序代码的静态分析和动态测试来确定应用程序中存在的安全漏洞。其主要目的是检测应用程序中可能被攻击者利用的安全漏洞,如输入验证问题、访问控制问

    2024年02月12日
    浏览(38)
  • Java代码审计之XSS攻击

    存在XSS漏洞的java代码: 第一段 反射型XSS payload 第二段 存储型XSS 访问如下地址存储脚本到Cookie中 当后端再获取Cookie返回时 访问 成功弹窗 修复 目前最有效的办法,对特殊字符进行实体转义。 XSS安全代码: XSS排查 利用xsstriker等工具进行扫描 手动输入特殊字符看被没被实体

    2024年02月15日
    浏览(46)
  • Java代码审计——Commons Collections5 BadAttributeValueExpException

    反序列化总纲 cc链无非就是不同的调用拼接在一起形成的,比如cc5就是在cc1的基础上进行调用调整的。 在LazyMap的基础上,发现了一个新的调用方式,就是通过 TiedMapEntry+BadAttributeValueExpException的方式进行调用的。 在之前,我们知道LazyMap需要调用get方法才可以触发,那么我们

    2023年04月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包