題目:備份是個好習慣
思路分析
打開題目,看到一個字符串。
聯系到題目,就猜到肯定是源代碼泄露,用工具掃一下,發現了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