HackTheBox-Challenges Juggling facts Writeup

kazma 成大資安社 創辦人/社長

Exploitation

這題是 web,我們逛一下網站後會看到沒有明顯的輸入點,但是有三個按鈕會呈現不同的頁面,我們來看一下 code。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php spl_autoload_register(function ($name) {
if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
}
include_once "${name}.php";
});

$database = new Database('localhost', 'root', 'M@k3l@R!d3s$', 'web_juggling_facts');
$database->connect();

$router = new Router();
$router->new('GET', '/', 'IndexController@index');

$router->new('POST','/api/getfacts', 'IndexController@getfacts');

die($router->match());

上面可以看到他設定了兩種路由,一種是 GET / 會呼叫 IndexController 類中的 index 方法,另一個是註冊一個 POST 方法的路由,URL 路徑為 /api/getfacts,當發送 POST 請求至 /api/getfacts 路徑時,會呼叫 IndexController 類中的 getfacts 方法。那我們接著就看 challenge/controllers/IndexController.php

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php

class IndexController extends Controller
{
public function __construct()
{
parent::__construct();
}

public function index($router)
{
$router->view('index');
}

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':
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!'
]);
}
}
}

上面提到在訪問 /api/getfacts 的時候會帶一個 type 的參數,根據不同的 case 會有不同的 response,其中有一個 type 是 secrets 他前面先檢查是否是本地存取,否的話就會 return 然後輸出警告。
那這邊就要提到 php 的一個問題,就是當我們使用兩個等號做比較的時候會被稱作 loose comparison,因為當兩個類型不同時 php 會嘗試幫我們轉型再做比較。
例如,0 == ‘0’ 和 0 == false 都會返回 true,因為在鬆散比較下 PHP 會將字符串和布爾值轉換成數字進行比較。
而當我們使用 ===:這會是一個 strict comparison,不會進行類型轉換。
嚴格比較要求值和類型都必須相同,否則結果為 false。
例如,0 === ‘0’ 和 0 === false 都會返回 false,因為類型不同(數字與字符串或布爾值),PHP 不會嘗試轉換它們。
那這邊放上一張圖片給大家參考:
ref
圖片來源:https://blog.stackademic.com/the-curious-case-of-php-loose-comparisons-a-tale-of-a-b-and-c-70e6dff98c39
那我們就可以嘗試找到一個值是會在三個等號時不等於 ‘secrets’ 但是兩個等號會相等的,這種漏洞也叫做 Type Juggling Vulnerability 跟題目呼應,中文可能叫型別強制漏洞。
那我們就透過 true 來跟 “secrets” 做比較搭配 burp 來協助我們送封包,效果如下:
weak

Pwned !!!

pwn

References

  • Title: HackTheBox-Challenges Juggling facts Writeup
  • Author: kazma
  • Created at : 2024-11-02 01:50:29
  • Updated at : 2024-11-02 02:28:05
  • Link: https://kazma.tw/2024/11/02/HackTheBox-Challenges-Juggling-facts-Writeup/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
HackTheBox-Challenges Juggling facts Writeup