1. 程式人生 > 遊戲 >《失落的方舟》IGN評8分:遊戲出色 借鑑了暗黑許多元素

《失落的方舟》IGN評8分:遊戲出色 借鑑了暗黑許多元素

直接分析原始碼,首先去除了對GET、POST傳入引數的轉義。另外get_magic_quotes_gpc函式在PHP7.4.0起已廢棄。

if (get_magic_quotes_gpc()) {
	function stripslashes_deep($value)
	{
		$value = is_array($value) ?
		array_map('stripslashes_deep', $value) :
		stripslashes($value);
		return $value;
	}

	$_POST = array_map('stripslashes_deep', $_POST);
	$_GET = array_map('stripslashes_deep', $_GET);
	$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
	$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

下面對反斜線、左右括號、等號和or進行了檢測,若存在則會觸發waf,可以使用like替代等號,||替代or,由於不能使用括號,理論上來講報錯注入無法執行,因為前面學過的那些報錯函式都需要括號。

if(preg_match("/\(|\)|\=|or/", $name)){
	die("do not hack me!");
}

又對輸入的密碼進行了md5加密儲存在$t_pw中,隨後將使用者輸入的使用者名稱以單引號包圍拼接到SQL語句中,該條語句也出現在原始碼起始的提示中,先用base32再base64解密可得。關鍵在於下面這段,通過mysqli_fetch_row()函式從查詢結果中獲取一行,並以陣列返回。而後檢查結果陣列第二個元素(下標1)是否為admin:若否,則返回“wrong user”,若是則比對結果陣列第三個元素的值,是否與使用者輸入的password的md5值相等,若相等則返回flag。(有個瑕疵,這應該用$t_pw來比對,前面已經計算過password的md5值了並存在$t_pw中)。

$result = mysqli_query($con, $sql);

$arr = mysqli_fetch_row($result);
// print_r($arr);
if($arr[1] == "admin"){
	if(md5($password) == $arr[2]){
		echo $flag;
	}
	else{
		die("wrong pass!");
	}
else{
	die("wrong user!");
}

由於沒有對union、select、以及註釋符的檢測或過濾,於是可以在使用者名稱處使用聯合查詢,例如:1' union select 1,2,3,那麼得到的結果陣列中三個元素將依次為1,2,3;於是構造payload1' union select 1,'admin','<密碼的md5值>' %23

即可獲得flag。

寫的大都是個人學習筆記,如有錯誤歡迎指正,如有疑問,歡迎討論!