Tags: php 

Rating: 5.0

This challenge can be locally setup using [this repo](https://github.com/amccormack/ctf_challenges/tree/master/tsg_ctf/web/secure_bank)

The prompt of the challenge is:

> I came up with more secure technique to store user list. Even if a cracker could dump it, now it should be of little value!!!

The website links to [source code](https://github.com/amccormack/ctf_challenges/blob/master/tsg_ctf/web/secure_bank/source.rb)
and logging in shows that it is a banking application.

Looking at the source file shows that in order to get the flag the balance
of the account should be greater than or equal to 10 billion.

I decided to take a look at the transfer function to see if I could spot any
vulnerabilities.

The api takes two arguments, a destination user account and an amount.

The amount to transfer must be greater than 0 and the usernames can not be the same

The usernames of the sender and the destination are both hashed, and the hashes
are used to locate the records of the users in the database.

Seeing the `dst != src` validation made me realize that if the usernames where the same
the transfer would give extra coins. This is because the new amount for the destination is
calculated using values obtained before the coins where subtracted from the sender.

The user's data is obtained from the database by the SHA1 hash of the user ID. So
if we can get two different usernames but the same hash, we can add coins to our account
and overwrite the effects of subtracting.

SHA1 is [vulnerable](https://shattered.io/) to collisions, and researchers have
figured out how to generate the same SHA1 hash from two different byte sequences.

This website provides a [SHA1 collider](https://alf.nu/SHA1). You can
specify two files and it will return two PDFs with different data but each with
the same SHA1 hash. I used the website to generate two PDFs, and then used
python to to chop off the ends and test the hash until the PDFs were 320 bytes long.

I then wrote python to register the first PDF as user 1, and transfered all available coins to user 2.
This doubled user 1's coins and I continued this process until the coin balance was over 10 billion and
retrieved the flag.

```
$ python solve.py http://34.85.75.40:19292
200
400
800
1600
3200
6400
...
3355443200
6710886400
13421772800
{'flag': 'TSGCTF{H4SH_FUNCTION_1S_NOT_INJ3C71V3... :(}\n'}
```

A more detailed writeup and source code is available [on my blog](https://amccormack.net/2019-05-05-secure-bank-tsg-ctf.html)

Original writeup (https://amccormack.net/2019-05-05-secure-bank-tsg-ctf.html).