xpath簡介:php
提到xpath就要先說下xml,xml意爲可擴展標記語言,簡單來講就是一種存儲數據的標準格式,能夠把他視爲一個小型的數據庫,他能夠解決數據在網上傳輸的標準問題。是一種比數據庫更具通用性,便捷型的存儲形式,由於不一樣的業務會涉及到不一樣產品類型的數據庫,在更換產品或是接口需求變更的時候每每又要重寫接口代碼、更改表結構,同時數據庫的維護和防火牆的限制也是麻煩,xml的存儲形式正好能夠彌補這些缺陷,但一樣的,xml的輕量級也決定了他沒法像數據庫那樣高效的存儲、索引、修改、觸發還有訪問控制。html
那麼xpath呢,他是一種對xml文檔進行查詢操做的語言,經過使用路徑表達式來選取 XML 文檔中的節點或節點集,並返回計算後的值。node
xpath語法:sql
nodename:選取此節點的全部子節點數據庫
/ :從根節點選取服務器
// :從匹配選擇的當前節點選擇文檔中的節點,而不考慮他們的位置cookie
. :選取當前節點函數
.. :選取當前節點的父節點ui
@:選取屬性加密
* :匹配任何元素節點
//*:選取文檔中的全部元素
@*:匹配任何屬性節點
node():匹配任何類型節點
/bookstore/book[1]:選取屬於bookestore子元素的第一個book元素
//title[@lang]:選取全部擁有名爲lang的屬性的title元素
/bookstore/book | //price:選取屬於bookstore元素的全部book元素,以及文檔中全部的price元素
注入原理:
xpath注入的原理其實和sql注入很像,都是經過語法構造特殊輸入,這些輸入經過傳參的方式拼接到原查詢語句後被執行,以獲取非預期顯示信息。注入的對象不過是換了一個存儲形式,同時,由於xpath不存在訪問控制,因此相較sql注入要容易不少,這裏用一道賽題來舉例:
經過訪問/download.php?file=backup.zip下載網頁源碼,以下:
1 <?php 2 $re = array('and','or','count','select','from','union','group','by','limit','insert','where','order','alter','delete','having','max','min','avg','sum','sqrt','rand','concat','sleep'); 3 setcookie('injection','c3FsaSBpcyBub3QgdGhlIG9ubHkgd2F5IGZvciBpbmplY3Rpb24=',time()+100000); 4 5 if(file_exists('t3stt3st.xml')) { 6 $xml = simplexml_load_file('t3stt3st.xml'); 7 $user=$_GET['user']; 8 $user=str_replace($re, ' ', $user); 9 // $user=str_replace("'", "&apos", $user); 10 $query="user/username[@name='".$user."']"; 11 $ans = $xml->xpath($query); 12 foreach($ans as $x => $x_value) 13 { 14 echo $x.": " . $x_value; 15 echo "<br />"; 16 } 17 }
首先看到他過濾了sql注入的一些關鍵字,setcookie中有一段base64加密的密文,解碼後獲得的是:「sqli is not the only way for injection」,根據提示sql不是惟一的注入方式,再結合下面對xml的一系列操做,能夠肯定這道題是用xpath注入,因而根據$query="user/username[@name='".$user."']";這一句可構造以下payload:
這句payload的意思是閉合了「.$user.」先後的單引號同時執行三個操做,其中第二個操做//*便是關鍵點,列出文檔中的全部元素,最後拿到flag
站在開發的角度來看,當存在以下user.xml文檔時:
1 <user> 2 <firstname>Ben</firstname> 3 <lastname>Elmore</lastname> 4 <loginID>abc</loginID> 5 <password>test123</password> 6 </user> 7 <user> 8 <firstname>Shlomy</firstname> 9 <lastname>Gantz</lastname> 10 <loginID>xyz</loginID> 11 <password>123test</password> 12 </user>
xpath典型的查詢語句即是:
//users/user[loginID/text()='xyz'and password/text()='123test']
但此處存在一個xpath注入能夠繞過用戶驗證:只需將傳入的參數loginID和password的值改成' or ''='
//users/user[loginID/text()='' or ''='' and password/text()='' or ''='']
此時,經過傳入的值閉合了參數兩邊的單引號,又使其查詢恆爲真,故達到了繞過的目的
延展開來,xpath的注入還有不少花樣,像是經過updataxml()函數實現xpth報錯注入,還有xpth的盲注
防護方法:
一、和sql注入的防護同樣,在服務器處理提交的數據前先檢查數據是否包含特殊字符,對其進行過濾
二、對系統出現的錯誤信息用統一的報錯頁面代替(如updataxml()這類)
三、在數據的傳輸過程當中,對敏感信息進行加密
四、構建xpath查詢表達式,以變量的形式參數化xpath查詢:
//users/user[@loginID=$loginID and @password= $password]
參考文獻:
http://www.runoob.com/xpath/xpath-syntax.html
http://blog.csdn.net/qq1175421841/article/details/50194673
http://blog.csdn.net/quiet_girl/article/details/50588130