溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP弱類型安全問題案例

發(fā)布時間:2020-11-03 13:47:33 來源:億速云 閱讀:125 作者:小新 欄目:編程語言

這篇文章主要介紹了PHP弱類型安全問題案例,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

0x00 弱類型初探

沒有人質疑php的簡單強大,它提供了很多特性供開發(fā)者使用,其中一個就是弱類型機制。

在弱類型機制下 你能夠執(zhí)行這樣的操作

<?php
$var = 1;
$var = array();
$var = "string";
?>

php不會嚴格檢驗傳入的變量類型,也可以將變量自由的轉換類型。

比如 在$a == $b的比較中

$a = null; $b = false; //為真
$a = ''; $b = 0; //同樣為真

然而,php內核的開發(fā)者原本是想讓程序員借由這種不需要聲明的體系,更加高效的開發(fā),所以在 幾乎所有內置函數(shù)以及基本結構 中使用了很多松散的比較和轉換,防止程序中的變量因為程序員的不規(guī)范而頻繁的報錯,然而這卻帶來了安全問題。

0x02 知識預備 php內核之zval結構

在PHP中聲明的變量,在ZE中都是用結構體zval來保存的

zval的定義在zend/zend.h

typedef struct _zval_struct zval;  
struct _zval_struct {  
  /* Variable information */  
  zvalue_value value; /* value */  
  zend_uint refcount__gc;  
  zend_uchar type;/* active type */  
  zend_uchar is_ref__gc;  
};  
typedef union _zvalue_value {  
  long lval;  /* long value */  
  double dval;/* double value */  
  struct {  
    char *val;  
    int len;  
  } str;  
  HashTable *ht;  /* hash table value */  
  zend_object_value obj;  
} zvalue_value;

其中php通過type判斷變量類型 存入value

如上也就是php內核中弱類型的封裝,也是我們后面講的所有東西的原理和基礎。

0x03變量的強制轉換

通過剛剛的了解,我們知道zval.type決定了存儲到zval.value的類型。

當源代碼進行一些未限制類型的比較,或數(shù)學運算的時候,可能會導致zval.type的改變,同時影響zval.value的內容改變。

當int遇上string

cp.1 數(shù)學運算

當php進行一些數(shù)學計算的時候

ar_dump(0 == '0'); // true
var_dump(0 == 'abcdefg'); // true  
var_dump(0 === 'abcdefg'); // false
var_dump(1 == '1abcdef'); // true

當有一個對比參數(shù)是整數(shù)的時候,會把另外一個參數(shù)強制轉換為整數(shù)。

相當于對字符串部分

intval再和整數(shù)部分比較,其實也就是改變了zval.type的內容 尤為注意的是,'1assd'的轉換后的值是1,而‘a(chǎn)sdaf’是0

也說明了intval會從第一位不是數(shù)字的單位開始進行

所有也有

var_dump(intval('3389a'));//輸出3389

這個例子就告訴我們,永遠不要相信下面的代碼

if($a>1000){    
mysql_query('update ... .... set value=$a')
}

你以為這時候進入該支的萬無一失為整數(shù)了

其實$a可能是1001/**/union...

cp.2 語句條件的松散判斷

舉個例子php的switch使用了松散比較. $which會被自動intval變成0如果每個case里面沒有break ,就會一直執(zhí)行到包含,最終執(zhí)行到我們需要的函數(shù),這里是成功包含

<?php
if (isset($_GET['which']))
{
  $which = $_GET['which'];
  switch ($which)
  {
  case 0:
  case 1:
  case 2:
    require_once $which.'.php';
    break;
  default:
    echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
    break;
  }

cp.3 函數(shù)的松散判斷

var_dump(in_array("abc", $array));

in_array — 檢查數(shù)組中是否存在某個值 參數(shù)

needle 待搜索的值。

Note: 如果 needle 是字符串,則比較是區(qū)分大小寫的。 haystack 這個數(shù)組。

strict 如果第三個參數(shù) strict 的值為 TRUE 則 in_array() 函數(shù)還會檢查 needle 的類型是否和 haystack 中的相同。

可以看到,只有加了strict才會對類型進行嚴格比較, 那么我們再次把×××和字符串進行比較呢?

var_dump(in_array("abc", $array1));</br>
var_dump(in_array("1bc", $array2));

它遍歷了array的每個值,并且作"=="比較(“當設置了strict 用===”)

結果很明顯了

如果array1里面有個值為0,那么第一條返回就會為真//intval('abc')=0

如果array2里面有個值為1,那么第二條就會為真//intval('1bc')=1

array_search也是一樣的原理

這里的應用就很廣泛了,

很多程序員都會檢查數(shù)組的值,

那么我們完全可以用構造好的int 0或1 騙過檢測函數(shù),使它返回為真

總結一下, 在所有php認為是int的地方輸入string,都會被強制轉換 ,比如

$a = 'asdfgh';//字符串類型的a</br>
echo $a[2];  //根據(jù)php的offset 會輸出'd'</br>
echo $a[x];  //根據(jù)php的預測,這里應該是int型,那么輸入string,就會被intval成為0 也就是輸出'a'

當數(shù)組遇上string

這一個例子我是在德國的一個ctf中遇到,很有意思前面我們講的都是string和int的比較

那么array碰上int或者是string會有什么化學反應?

由php手冊我們知道

Array轉換整型int/浮點型float會返回元素個數(shù);

轉換bool返回Array中是否有元素;轉換成string返回'Array',并拋出warning。

那么實際應用是怎樣的呢?

if(!strcmp($c[1],$d) && $c[1]!==$d){
...
}

可以發(fā)現(xiàn),這個分支通過strcmp函數(shù)比較要求兩者相等且“==”要求兩者不相等才能進入。

strcmp() 函數(shù)比較兩個字符串。

該函數(shù)返回:

0 - 如果兩個字符串相等

<0 - 如果 string1 小于 string2

>0 - 如果 string1 大于 string2

這里的strcmp函數(shù)實際上是將兩個變量轉換成ascii 然后做數(shù)學減法,返回一個int的差值。

也就是說鍵入'a'和'a'進行比較得到的結果就是0

那么如果讓$array和&lsquo;a’比較呢?

http://localhost:8888/1.php?a[]=1
var_dump(strcmp($_GET[a],'a'));

這時候php返回了null!

也就是說,我們讓這個函數(shù)出錯從而使它恒真,繞過函數(shù)的檢查。

0x04時時防備弱類型

作為一個程序員,弱類型確實給程序員書寫代碼帶來了很大的便利,但是也讓程序員忘記了$array =array();的習慣。都說一切輸入都是有害的

那么其實可以說一切輸入的類型也是可疑的,永遠不要相信弱類型的php下任何比較函數(shù),任何數(shù)學運算。否則,你絕對是被php出賣的那一個。

感謝你能夠認真閱讀完這篇文章,希望小編分享PHP弱類型安全問題案例內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

php
AI