# X marks the spot

## Problem

> Another login you have to bypass. Maybe you can find an injection that works? <http://mercury.picoctf.net:16521/>

## Solution

1. The challenge says this is an `XPATH` injection. We can try the standard payload `blah' or 1=1 or 'a'='a` from [OWASP](https://owasp.org/www-community/attacks/XPATH_Injection) and see if we can sign in. This results in a message saying `You're on the right path.`, so it looks like our query succeeded. However, we did not get redirected to an application so this looks like a "blind `XPATH` injection."
2. [HackTricks](https://book.hacktricks.xyz/pentesting-web/xpath-injection) is a good resource here. Their [`XPATH` Injection article](https://book.hacktricks.xyz/pentesting-web/xpath-injection) explains the basics of `XPATH` and even has an example script to execute a blind `XPATH` injection attack. This script was the basis of my [solve script](https://github.com/HHousen/PicoCTF-2021/blob/master/Web%20Exploitation/X%20marks%20the%20spot/script.py).
3. Essentially, when the `You're on the right path.` message is shown, we know our query returned a true value and otherwise our query was false. We can modify the query using `or` to join the login query with a special query and then tell `XPATH` to ignore the rest of the login query.
4. By using `' or string-length(//user[position()=3]/pass)=4 or ''='` we can check if the length of the `pass` field of the 3rd `user` element in document is 4. I guessed that the password field would be called `pass` because that is the name of the form element in the website's HTML. The `position()=3` was manually checked by scanning each position starting at 1. If the name of the field is unknown, a query such as the following could be used instead: `' or string-length(//user[position()=1]/child::node()[position()=1])=4 or ''='`. We can bruteforce the `4` in this case and determine the length of the 3rd user's password.
5. Once we know the length of the password/flag, we can use `' or substring(//user[position()=3]/pass,<position>,1)="<character>" or ''='`where `<position>` is the position in the string and `<character>` is the character we are checking. We loop though all the possible characters at position `0` until the `You're on the right path.` message is shown. When that loop is complete, we will know the first letter of the password/flag. We can continue doing this for each character of the password/flag until we reach the length we found in the previous step.
6. The [solve script](https://github.com/HHousen/PicoCTF-2021/blob/master/Web%20Exploitation/X%20marks%20the%20spot/script.py) executes the above scripts to determine the flag character by character. Depending on your internet connection (how fast you can send requests to the server), the script may take a few minutes (≈4 minutes maximum) to run.

### Flag

`picoCTF{h0p3fully_u_t0ok_th3_r1ght_xp4th_28cb0023}`
