前陣子做了南京郵電大學網路攻防平台上面的題目,寫了一個writeup之後,還有必要總結一下。由於做的題目都是web類型的,所有的題目都是使用PHP來寫的,所以很多題目並沒有考察到傳統的如SQL注入,XSS的類型的漏洞,很多都是PHP本身語法的問題。鑑於目前PHP是世界上最好的語言,PHP本身的問題也可以算是web安全的一個面向。在PHP中的特性就是弱型,以及內建函數對於傳入參數的鬆散處理。這篇文章主要是記錄我在做攻防平台上面遇到的PHP的函數中存在的問題,以及PHP的弱型態所帶來的問題。
PHP弱型別簡介
在PHP中,可以進行一下的操作。
$param = 1; $param = array(); $param = "stringg";
弱類型的語言對變量的數據類型沒有限制,你可以在任何地時候將變量賦值給任意的其他類型的變量,同時變量也可以轉換成任意地其他類型的數據。
型轉換問題
型轉換是無法避免的問題。例如需要將GET或是POST的參數轉換為int類型,或是兩個變數不符的時候,PHP會自動地進行變數轉換。但是PHP是一種弱型的語言,導致在進行型別轉換的時候會存在很多意想不到的問題。
比較操作符
型轉換
在$a==$b的比較中
$a=null;$b=flase ; //true$a='';$b=null;//true
這樣的例子
在$a==$b的比較中0=='0'//true0 == 'abcdefg'//true0 === 'abcdefg'//false1 == '1abcdef'//true
"0e132456789"=="0e7124511451155" //true"0e123456abc"=="0e1dddada"//false"0e1abc"=="0" //true
Hash比較
除了以上的這種方式之外在進行hash比較的時候也會存在問題。如下:"0x1e240"=="123456"//true "0x1e240"==123456//true "0x1e240"=="1e240"//false
十六進位轉換
還存在一種十六進位餘字串進行比較運算時的問題。例子如下:$var = 5;
型轉換
常見的轉換主要是int轉換為string,string轉換為int。
int轉string:
var_dump(intval('2'))//2 var_dump(intval('3abcd'))//3 var_dump(intval('abcd'))//0
方式2:$item = strval($var);
string轉int:intval()函數。 對於這個函數,可以先看2個例子。if(intval($a)>1000) { mysql_query("select * from news where id=".$a) }
$array1[] = array( "foo" => "bar", "bar" => "foo", ); $array2 = array("foo", "bar", "hello", "world"); var_dump(md5($array1)==var_dump($array2));//true
內置函數的參數的鬆散性
內建函數的鬆散性說的是,呼叫函數時給函數傳遞函數無法接受的參數型別。解釋起來有點拗口,還是直接透過實際的例子來說明問題,以下會重點介紹幾個這個函數。 md5()
$array=[1,2,3]; var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。
$i ="2abc"; switch ($i) { case 0: case 1: case 2: echo "i is less than 3 but not negative"; break; case 3: echo "i is 3"; }
$array=[0,1,2,'3']; var_dump(in_array('abc', $array)); //true var_dump(in_array('1bc', $array)); //true
在PHP手册中,in_array()函数的解释是bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ),如果strict参数没有提供,那么in_array就会使用松散比较来判断$needle是否在$haystack中。当strince的值为true时,in_array()会比较needls的类型和haystack中的类型是否相同。
$array=[0,1,2,'3']; var_dump(in_array('abc', $array)); //true var_dump(in_array('1bc', $array)); //true
可以看到上面的情况返回的都是true,因为’abc’会转换为0,’1bc’转换为1。
array_search()与in_array()也是一样的问题。