搜尋
首頁php教程PHP源码PHP弱型別問題總結

前陣子做了南京郵電大學網路攻防平台上面的題目,寫了一個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
在進行比較運算時,如果遇到了0ed+這種字串,就會將這種字串解析為科學計數法。所以上面例子中2個數的值都是0因而就相等了。如果不滿足0ed+這種模式就不會相等。這個題目在攻防平台中的md5 collision就有考到。

十六進位轉換

還存在一種十六進位餘字串進行比較運算時的問題。例子如下:

$var = 5;
當其中的一個字串是0x開頭的時候,PHP會將此字串解析成為十進位然後再進行比較,0×1240解析成為十進位就是123456,所以與int型別和string型別的123456比較都是相等。攻防平台中的起名字真難就是考察的這個特性。

型轉換

常見的轉換主要是int轉換為string,string轉換為int。


int轉string:

var_dump(intval('2'))//2
var_dump(intval('3abcd'))//3
var_dump(intval('abcd'))//0

方式1:$item = (string)$var;

方式2:$item = strval($var);

string轉int:intval()函數。

對於這個函數,可以先看2個例子。

if(intval($a)>1000) {
    mysql_query("select * from news where id=".$a)
}

說明intval()轉換的時候,會將從字串的開始進行轉換知道遇到一個非數字的字元。即使出現無法轉換的字串,intval()不會報錯而是回傳0。

intval()的這種特性在攻防平台中的MYSQL這題目中就有考到。

同時,程序員在編程的時候也不應該使用如下的這段代碼:

$array1[] = array(    "foo" => "bar",    "bar" => "foo",
);
$array2 = array("foo", "bar", "hello", "world");
var_dump(md5($array1)==var_dump($array2));//true
這個時候$a的值有可能是1002 union…..

內置函數的參數的鬆散性


內建函數的鬆散性說的是,呼叫函數時給函數傳遞函數無法接受的參數型別。解釋起來有點拗口,還是直接透過實際的例子來說明問題,以下會重點介紹幾個這個函數。

md5()

$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。

PHP手冊中的md5()函數的描述是string md5 ( string $str [, bool $raw_output = false ] ),md5()中的需要是一個string類型的參數。但當你傳遞一個array時,md5()不會報錯,知識會無法正確地求出array的md5值,這樣就會導致任意2個array的md5值都會相等。這個md5()的特性在攻防平台中的bypass again同樣有考到。

strcmp()

strcmp()函數在PHP官方手冊中的描述是int strcmp ( string $str1 , string $str2 ),需要給strcmp()傳遞2個string類型的參數。如果str1小於str2,回傳-1,相等回傳0,否則回傳1。 strcmp函數比較字串的本質是將兩個變數轉換為ascii,然後進行減法運算,然後根據運算結果來決定傳回值。

如果傳入給strcmp()的參數是數字呢?

$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";
}

strcmp這種特性在攻防平台中的pass check有測驗。

switch()

如果switch是數字類型的case的判斷時,switch會將其中的參數轉換為int型別。如下:

$array=[0,1,2,'3'];
var_dump(in_array('abc', $array));  //true
var_dump(in_array('1bc', $array));    //true

這個時候程式輸出的是i is less than 3 but not negative,是由於switch()函數將$i進行了型別轉換,轉換結果為2。 🎜🎜in_array()🎜

在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()也是一样的问题。


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器