php弱类型漏洞,php代码审计之弱类型引发的灾难
天融信阿爾法實(shí)驗(yàn)室 李喆
有人說php是世界上最好的語言,這可能是對開發(fā)人員來說,確實(shí)有這方面的特點(diǎn),因?yàn)樗_發(fā)起來不像其他語言那樣麻煩,就比如:弱類型,它不需要像java等語言那樣明確定義數(shù)據(jù)類型。這給開發(fā)帶來了很大的便利,所有的數(shù)據(jù)類型都可以用$xx來定義,而不需要int i,string a,fload b等等這樣去定義它。這樣確實(shí)很方便,因?yàn)閜hp幫助你判斷了數(shù)據(jù)類型,比如整形int ,你只要$a=1;那這個(gè)1就是整形,$a=’abc’那這個(gè)abc就會(huì)被php判斷為字符串類型。但是弱類型方便是方便,但是帶來的安全問題也是巨大的,很多的php安全漏洞都是因?yàn)樗鼛淼摹?/p>
本文是給做代碼審計(jì)漏洞挖掘和滲透測試人員總結(jié)的一個(gè)思路,有不對的地方請多多指出。
這里主要是介紹如何通過利用弱類型來做php代碼審計(jì)的漏洞挖掘。漏洞挖掘關(guān)鍵點(diǎn)肯定在變量上,因?yàn)樽兞靠梢猿薪油鈦韰?shù)和內(nèi)部數(shù)據(jù)的交互工作,這是漏洞的起因,也是必要條件。如果外來參數(shù)是惡意代碼,同時(shí)再因?yàn)槭褂昧巳躅愋偷暮瘮?shù)或者比較運(yùn)算符導(dǎo)致了惡意參數(shù)的數(shù)據(jù)進(jìn)入了程序里比如數(shù)據(jù)庫,就可能引發(fā)想象不到的破壞力。這里我介紹了三種可以導(dǎo)致惡意數(shù)據(jù)進(jìn)入判斷體里的函數(shù)和比較運(yùn)算符,他們有共同的特點(diǎn),就是和數(shù)據(jù)比較,然后把外來變量做自動(dòng)類型轉(zhuǎn)換,如果外來變量是惡意變量,利用一定的方法就可以繞過你想繞過的地方比如判斷if條件,讓惡意變量進(jìn)入到條件體內(nèi),惡意變量如果在判斷體內(nèi)被代入到了數(shù)據(jù)庫的增刪改查操作中就可以引發(fā)sql注入等漏洞問題。
01第一個(gè)要介紹的是 is_numeric,它的功能是,判斷參數(shù)是否為數(shù)字或者數(shù)字字符串,如果是則返回true,假返回false,它的弱類型問題是他支持十六進(jìn)制0x格式,如何引發(fā)的安全問題讓我們繼續(xù)觀看。
安全問題描述:is_numeric在做判斷時(shí)候,如果攻擊者把payload改成二進(jìn)制0x..,is_numeric會(huì)先對十六進(jìn)制做類型判斷,十六進(jìn)制被判斷為數(shù)字型,為真,就進(jìn)入了條件語句,如果再把這個(gè)代入進(jìn)入sql語句進(jìn)入mysql數(shù)據(jù)庫,mysql數(shù)據(jù)庫會(huì)對hex進(jìn)行解析成字符串存入到數(shù)據(jù)庫中,如果這個(gè)字段再被取出來二次利用,就可能因?yàn)槎巫⑷肼┒?比如這樣:
if(is_numeric($_GET['num']))
{
echo $_GET['num'];
echo “”;
//假設(shè)這個(gè)插入進(jìn)了mysql數(shù)據(jù)庫,mysql數(shù)據(jù)庫就會(huì)把十六進(jìn)制轉(zhuǎn)換成了字符串,這里為了方便用 Hex2String 函數(shù)代替
echo Hex2String($_GET['num']);
//輸入http://127.0.01/equal.php?num=0x39393939393939393939393920756e696f6e20616c6c202873656c656374202748656c6c6f21212729
// 輸出0x39393939393939393939393920756e696f6e20616c6c202873656c656374202748656c6c6f2121272
//輸出9999999999999 union all (select ‘Hello!!’)
}
function Hex2String($hex){
$string=”;
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
可以看到,數(shù)據(jù)庫存入的是 9999999999999 union all (select ‘Hello!!’) ,如果被取出來再輸出沒做過濾就會(huì)引發(fā)二次注入
防御方法:用intval函數(shù)獲取變量整數(shù)值,對從數(shù)據(jù)庫取出變量做過濾
上面的不理解,可以看一個(gè)案例分析:
這里有個(gè)例子:
圖1.1
問題出現(xiàn)在if (!isset($_POST['id'], $_POST['vote']) || !is_numeric($_POST['id'])) 如果能繞過is_numeric,就可以執(zhí)行mysql_query(“INSERT INTO vote VALUES ({$id}, {$vote}, ‘{$login}’)”); 注入sql語句。
999999999999 union all \(select ‘Hello!!’\)
轉(zhuǎn)成 hex=0x39393939393939393939393920756e696f6e20616c6c202873656c656374202748656c6c6f21212729
我們提交的參數(shù):
vote=1&submit=&id=0x39393939393939393939393920756e696f6e20616c6c202873656c656374202748656c6c6f21212729
圖1.2
我們可以清楚的在圖片里看到,我們插入的Hello!在其他查詢位置被顯示了出來,引發(fā)了二次注入漏洞問題。
02 第二個(gè)介紹的是比較運(yùn)算符的安全隱患,比如 ==,!= ,同時(shí)還會(huì)介紹他們和恒等式和=== ,!==的區(qū)別和安全問題
函數(shù)功能:
==和!=是比較運(yùn)算符號(hào) 不會(huì)檢查條件式的表達(dá)式的類型
安全問題描述:php是弱類型,在做匹配和比較時(shí)候,會(huì)根據(jù)匹配的類型做類型轉(zhuǎn)換,如果后面是整形,如$a==1,因?yàn)楹竺娴?是整形,那前面gpc傳進(jìn)來就會(huì)轉(zhuǎn)換成整形,轉(zhuǎn)換規(guī)則是前面的數(shù)字不變后面字母被當(dāng)成字符型舍去,也就是1a會(huì)變成1,判斷為真進(jìn)入判斷體;如果這樣$a==”1″,那么后面的就是字符串1,如果gpc傳進(jìn)來1a會(huì)發(fā)現(xiàn)為假,因?yàn)閭鬟M(jìn)來的1a做類型轉(zhuǎn)換成字符串后就是1a,字符串1a和字符串1不想等,所以為假,這時(shí)候要改成1才能進(jìn)入判斷體內(nèi);同樣在進(jìn)行加減乘除比較運(yùn)算判斷時(shí)候也會(huì)做自動(dòng)類型轉(zhuǎn)換,如果跟整形比較,1a會(huì)轉(zhuǎn)換成1,跟字符串比較,a1就會(huì)轉(zhuǎn)換成字符串a(chǎn)1,其他類型也一樣。
如果你覺得這樣很繞看不懂,那就簡單說,如果和字符串做比較,就會(huì)轉(zhuǎn)換成字符串,如果和整形做比較,就會(huì)自動(dòng)轉(zhuǎn)換成整形,只不過整形自動(dòng)轉(zhuǎn)換的時(shí)候php就是用的intval 函數(shù)導(dǎo)致1a為1。intval函數(shù)可以自查下,大致如:intval(“a”)=0; intval(12.3223)=12; intval(“12abc”)=12;
比如:
$a = $_GET['a'];
if ($a==1)
{
echo ‘vul->’.$a;
}
同樣!=也會(huì)有這個(gè)問題,換成2就可以進(jìn)到判斷體內(nèi)
$a = $_GET['a'];
if ($a!=1)
{
echo ‘vul->’.$a;
}
防范方法:用===和!==來做判斷,他們是恒等計(jì)算符, 同時(shí)檢查表達(dá)式的值與類型
跟數(shù)字有關(guān)的運(yùn)算都可能引起弱類型漏洞,比如下面這個(gè)運(yùn)算
但是這樣也不完全可以,比如加減乘除運(yùn)算符也會(huì)做類型轉(zhuǎn)換
假如這樣:
$a = $_GET['a'];
$b = $_GET['b'];
if($a+$b===2)
{
echo “vul->”.$a.””.$b;
}
所以最安全的防范是對gpc獲取數(shù)字型的參數(shù)值進(jìn)行intval強(qiáng)制類型轉(zhuǎn)換或者過濾,再做判斷
$a = intval($_GET['a']);
$b = intval($_GET['b']);
if($a+$b===2)
{
echo “vul->”.$a.””.$b;
}
03 第三個(gè)要就介紹的是in_array()函數(shù)
函數(shù)功能:判斷一個(gè)值是否在數(shù)組中存在
安全問題描述:這個(gè)函數(shù)的弱類型問題是,判斷的值在比較之前會(huì)做類型轉(zhuǎn)換,同樣是弱類型問題,比如in_array($_GET['id'],array(1,2,3,4,5)),如果我們傳入 id=1’ union select… ,判斷就會(huì)為真,因?yàn)閕d被轉(zhuǎn)換成1,這時(shí)候假如我們再把$_GET['id']拼接到數(shù)據(jù)庫語句中,就會(huì)引起sql注入漏 洞。
if(in_array($_GET['id'],array(1,2,3,4,5)))
{
echo $_GET['id'];
//輸入http://127.0.01/equal.php?id=1′id
//輸出: 1′id
}
防范方法:外來變量要做過濾,或者強(qiáng)制類型轉(zhuǎn)換
總結(jié)
以上是生活随笔為你收集整理的php弱类型漏洞,php代码审计之弱类型引发的灾难的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arcgis标注牵引线_解析ArcGis
- 下一篇: server sql 去 反斜杠_%00