cristi075@home:~$

Mildly secure

HTB HackTheBoo 2022 - (Web) Juggling Facts writeup

‘Juggling Facts’ was a web challenge (day 4 out of 5) from HackTheBox’s HackTheBoo CTF.
Getting the flag involved exploiting a type juggling issue in a PHP app.

What we got

Like all the other web challenges from this CTF, we got the code for the app and a docker container running it.

Since I didn’t want to install the php dependencies or build the container, I started with their container this time.

Analyzing the app

The webapp displays facts about pumpkins 🎃.
These are grouped into three categories: “spooky”, “not so spooky” and “secret”. The webapp

If we try to access the “secret” facts, we’re told that we need admin permissions. The 'Secret' option

Let’s take a look at the request made for that (using BurpSuite) Request made for 'secret' facts

The error message is a different one; this ones states that we can only access the ‘secret’ facts through localhost.
Let’s take a look at the code in order to understand what’s happening there.

Analyzing the code

First, based on entrypoint.sh, we can confirm that the flag is stored in the facts table with the ‘secret’ type.

In indexController.php we see the method used for retrieving the facts.
The check that prevents us from retrieving those is checking for the ‘type’ variable to be equal to ‘secrets’ and for the server to address to be 127.0.0.1.

I don’t know how these requests could make to appear to be from localhost and I don’t see a way of interfering with that variable.
However, we notice that a strict comparison (===) is used for the ‘security’ check and then a switch statement is used to select the type of facts that are being retrieved.

Vulnerable code

The comparison made by default in a switch statement is equal to a loose comparison (==) in PHP.
The difference between the two comparison types makes this code vulnerable to type juggling attacks. Also, the name of the challenge is a good hint in that direction too.

You can read more about type juggling vulnerabilities here.
Another very good resource that I found is this presentation from OWASP Day 2015: link.

The presentation linked above also has this table that helps with visualizing what you might expect when comparing two different types (using the loose comparison). Type juggling table

So, we have to find an input value that is not the string ‘secrets’ (so it won’t match on the strict comparison) but that returns true when compared to the ‘secrets’ string using a loose comparison.

Type juggling

To make this a bit easier, I installed php8 on a VM and created a short script that would compare my input with the ‘secrets’ string using both loose and strict comparisons.

test.php (click to expand)

<?php

$input = json_decode($argv[1], true);

echo('JSON:' . PHP_EOL);
var_dump($input);
echo(PHP_EOL . 'Type field:' . PHP_EOL);
var_dump($input['type']);

echo(PHP_EOL . 'Loose' . PHP_EOL);
var_dump($input['type'] == 'secrets');

echo(PHP_EOL . 'Strict' . PHP_EOL);
var_dump($input['type'] === 'secrets');

?>

The most common payloads for type juggling involve comparing strings to integers.
However, those won’t work anymore in php8. You can find this being mentioned in the PayloadsAllTheThings repository, here.

Based on the table shown above (this can also be found in the github repository linked above) another choice might be to use the ‘true’ boolean value.
It should return true when compared with any string. In our case, the comparison with ‘secrets’ is the first one made inside the switch block so we can make use of this.

But first, let’s test it using the script that I mentioned before.

Type juggling

It seems to work well: we get false when using a strict comparison and true when using a loose comparison.

Getting the flag

Now let’s try using it on the actual app.

Getting the flag

Success!

Can this vulnerability be fixed?

After seeing this I was thinking about if this vulnerability could’ve been prevented.
According to this thread on StackOverflow, it can’t.
Switch statements will always use loose comparisons.

Other web challenges from this CTF

This CTF released a challenge in each of its 5 categories each day.
I have posted writeups for all the web challenges. Here are some links to them: