php弱类型总结
目錄:
PHP弱類型介紹
數字和字符串比較
CTF之md5繞過
PHP弱類型介紹
比較操作符 === 在進行比較的時候,會先判斷兩邊的類型是否相等,再比較。 == 在進行比較的時候,如果是數字與字符串進行比較(或者字符串與數字),會先將字符串類型轉化成數值型再比較。當字符串與數字使用==進行比較時,會將字符串類型轉換成數字型再進行比較(如果兩邊都是字符串,則雙方都轉換為數字型),只比較轉換后的數值的大小
(1)當字符串的開始部分不存在數值時會把該字符串轉換成數值0
(2)當字符串的開始部分有合法數值時,會把該字符串轉換成該合法數值(取從最開始后面連續的數值,可以見下面的例子)
(3)當字符串中存在合法數值但合法數值不在開始部分,那么字符串仍然會轉換成數值0
(4)當字符串中包含e或E時,系統會將其識別為科學記數法(0^n均為0)(0e123456=0E789=0)
(1)(2)(3)點總結:字符串的開始部分決定了它的值,如果該字符串以合法的數值開始,則使用該數值,否則其值為0。
數字和字符串比較
<?php var_dump('root' == 0); //true//分析:先將字符串root轉化成和0同等類型即數字型,因為字符串開始沒有合法數值,則字符串root轉換為0,最后0==0,所以成立。 var_dump(0 == 'root'); //true//分析:先將字符串root轉化成和0同等類型即數字型,因為字符串開始沒有合法數值,則字符串root轉換為0,最后0==0,所以成立。 var_dump('22root' == 22); //true//分析:先將字符串22root轉化成和0同等類型即數字型,因為字符串開始有合法數值,則取其連續的合法數值22,最后22==22,所以成立。 var_dump('22r22oot' == 22); //true//分析:先將字符串22r22oot轉化成和0同等類型即數字型,因為字符串開始有合法數值,則取其連續的合法數值22,r后面的22因為與開始的合法數值不連續,所以不取它的值,22==22,所以成立。 var_dump('root22' == 22); //false//分析:先將字符串root22轉化成和0同等類型即數字型,因為字符串開始沒有合法數值,則字符串root22轉換為0,最后0==22,所以不成立。 var_dump('root22' == 0); //true//分析:先將字符串root22轉化成和0同等類型即數字型,因為字符串開始沒有合法數值,則字符串root22轉換為0,最后0==0,所以成立。 var_dump('0e170' == '0e180'); //true//分析:因為字符串中含有e開頭的值,那么php代碼會將其整體看成科學記數法,最后0的170次方==0的180次方,即0==0,所以成立 var_dump(0 === 'root'); //false//分析:=== 在進行比較的時候,會先判斷兩邊類型是否相等,這里數值和字符串類型明顯不等,因此不成立 var_dump ("0e830400451993494058024219903391" == 0); //true//分析:先將字符串0e830400451993494058024219903391轉化成和0同等類型即數字型,因為字符串開始有合法數值,則字符串0e830400451993494058024219903391轉換為0,最后0==0,所以成立。 var_dump ("0e830400451993494058024219903391" == "0e830400451993494058024219904444"); //true//分析:先將字符串0e830400451993494058024219903391與0e830400451993494058024219904444分別轉化成數字型,因為兩個字符串開始都有合法數值,則字符串0e830400451993494058024219903391轉換為0,字符串0e830400451993494058024219904444轉換為0,最后0==0,所以成立。 var_dump (0e830400451993494058024219903391 == 0e830400451993494058024219904444); //true//分析:這不是字符串的比較了,這是數字型的比較,因為==兩邊的都是科學記數法0e(0的次方),最終0=0 ?>注:有一點需要注意,就是如果字符串中出現的"."或"e"或"E",那么,此類字符串和數字進行比較時,會有所區別,如下:
<?php var_dump("123.a1bc"==123);//true var_dump("123ea1bc"==123);//true var_dump("123Ea1bc"==123);//true 上面都是true,有什么區別嗎,其實這上面是沒有什么區別,和前面說到的一樣,將字符串開始部分從數字連續取到非數字截止 那看看下面這幾個代碼 var_dump("123.2abc"==123);//false var_dump("123.2abc"==1232);//false var_dump("123e2abc"==123);//false vardump("123E2abc"==123);//false 開始部分存在數字,若連續的數字中包含.或e或E會干擾字符串和數字的比較,因為.就表示了浮點數,e和E表示了科學計數法,只要字符串中包含這些,上面所說的比較就不能理想地實現 ?>CTF之md5繞過
$md51 = md5('QNKCDZO');//md5=0e830400451993494058024219903391 $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'QNKCDZO' && $md51 == $md52) {echo "nctf{*****************}"; } else {echo "false!!!"; }} else{echo "please input a";}這里關鍵部分為$a != 'QNKCDZO' && $md51 == $md52即為$a不等于QNKCDZO并且$md51 == $md52
那么這里就要用到0e了,$md51=0e830400451993494058024219903391,因此$md52我們需要使用加密后是0e開頭的值,那么代碼中的a經加密后是0e開頭的有如下(列出幾個):
此時,a等于其中上述一個即可繞過
s878926199a != 'QNKCDZO' && 0e830400451993494058024219903391 == 0e545993274517709034328855841020 &&左半部分不相等,右半部分,都是0e開頭的相比較(科學記數法),0的830400451993494058024219903391次方==0的545993274517709034328855841020,即為0==0,成立特別注意:bool類型的true跟任意字符串可以弱類型相等
總結
- 上一篇: CGCTF-Web-签到题
- 下一篇: csgo老六是啥意思 请问csgo玩国服