理論
parse_str
函數的作用就是解析字符串並註冊成變量,在註冊變量之前不會驗證當前變量是否存在,所以直接覆蓋掉已有變量。
void parse_str ( string $str [, array &$arr ] )
str 輸入的字符串。
arr 如果設置了第二個變量 arr,變量將會以數組元素的形式存入到這個數組,作爲替代。
實踐
測試代碼:
<?php
error_reporting(0);
$flag = 'flag{V4ri4ble_M4y_Be_C0verEd}';
if (empty($_GET['b'])) {
show_source(__FILE__);
die();
}else{
$a = "www.sqlsec.com";
$b = $_GET['b'];
@parse_str($b);
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')) {
echo $flag;
}else{
exit('your answer is wrong~');
}
}
?>
考察點
- parse_str變量覆蓋缺陷
write-up
找到核心代碼:
@parse_str($b);
這裏使用了parse_str函數來傳遞b的變量值
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO'))
這裏用到的是文章上面的知識點md5()函數缺陷
因爲這裏用到了parse_str
函數來傳遞b
,if語句的條件是拿$a[0]
來比較的,因爲這裏的變量a的值已經是固定的了。
整體代碼乍看起來又不可能,但是利用變量覆蓋函數的缺陷這裏可以對a
的變量進行重新賦值,後面的的if語句再利用本文前面提到的md5()
比較缺陷進行繞過:
http://localhost/?b=a[0]=240610708