To weaken the Golden Fang army, we must cut off their funding of the Genesis coins. Ulysses managed to perform a phishing attack against one of the financial operators of the mercenary and retrieved the login credentials “icarus:FlyHighToTheSky” for the Genesis wallet. However, the account is protected with 2FA. Can you hack into this renowned intergalactic wallet and move their funds to your account?

Sometimes, you know there’s a vulnerability in a piece of software that’s been patched, and you want to find the vulnerability so you can use it on an unpatched system. This CTF gave me a good opportunity to practice that. There was an unitended solution to the original genesis challenge. The operators patched the problem, but in a brand new challenge, leaving a vulnerable version up. I decided to see if I could reverse engineer the change and find the problem.

The Challenge

When we first browse to the page, we’re presented with a login/sign in prompt:

4e0fcb82ed27c553021a061ccbe5f403.png

After logging in with our new credentials, we’re required to keep track of a totp code:

8b8b3ad97eb00b9fef6a4a3a6b39c816.png

After saving it, and logging in with our new credentials and one time passcode, we’re presented with the main page.

590495d0eaa9a4dd6600f920b36ec320.png

We’re able to change our two factor code on the settings page, log out, view incoming and outgoing transactions, but the most important part, at least for us, is being able to send transactions:

f9d6dda1e61837b84b530b56be62b3f4.png

Based on this information, my guess at the solution was to send something malicious to the ‘icarus’ user. In order to do that, we need two things: the icarus' address, and some kind of payload.

The solution

This is the unintended solution, which I got during the competition. A different post will show the intended solution to the patched challenge: Genesis Wallet Redemption.

a60d8d65393890ab46b6af35bb6fb5e2.png

After grabbing the zip files of the two challenges and putting them into a folder, as shown above, we can extract both of them:

$ unzip web_genesis_wallet
Archive:  web_genesis_wallet.zip
   creating: web_genesis_wallet
   ...
   
$ unzip web_genesis_wallet_redemption.zip 
Archive:  web_genesis_wallet_redemption.zip
   creating: web_genesis_wallet_redemption/
   ...

Now, we can use the command diff -r to compare these two websites, and see what was changed in the patched version:

1b92d3bdb70f78bb0287240c93f48080.png

That’s a little suspicious. It looks like in the patched version, they added a check to prevent someone transfering negative amounts. So theoretically, if we knew icarus' address, we could send them negative money, and drain their account that way.

Probably the best place to look for the user’s address is in the registration flow. First, we look at routes/index.js, at the /api/register endpoint:

router.post('/api/register', async (req, res) => {
	const { username, password } = req.body;

	if (username && password) {
		return db.getUser(username)
			.then(user => {
				if (user) return res.status(401).send(response('Account already exists!'));
				return db.registerUser(username, password)
					.then(()  => res.send(response('Account registered successfully')))
			})
			.catch(() => res.status(500).send(response('Internal server error!')));
	}
	return res.status(401).send();
});

We see that it calls the db.registerUser function, and so we follow the trail there:

async registerUser(user, pass) {
	return new Promise(async (resolve, reject) => {
		try {
			let address = crypto.createHash('md5').update(user).digest("hex");
			let stmt = await this.db.prepare('INSERT INTO users (username, password, address) VALUES ( ?, ?, ?)');
			resolve(await stmt.run(user, pass, address));
		} catch(e) {
			reject(e);
		}
	});
}

From this, we see that the user’s address is nothing more than the md5 hash of their username! We can generate icarus' address using this command:

$ echo -n "icarus" | md5sum
1ea8b3ac0640e44c27b3cb8a258a87f8  -

The -n is necessary to prevent echo from adding a \n character to the end and spoiling the hash.

With that wallet address and the vulnerability, we’re ready to execute the attack. We go to the Genesis Wallet dashboard, and use the send button to send the address 1ea8b3ac0640e44c27b3cb8a258a87f8 -1337GTC.

7b001f14242b5cceb8b91c0d09e4e941.png

The last step is to go to the transactions page and verify the transaction:

3b5d3a6e089cac22aee8dd0b86a6c439.png

After the transaction is processed, we just have to go back to the dashboard, and enjoy our newfound wealth, as well as a shiny new flag:

b1f321f6f176754a4b1276485c3a4a05.png

If this was interesting at all, helped you with one of your challenges, or if you have any questions or corrections, please drop me a line!