XPath注入學習
XPath注入學習
這篇記錄是看完先知社群:XPATH注入學習寫的,所以可能很多內容是重複的。寫這篇記錄僅僅為了讓自己更好的掌握XPath注入。
0x01 XPath入門
在學習XPath注入之前,先了解一下什麼是XPath
學習入口:W3school學習XPath
按照我個人的理解,XPath就是用於查詢xml節點的查詢語句,類似於T-SQL。
0x02 XPath注入原理
XPath注入原理類似於SQL注入,當程式沒有對使用者輸入的資料進行過濾就拼接到XPath查詢語句中時,就可能產生XPath注入。但是與SQL注入不同的時,XPath沒有使用者許可權這一說法,所以XPath注入容易導致所有XML資料洩露。
0x03 例項
例項1
// 1.php
<?php
$xml = simplexml_load_file('test.xml');
$query = "user/username[@name='" . $_GET['name'] . "']";
$result = $xml->xpath($query);
foreach($result as $k => $v){
echo $k . ' => ' . $v . '<br />';
}
?>
<!--test.xml--> <?xml version="1.0" encoding="utf-8"?> <root> <user> <username name='user1'>user1_value</username> <username name='user2'>user2_value</username> <username name='user3'>user3_value</username> <username name='user4'>user4_value</username> <username name='user5'>user5_value</username> <username name='user6'>user6_value</username> <username name='user7'>user7_value</username> </user> <flag> <value>flag{57e7f266bb0dc62f2cb0f25976c14e93}</value> </flag> </root>
正常XPath功能
當我們訪問地址http://ctf.cn/1.php?name=user1時,查詢語句是:user/username[@name='user1']
。所以會查詢user下的username節點,且username節點name屬性的值為user1的節點內容。返回結果如下:
判斷注入點
當我們在引數值中輸入單引號'時,頁面出現XPath查詢報錯,說明可能存在XPath注入。
此時的XPath語句:user/username[@name='user1'']
進一步判斷注入點(獲取更多資料)
當我們輸入' or '1'='1時,可以看到將user/username下的所有節點值都查詢出來了。
此時的XPath語句:user/username[@name='user1' or '1'='1']
獲取整個xml檔案資料
但是我們顯然是不滿足於獲取這點資料的,XPath中一個類似於SQL注入中' or '1'='1
的payload:']|//*|//*['
,我們嘗試一下:
此時的XPath語句:user/username[@name='user1']|//*|//*['']
payload解析
payload:']|//*|//*['
- 這裡首先通過
']
閉合前面的語句,然後使用|運算子(使用|拼接多個語句時會返回多個語句查詢結果的節點並集)拼接多個語句。 - 拼接的
//*
查詢文件中所有元素 - 最後的
//*['
是為了閉合後面的']
例項2
在一些情況下,雖然後臺程式碼執行了我們注入的XPath語句,當時沒有回顯資料,這時候就需要一些手段來進行盲注了。
// login.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="POST">
username:
<input type="text" name="username">
</p>
password:
<input type="password" name="password">
</p>
<input type="submit" value="登入" name="submit">
</p>
</form>
</body>
</html>
<?php
if (file_exists('account.xml')) {
$xml = simplexml_load_file('account.xml');
if ($_POST['submit']) {
$username = $_POST['username'];
$password = $_POST['password'];
$x_query = "/accounts/user[username='{$username}' and password='{$password}']";
print_r('XPath query:' . $x_query);
$result = $xml->xpath($x_query);
if (count($result) == 0) {
echo '
登入失敗';
} else {
echo "
登入成功";
$login_user = $result[0]->username;
echo "you login as $login_user";
}
}
}
?>
<!--account.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<accounts>
<user id="1">
<username>Twe1ve</username>
<email>[email protected]</email>
<accounttype>administrator</accounttype>
<password>P@ssword123</password>
</user>
<user id="2">
<username>test</username>
<email>[email protected]</email>
<accounttype>normal</accounttype>
<password>123456</password>
</user>
</accounts>
下面的內容很多是照抄的,但是加了自己對payload細節的理解