有人說php是世界上最好的語(yǔ)言吧凉,這可能是對(duì)開發(fā)人員來說,確實(shí)有這方面的特點(diǎn)怎栽,因?yàn)樗_發(fā)起來不像其他語(yǔ)言那樣麻煩丽猬,就比如:弱類型,它不需要像java等語(yǔ)言那樣明確定義數(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ì)漏洞挖掘和滲透測(cè)試人員總結(jié)的一個(gè)思路娃循,有不對(duì)的地方請(qǐng)多多指出。
這里主要是介紹如何通過利用弱類型來做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ù)庫(kù)爆哑,就可能引發(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ù)庫(kù)的增刪改查操作中就可以引發(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ì)先對(duì)十六進(jìn)制做類型判斷敞斋,十六進(jìn)制被判斷為數(shù)字型,為真疾牲,就進(jìn)入了條件語(yǔ)句植捎,如果再把這個(gè)代入進(jìn)入sql語(yǔ)句進(jìn)入mysql數(shù)據(jù)庫(kù),mysql數(shù)據(jù)庫(kù)會(huì)對(duì)hex進(jìn)行解析成字符串存入到數(shù)據(jù)庫(kù)中阳柔,如果這個(gè)字段再被取出來二次利用焰枢,就可能因?yàn)槎巫⑷肼┒?比如這樣:
if(is_numeric($_GET['num']))
{
echo $_GET['num'];
echo “
”;//假設(shè)這個(gè)插入進(jìn)了mysql數(shù)據(jù)庫(kù),mysql數(shù)據(jù)庫(kù)就會(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ù)庫(kù)存入的是 9999999999999 union all (select ‘Hello!!’) ,如果被取出來再輸出沒做過濾就會(huì)引發(fā)二次注入
防御方法:用intval函數(shù)獲取變量整數(shù)值架诞,對(duì)從數(shù)據(jù)庫(kù)取出變量做過濾
上面的不理解拟淮,可以看一個(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語(yǔ)句谴忧。
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,其他類型也一樣引颈。
如果你覺得這樣很繞看不懂耕皮,那就簡(jiǎn)單說,如果和字符串做比較蝙场,就會(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;
}
所以最安全的防范是對(duì)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í)候假如我們?cè)侔?_GET['id']拼接到數(shù)據(jù)庫(kù)語(yǔ)句中,就會(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)換