題目:備份是個好習慣
思路分析
開啟題目,看到一個字串。
聯絡到題目,就猜到肯定是原始碼洩露,用工具掃一下,發現了index.php.bak
,驗證了我的猜想,下載下來看看。
<?php
/**
* Created by PhpStorm.
* User: Norse
* Date: 2017/8/6
* Time: 20:22
*/
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag."取得flag";
}
?>
原始碼審計
關注到parse_str
函式。
parse_str — 將字串解析成多個變數
如果
string
是 URL 傳遞入的查詢字串(query string),則將它解析為變數並設定到當前作用域(如果提供了result
則會設定到該陣列裡 )。str_replace — 子字串替換
str_replace(
mixed$search
,
mixed$replace
,
mixed$subject
,
int&$count
= ?
): [mixed]該函式返回一個字串或者陣列。該字串或陣列是將
subject
中全部的search
都被replace
替換之後的結果。
程式碼邏輯分析
程式邏輯比較簡單:
-
提取query string,並去掉
?
,儲存為$str
-
使用
str_replace
將$str
中的key
字串替換成空格 -
使用
parse_str
將$str
中的變數解析出來 -
判斷變數
$key1
和$key2
的md5,需要同時滿足:
-
md5($key1) == md5($key2)
-
$key1 !== $key2
所以做題思路也很簡單,第一步,繞過str_replace
。第二步,構造字串繞過md5值比較。
payload構造
第一步payload:?kekeyy1=a&kekeyy2=a
第二步payload:?kkeyey1=QNKCDZO&kkeyey2=240610708
字串不相等時如何構造md5相等?
PHP中==是判斷值是否相等,若兩個變數的型別不相等,則會轉化為相同型別後再進行比較。PHP在處理雜湊字串的時候,它把每一個以0e開頭的雜湊值都解析為0。
在md5加密後以0E開頭
- QNKCDZO
- 240610708
- s878926199a
- s155964671a
在sha1加密後以0E開頭
- aaroZmOk
- aaK1STfY