最近做ctf題目會經常碰到PHP弱類型的題目,本文主要和大家分享PHP弱類型總結,希望能協助到大家。
知識介紹:
php中有兩種比較的符號 == 與 ===
<?php$a = $b ;$a===$b ;?>
=== 在進行比較的時候,會先判斷兩種字串的類型是否相等,再比較
== 在進行比較的時候,會先將字串類型轉化成相同,再比較
如果比較一個數字和字串或者比較涉及到數字內容的字串,則字串會被轉換成數值並且比較按照數值來進行
php不會嚴格檢驗傳入的變數類型,也可以將變數自由的轉換類型。
比如 在$a == $b的比較中
$a = null; $b = false; //為真 $a = ''; $b = 0; //同樣為真
另外,如果一個數值和字串進行比較的時候,會將字串轉換成數值
<?phpvar_dump("admin"==0); //truevar_dump("1admin"==1); //truevar_dump("admin1"==1) //falsevar_dump("admin1"==0) //truevar_dump("0e123456"=="0e4456789"); //true ?>
1 、觀察上述代碼,"admin"==0 比較的時候,會將admin轉化成數值,強制轉化,由於admin是字串,轉化的結果是0自然和0相等。
2 、"1admin"==1 比較的時候會將1admin轉化成數值,結果為1,而“admin1“==1 卻等於錯誤,也就是"admin1"被轉化成了0。
3 、"0e123456"=="0e456789"相互比較的時候,會將0e這類字串識別為科學技術法的數字,0的無論多少次方都是零,所以相等。
應當注意的是: 當一個字串欸當作一個數值來取值,其結果和類型如下:如果該字串沒有包含 '.' ,'e' , 'E',並且其數值值在整形的範圍之內 該字串被當作int來取值,其他所有情況下都被作為float來取值,該字串的開始部分決定了它的值,如果該字串以合法的數值開始,則使用該數值,否則其值為0。
繞過類型:
md5繞過(Hash比較缺陷)
<?php if (isset($_GET['Username']) && isset($_GET['password'])) { $logined = true; $Username = $_GET['Username']; $password = $_GET['password']; if (!ctype_alpha($Username)) {$logined = false;} if (!is_numeric($password) ) {$logined = false;} if (md5($Username) != md5($password)) {$logined = false;} if ($logined){ echo "successful"; }else{ echo "login failed!"; } } ?>
題目大意是要輸入一個字串和數字類型,並且他們的md5值相等,就可以成功執行下一步語句
介紹一批md5開頭是0e的字串 上文提到過,0e在比較的時候會將其視作為科學計數法,所以無論0e後面是什麼,0的多少次方還是0。md5('240610708') == md5('QNKCDZO')成功繞過!
==南郵ctf bypass again==
開啟後看到代碼:
if (isset($_GET['a']) and isset($_GET['b'])) {if ($_GET['a'] != $_GET['b'])if (md5($_GET['a']) == md5($_GET['b']))die('Flag: '.$flag);elseprint 'Wrong.';}
源碼要求提交兩個不相等的值使他們的md5值嚴格相等。md5()函數要求接收一個字串,若傳遞進去一個數組,則會返回null,即var_dump(md5(array(2))===null);值為bool(true)
可以向$_GET數組傳入兩個名為a、b的不相等的數組,從而導致md5()均返回空,於是得到flag。 構造url:http://chinalover.sinaapp.com/web17/index.php?a[]=0&b[]=1 json繞過
<?phpif (isset($_POST['message'])) { $message = json_decode($_POST['message']); $key ="*********"; if ($message->key == $key) { echo "flag"; } else { echo "fail"; } } else{ echo "~~~~"; }?>
輸入一個json類型的字串,json_decode函數解密成一個數組,判斷數組中key的值是否等於 $key的值,但是$key的值我們不知道,但是可以利用0=="admin"這種形式繞過
最終payload message={"key":0}。
strcmp漏洞繞過
<?php $password="***************" if(isset($_POST['password'])){ if (strcmp($_POST['password'], $password) == 0) { echo "Right!!!login success";n exit(); } else { echo "Wrong password.."; } ?>
strcmp是比較兩個字串,如果str1<str2 則返回<0 如果str1大於str2返回>0 如果兩者相等 返回0
我們是不知道$password的值的,題目要求strcmp判斷的接受的值和$password必需相等,strcmp傳入的期望類型是字串類型,如果傳入的是個數組會怎麼樣呢
我們傳入 password[]=xxx 可以繞過 是因為函數接受到了不符合的類型,將發生錯誤,但是還是判斷其相等
payload: password[]=xxx
相關推薦:
php弱類型語言中關於類型判斷的執行個體分析
PHP弱型別安全問題總結
PHP弱類型變數是如何?的