PHP數組繞過intval和preg_match的CTF技巧
原題目
<?php
include("flag.php"); // 引入flag文件,flag變量在這里定義
show_source("index.php"); // 顯示index.php文件的源碼(方便選手查看)// 判斷是否通過GET方式傳入了pangoulin參數
if(isset($_GET['pangoulin'])){$pangoulin = $_GET['pangoulin']; // 獲取pangoulin參數的值// 檢查pangoulin中是否包含數字(0-9),如果有則終止程序并輸出提示if(preg_match("/[0-9]/", $pangoulin)){die("no no no!"); // 包含數字則直接退出}// 判斷pangoulin轉換為整數后是否為真(非0),如果為真則輸出flagif(intval($pangoulin)){echo $flag; // 滿足條件,輸出flag}
}
參數傳遞與數字過濾?:題目要求通過GET傳遞pangoulin參數,但參數值不能包含數字字符(0-9),否則會被preg_match攔截并終止腳本。
intval判斷邏輯 intval($pangoulin)需要返回非零值才能輸出flag。常規字符串(如"abc")經intval轉換結果為0,無法滿足條件。
數組參數在PHP中的獨特特性
使用數組形式傳遞參數(如?pangoulin[]=value
)時,PHP會將$_GET['pangoulin']
自動解析為數組類型。這種特性在表單處理或API參數傳遞中較為常見。
數組參數的強制轉換問題
調用intval()
對數組參數進行強制轉換時,結果會固定返回1
。這是PHP的類型轉換機制決定的,數組轉換為整數時總是返回1
(非空數組)或0
(空數組)。
// 示例:intval對數組的轉換
$val = intval(['a', 'b']); // 結果為1
$emptyVal = intval([]); // 結果為0
preg_match對數組參數的響應
當preg_match()
函數接收到數組參數時,PHP會生成Warning
級別錯誤,但腳本會繼續執行。這與函數預期接收字符串參數的行為不符,但不會像Fatal Error
那樣終止程序。
// 示例:preg_match對數組的響應
preg_match('/\d+/', ['a', 'b']);
// 輸出:Warning: preg_match() expects parameter 2 to be string, array given
安全建議
處理用戶輸入時應顯式檢查變量類型,避免因自動類型轉換導致邏輯漏洞。使用is_array()
或filter_input()
函數驗證參數類型:
// 類型檢查示例
if (is_array($_GET['pangoulin'])) {// 處理數組邏輯
}// 使用過濾器驗證
$value = filter_input(INPUT_GET, 'pangoulin', FILTER_DEFAULT, FILTER_REQUIRE_SCALAR);
if ($value === null) {// 非標量參數處理
}
實戰利用方法 構造請求URL為:
?pangoulin[]=
- 參數變為空數組
- 繞過數字檢測
- intval返回1觸發flag輸出
題目流程圖
技術原理總結
- PHP數組傳參需在參數名后加[]
- 類型轉換特性:intval(array)→1
- preg_match對非字符串參數的容錯處理
// 關鍵代碼邏輯示例
if(isset($_GET['pangoulin'])){$param = $_GET['pangoulin'];if(preg_match("/[0-9]/", $param)) die("Blocked");if(intval($param)) echo $flag;
}
典型應用場景 該技巧適用于需要同時滿足:
- 參數值不能包含特定字符
- 需要參數經類型轉換后為真值 的CTF題目突破場景。