前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java代码审计汇总系列(二)——XXE注入

Java代码审计汇总系列(二)——XXE注入

作者头像
Jayway
发布2019-11-12 21:35:10
2.3K0
发布2019-11-12 21:35:10
举报
文章被收录于专栏:卓文见识卓文见识

一、概述

OWASP Top 10中的另一个注入漏洞是XML外部实体注入(XXE),它是在解析XML输入时产生的一种漏洞,漏洞原理和黑盒挖掘技巧见之前的文章:XML外部实体(XXE)注入原理解析及实战案例全汇总,这里从代码层角度挖掘XXE漏洞。

XML解析相关的漏洞除了XXE,还有XML注入和XEE(实体膨胀)等。

二、挖掘过程

还是以Webgoat的一个案例讲解,审计的思路依旧是:针对特定功能进行抓包,定位到相关代码,追踪利用链,判断是否存在问题,漏洞验证/利用。

通过抓包得到请求路径,POST 请求的正文是一个标准格式的XML:

Spring Boot微服务框架处理各种请求时,是通过里面的注解,所以通过注解xxe/simple找到对应类SimpleXXE.java:

代码语言:javascript
复制
@Autowiredprivate Comments comments;@PostMapping(path = "xxe/simple", consumes = ALL_VALUE,produces = APPLICATION_JSON_VALUE)@ResponseBody   public AttackResult createNewComment(@RequestBody String commentStr)throws Exception {       String error = "";       try {           Comment comment = comments.parseXml(commentStr);           comments.addComment(comment, false);           if (checkSolution(comment)) {                return trackProgress(success().build());           }       } catch (Exception e) {           error = ExceptionUtils.getFullStackTrace(e);

做代码审计工作,大部分时间都是找到关键代码,一行一行代码去嚼,每一句是什么意思、做了什么事情,读得多了,速度自然就快。

比如上面这段代码,首先@表示注解:

代码语言:javascript
复制
@PostMapping注解是url的Map映射,consumes和 produces则是post请求的两个参数,@ResponseBody表示将方法的返回结果直接写入 HTTP返回包的正文body中。@RequestBody String commentStr,表示将请求中的数据写入到commentStr的String对象中。

然后看代码层面:

第一句,必须看懂private Comments comments;是对象的典型定义办法,comments对象是抽象类Comments的一个实例,原则上引用了哪个类我们就要跟踪过去,后续定义了createNewComment方法,顾名思义是创建新的评论,看方法里实现了什么操作,异常try中实例化了另一个Comment类,调用的是comments的parseXml方法,最后addComment进行新增评论。

跟进两个类,Comment.java定义了几个变量,不用关注:

代码语言:javascript
复制
public class Comment {   private String user;   private String dateTime;   private String text;}

跟进Comments.java,里面有三个方法,其中调用的parseXml方法描述了如何处理commentStr:

代码语言:javascript
复制
protected Comment parseXml(String xml)throws Exception {       JAXBContext jc = JAXBContext.newInstance(Comment.class);        XMLInputFactory xif = XMLInputFactory.newFactory();       xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true);       xif.setProperty(XMLInputFactory.IS_VALIDATING, false);        xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);       XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));        Unmarshaller unmarshaller = jc.createUnmarshaller();       return (Comment) unmarshaller.unmarshal(xsr);}

审计XXE漏洞时对这段代码要保持敏感,这是xml解析的的典型接口Unmarshaller,也是发现XXE的搜索特征之一。

这里parseXml方法做的主要操作是:获取一个JAXBContext的实例名为jc——>js创建一个Unmarshaller对象——>执行unmarshaller方法将xml格式字符串xsr反序列化为java对象得到comment。反序列过程中解析了XML,也是这个过程导致了XXE注入。

最后在xxe/simple数据包处构造参数为payload,经过调用链解析xml数据进行特定攻击。

三、挖掘技巧

挖掘XXE漏洞的关键是找到代码是否涉及xml解析——>xml输入是否是外部可控——>是否禁用外部实体(DTD),若三个条件满足则存在漏洞。

功能层面XML解析一般在导入配置、数据传输接口等需对xml数据进行处理的场景,代码层面需要关注xml解析的几种实现接口,定位到关键代码后看是否有禁用外部实体的相关代码,从而判断是否存在XXE。

解析XML常见的方法有四种,即:DOM、DOM4J、JDOM 和SAX,部分XML解析接口如下:

代码语言:javascript
复制
javax.xml.parsers.DocumentBuilderjavax.xml.stream.XMLStreamReaderorg.jdom.input.SAXBuilderorg.jdom2.input.SAXBuilderjavax.xml.parsers.SAXParserorg.dom4j.io.SAXReaderorg.xml.sax.XMLReaderjavax.xml.transform.sax.SAXSourcejavax.xml.transform.TransformerFactoryjavax.xml.transform.sax.SAXTransformerFactoryjavax.xml.validation.SchemaFactoryjavax.xml.bind.Unmarshallerjavax.xml.xpath.XPathExpressionorg.apache.commons.digester3.Digester

在定位XXE漏洞的时候可以使用的搜索关键词有:

代码语言:javascript
复制
Documentbuilder|DocumentBuilderFactory|SAXReader|SAXParser|SAXParserFactory|SAXBuilder|TransformerFactory|reqXml|getInputStream|XMLReaderFactory|.newInstance|SchemaFactory|SAXTransformerFactory|javax.xml.bind|XMLReader|XmlUtils.get|Validator

三、漏洞防御

使用XML库的Java应用程序易受到XXE的攻击,因为大多数JavaXML解析器的默认设置是启用DTD。所以使用XML解析器时需要设置其属性,禁止使用外部实体,以上例中SAXReader为例,安全的使用方式如下:

代码语言:javascript
复制
sax.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);sax.setFeature("http://xml.org/sax/features/external-general-entities",false);sax.setFeature("http://xml.org/sax/features/external-parameter-entities",false);

其它XML解析器的安全使用可参考:

https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html

需要指出的是,若只禁用DTD未禁用Doctype,无法进行SSRF等攻击但仍可进行DOS攻击(Billion laughs attack):

代码语言:javascript
复制
<?xml version="1.0"?><!DOCTYPE lolz [ <!ENTITY lol"lol"> <!ELEMENT lolz(#PCDATA)> <!ENTITY lol1"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]><lolz>&lol9;</lolz>

五、实战案例

对一个CMS的webservice接口类YesbWebServiceImpl进行审计:

主要操作是定义了一个auth方法,形参是xmlSource,最终返回的是yesbOuterService类的auth方法,跟进:

继续跟进busiInvoke方法:

进行xmlToBean操作,跟进:

调用了getDocumentFromString方法,跟进:

发现这个方法内使用SAXReader对xml数据进行解析,且这段代码未禁用DTD,故存在XXE漏洞,其他场景的XXE漏洞挖掘过程也类似。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卓文见识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、概述
  • 二、挖掘过程
  • 三、漏洞防御
  • 五、实战案例
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档