Florent Daignière's blog

Posted 21 Jun, 2014

Exploiting XPath injection vulnerabilities with XCat

XPath injection bugs are relatively common in web applications, yet it's a vulnerability class ignored by the vast majority of pentesters.

I think that there is two main reasons for that:

This blog post will attempt to address the former, by detailing several trivial patches that have been submitted to XCat, an automated XPath injection exploitation tool. As you will soon realise, like most pentesting tools, XCat needs some love... In its current form, it's next to useless.

Patch number one: should you ever need to exploit a bug where the HTTP-response-code is your oracle, you will need the following:

commit 705b58c61efe116694dcfb0c62db9fe0daf1bbda
Author: Florent Daigniere <nextgens@freenetproject.org>
Date:   Sat Jan 18 21:28:20 2014 +0000

    The logic is not quite right; it can be HTTP codes too

diff --git a/src/xcat.py b/src/xcat.py
index 21bf950..f57b4e7 100755
--- a/src/xcat.py
+++ b/src/xcat.py
@@ -445,8 +445,8 @@ if __name__ == "__main__":

     sys.stderr.write("XCat version %s\n"%__VERSION__)

-    if not any([args.false_keyword, args.true_keyword, args.error_keyword]):
-        sys.stderr.write("Error: You must supply a false, true or error keywor
+    if not any([args.false_keyword, args.true_keyword, args.error_keyword, arg
+        sys.stderr.write("Error: You must supply a false, true or error keywor

     if not args.post_argument:

Patch number two: if the bug's oracle is error based, this will also be useful...

commit 290e93a1a9a57529e7bc07027a87beca9135f43d
Author: Florent Daigniere <nextgens@freenetproject.org>
Date:   Sat Jan 18 21:28:54 2014 +0000

    Fix the HTTP-error code case

diff --git a/src/lib/payloads.py b/src/lib/payloads.py
index 0093c7d..11855c4 100644
--- a/src/lib/payloads.py
+++ b/src/lib/payloads.py
@@ -91,7 +91,7 @@ class PayloadMaker(object):

         self._headers = Headers({"User-Agent":[config.user_agent], "Referer":[

-        if config.error_keyword:
+        if config.error_keyword or config.error_code:
             self.BASE = string.Template("' and (if ($payload) then error() els
             self.BASE = string.Template("' and $payload and '1'='1".replace("'

I hope these patches will save a few hours to the next poor soul that runs into the same issue as I did.

See you soon for a follow-up post, where I will try to convince the audience that XPath injection bugs can mean serious business.

Category: Blog
Tags: security blog