小迪安全 Web安全 第二十天 WEB攻防-PHP特性&缺陷對比函式&CTF考點&CMS審計例項
一、PHP特性 - 過濾函式
(一)"="、"=="與"==="
1、=,這是賦值符號,不會進行對比
2、==,相對等於,會對比值,但不會對比型別
(1)建立一個名為ctf1.php的檔案,寫入如下程式碼
$flag = '小迪吃西瓜!'; $a = 1; if($a == $_GET['x']){ echo $flag; }
(2)解析該檔案到瀏覽器,在url的ctf1.php後加上?x=1、?x=1.0、?x=+1、?x=1a,發現均能訪問ctf1.php檔案併成功輸出flag
(3)==相對等於判定存在缺陷,不具備唯一性,容易被繞過
3、===,絕對等於,既對比值也對比型別
(1)將上面的程式碼改成如下程式碼
$flag = '小迪吃西瓜!'; $a = 1; if($a === $_GET['x']){ echo $flag; }
(2)再通過瀏覽器訪問該檔案時,發現除了?x=1外,其他引數均不能輸出flag
(3)===絕對等於會判斷值和型別,必須全部符合才能通過判定,具備唯一性,安全效能更高
(二)MD5()函式
1、==相對等於判定
(1)新建一個檔案ctf2.php,寫入如下程式碼
$flag = '小迪吃西瓜!'; if($_GET['name'] != $_GET['password']){ if(MD5($_GET['name']) == MD5($_GET['password'])){ echo $flag; } echo '?'; }
(2)解析該檔案後,再瀏覽器開啟,把ctf2.php後的引數改成?name=QNKCDZO&password=240610708,回車,成功輸出flag,實現繞過
(3)這是因為科學計數法0e開頭的任意數都相等,QNKCDZO與240610708的md5值都是0e開頭,則它們的值會被判定為相等,從而實現判定繞過
2、===絕對等於判定
(1)把ctf2.php的程式碼改成如下形式,解析後通過瀏覽器開啟
$flag = '小迪吃西瓜!'; if($_GET['name'] != $_GET['password']){ if(MD5($_GET['name']) === MD5($_GET['password'])){ echo $flag; } echo '?'; }
(2)再通過引數?name=QNKCDZO&password=240610708訪問ctf2.php發現已經無法輸出flag,此時把引數改成?name[]=1&&password[]=2,發現輸出flag,成功繞過判定
(3)這是因為md5不能判定陣列,引數設定為陣列,其值會被認定為null,兩個引數的值都為null,則其值和型別都判定相等,如果站點的後臺判定是通過驗證使用者輸入資料與資料庫中的md5值是否相等,則可能會出現這種繞過漏洞,存在安全隱患
(三)intval()函式
1、intval()函式用於獲取變數的整數值,intval()函式通過使用指定的進位制 base 轉換(預設是十進位制),返回變數 var 的 integer 數值。 intval() 不能用於 object,否則會產生 E_NOTICE 錯誤並返回 1。
2、語法:int intval ( mixed $var [, int $base = 10 ] )
(1)$var:要轉換成 integer 的數量值。$base:轉化所使用的進位制。
(2)如果 base 是 0,通過檢測 var 的格式來決定使用的進位制:
- 如果字串包括了 "0x" (或 "0X") 的字首,使用 16 進位制 (hex);否則,將使用 10 進位制 (decimal)
- 如果字串以 "0" 開始,使用 8 進位制(octal);否則,將使用 10 進位制 (decimal)。
3、示例
(1)新建一個php檔案,寫入如下程式碼
$flag = '小迪吃西瓜!'; $i = '666'; $ii = $_GET['n']; if(intval($ii == $i)){ echo $flag; }
(2)該判定通過相對等於==實現,繞過方法與上述==判定繞過相同,但引數必須是數值
(四)strpos()函式
1、strpos() f函式查詢字串在另一字串中第一次出現的位置(區分大小寫)。
2、strpos()函式可以通過換行"%0a"進行繞過
(五)in_array()函式
1、in_array() 函式搜尋陣列中是否存在指定的值。
2、關鍵在於第三個引數,如果該引數設定為 TRUE,則 in_array() 函式檢查搜尋的資料與陣列的值的型別是否相同,不設定為true,就相當於相對等於==的檢測,容易被繞過
(六)preg_match()函式
1、preg_match 函式用於執行一個正則表示式匹配。但preg_match()函式不能匹配陣列,引數/i檢測是否區分大小寫,/m是否匹配換行
2、示例
(1)在php檔案中寫入如下程式碼
$flag = 'xiaodi ai chi xi gua!'; if(isset($_GET['num'])){ $num = $_GET['num']; if(preg_match("/[0-9]/",$num)){ die("no no no!"); } if(intval($num)){ echo $flag; } }
(2)解析後通過瀏覽器訪問該檔案,將url後的引數改成?num=1,發現輸出no no no!,將引數改成?num[]=1,輸出flag,成功繞過過濾判定
3、
(七)SQL過濾,str_replace()函式
1、str_replace() 函式替換字串中的一些字元(區分大小寫),但是str_replace()無法迭代,只能過濾一次
2、示例
$sql = $_GET['s']; $sql = str_replace('select','',$sql); echo $sql;
將url引數改成?s=seselectlect,即select雙寫,能夠輸出sql,實現繞過
二、CTF考點及課程中的CMS程式碼審計
1、參考ctfshow的web入門php特性部分題目
2、課程程式碼審計過濾缺陷-檔案讀取涉及CMS:MetInfo6.0.0