In this video from our Advanced SQL Injection and Data Store Attacks online course you will learn about XPATH injection, and blind XPATH injection, to use in your web application penetration testing. Our instructor Thomas Sermpinis laid everything out in an easy to understand way, so that you can get to using this technique right away. Dive in!
XPath is a language for addressing parts of an XML document, designed to be used by both XSLT and XPointer. In most cases, an XPath expression represents a sequence of steps that is required to navigate from one node of a document to another.
Where web applications store data within XML documents, they may use XPath to access the data in response to user-supplied input. If this input is inserted into the XPath query without any filtering or sanitization, an attacker may be able to manipulate the query to interfere with the application’s logic or retrieve data for which she is not authorized.
To start, let’s consider the following XML data store:
<addressBook> <address> <firstName>William</firstName> <surname>Gates</surname> <password>MSRocks!</password> <email>[email protected]</email> <ccard>5130 8190 3282 3515</ccard> </address> <address> <firstName>Chris</firstName> <surname>Dawes</surname> <password>secret</password> <email>[email protected]</email> <ccard>3981 2491 3242 3121</ccard> </address> <address> <firstName>James</firstName> <surname>Hunter</surname> <password>letmein</password> <email>[email protected]</email> <ccard>8113 5320 8014 3313</ccard> </address> </addressBook>
An XPath query to retrieve all e-mail addresses from this data store, would look like this:
A query to return all the details of the user Dawes would look like this:
In some applications, user-supplied data may be embedded directly into XPath queries, and the results of the query may be returned in the application’s response or used to determine some aspect of the application’s behavior.
Let’s see how we can perform injection on this example. This code comes from a web application that serves credit card info to users logged into it. An XPath query that effectively verifies the user-supplied credentials and retrieves the relevant user’s credit card number could be:
//address[surname/text()=’Dawes’ and password/text()=’secret’]/ccard/text()
Similarly to SQL Injection, an attacker may be able to subvert the application’s query, supplying a password with this value:
‘ or ‘a’=’a
This will result in the following XPath query, which retrieves the credit card details of all users:
//address[surname/text()=’Dawes’ and password/text()=’’ or ‘a’=’a’]/ccard/text()
Keep in mind that unlike SQL queries, keywords in XPath queries are case-sensitive, as are the element names in the XML document itself.
To continue, XPath injection flaws can be exploited to retrieve arbitrary information from within the target XML document. One widely used way of doing this uses the same technique as we saw on SQL injection, of causing the application to respond in different ways, contingent on a condition specified by the attacker.
Submitting the following two statements in the password field of an application, will result in different behavior by the application. Results are returned in the first case but not in the second:
‘ or 1=1 and ‘a’=’a ‘ or 1=2 and ‘a’=’a
This difference in behavior can be leveraged to test the truth of any specified condition and, therefore, extract arbitrary information one byte at a time. As with SQL, the XPath language contains a substring function that can be used to test the value of a string one character at a time. For example, supplying the following statement:
‘ or //address[surname/text()=’Thomas’ and substring(password/text(),1,1)=‘S’] and ‘a’=’a
results in the following query:
//address[surname/text()=’Mel’ and password/text()=’’ or //address[surname/text()=’Thomas’ and substring(password/text(),1,1)= ‘S’] and ‘a’=’a ‘]/ccard/text()
which returns results if the first character of the Thomas user’s password is S. By cycling through each character position and testing each possible value, we can extract the full value of Thomas’ password.