這篇文章主要介紹由php中字符offset特征造成繞過漏洞的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)建站是一家以成都網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)、品牌設(shè)計(jì)、軟件運(yùn)維、營(yíng)銷推廣、小程序App開發(fā)等移動(dòng)開發(fā)為一體互聯(lián)網(wǎng)公司。已累計(jì)為成都三維植被網(wǎng)等眾行業(yè)中小客戶提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開發(fā)服務(wù)。php中的字符offset特性
php中的字符串存在一個(gè)非常有趣的特性,php中的字符串也可以像數(shù)組一樣進(jìn)行取值。
$test = "hello world"; echo $test[0];
最后的結(jié)果就是h。
但是上述的這種特性有時(shí)會(huì)有意想不到的效果,看下面這段代碼
$mystr = "hello world"; echo $mystr["pass"];
上述的代碼的輸出結(jié)果是h.這是為什么呢?其實(shí)很簡(jiǎn)單,和很多其他的語言一樣,字符串在php中也像數(shù)組一樣可以使用下標(biāo)取值。$mystr["pass"]
中pass會(huì)被進(jìn)行隱性類型轉(zhuǎn)換為0,這樣$mystr[0]
的輸出結(jié)果就是首字母h.
同樣地,如果嘗試如下的代碼:
$mystr = "hello world"; echo $mystr["1pass"];
輸出結(jié)果就是e.因?yàn)?pass會(huì)被隱性類型轉(zhuǎn)換為1,$mystr[1]
的輸出結(jié)果就是第二個(gè)字母e.
字符特性造成的漏洞
下面這段代碼是在在phpspy2006中用于判斷登錄時(shí)所使用的代碼。
$admin['check'] = "1"; $admin['pass'] = "angel"; ...... if($admin['check'] == "1") { .... }
這樣的驗(yàn)證邏輯如果利用上述的特性就很容易地就可以被繞過。$admin沒有被初始定義為數(shù)組類型,那么當(dāng)我們用字符串提交時(shí)phpsyp.php?admin=1abc
時(shí),php會(huì)取字符串1xxx的第一位,成功繞過if的條件判斷。
上面那段代碼是一個(gè)代碼片段,接下來的這段代碼是一段完整的邏輯代碼,來自于php4fun中第5題,比較有意思。
8, # 'name' => 'jimbo18714', # 'pass' => 'MAYBECHANGED', # 'level' => 1 # ); require 'db.inc.php'; function mres($str) { return mysql_real_escape_string($str); } $userInfo = @unserialize($_GET['userInfo']); $query = 'SELECT * FROM users WHERE id = \'' . mres($userInfo['id']) . '\' AND pass = \'' . mres($userInfo['pass']) . '\';'; $result = mysql_query($query); if (!$result || mysql_num_rows($result) < 1) { die('Invalid password!'); } $row = mysql_fetch_assoc($result); foreach ($row as $key => $value) { $userInfo[$key] = $value; } $oldPass = @$_GET['oldPass']; $newPass = @$_GET['newPass']; if ($oldPass == $userInfo['pass']) { $userInfo['pass'] = $newPass; $query = 'UPDATE users SET pass = \'' . mres($newPass) . '\' WHERE id = \'' . mres($userInfo['id']) . '\';'; mysql_query($query); echo 'Password Changed.'; } else { echo 'Invalid old password entered.'; }
這道題目網(wǎng)上也僅僅只是給了一個(gè)最終的答案,其中的原理都沒有說或者沒有說得很詳細(xì)。其實(shí)原理就是上面講到的php的字符特性。
題目要求很簡(jiǎn)單就是修改admin的密碼,admin的id為1。我們需要思考以下幾個(gè)問題:
如何在更新的時(shí)候?qū)d修改為1
$userInfo['pass'] = $newPass;
這行代碼有什么作用,為什么會(huì)在if判斷語句中存在這種的代碼
想通了這兩個(gè)問題,那么最終的解決方法也有了。將id為8的用戶的密碼修改為8,然后傳入一個(gè)userInfo的字符串‘8',突破查詢防護(hù),最后利用$userInfo['pass'] = $newPass
將id修改為1。
最終的payload就是;
第一次提交,index.php?userInfo=a:2:{s:2:"id";i:8;s:4:"pass";s:12:"MAYBECHANGED";}&oldPass=MAYBECHANGED&newPass=8
,目的是將id為8的用戶的密碼修改為8
第二次提交,index.php?userInfo=s:1:"8";&oldPass=8&newPass=1
,這樣序列化$userInfo得到的就是字符串‘8',即$userInfo = ‘8'
,這樣數(shù)據(jù)庫(kù)查詢驗(yàn)證就可以通過。之后的if驗(yàn)證也可以通過,通過這行代碼$userInfo['pass'] = $newPass;
,由于$newpass的值為1,那么上述代碼變?yōu)榱?code>$userInfo['pass'] = 1; ,$userInfo
由于一個(gè)字符串類型,最后得到的是$userInfo='1'
,最后就可以更新id為1的用戶的密碼了。
修復(fù)方式
這種漏洞的修復(fù)方式也很簡(jiǎn)單,事先定義好數(shù)據(jù)類型同時(shí)在使用時(shí)好檢查一下所使用的數(shù)據(jù)類型是否和預(yù)期的一致。否則就會(huì)出現(xiàn)上述的繞過的問題。同時(shí)要控制好輸入,對(duì)輸入的數(shù)據(jù)要進(jìn)行檢查不要隨意地使用。
以上是“由php中字符offset特征造成繞過漏洞的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!