各種關於md5的Bypass操作,都是基本操作,考察數組繞過、弱類型比較繞過以及md5($password,true) ByPass
1、利用md5($password,true)實現SQL注入
F12或者Burp抓取響應頭可以看到Hint,也就是后端處理的SQL語句:
select * from 'admin' where password=md5($pass,true)
突破點在md5($pass,true)這里,先來看看md5函數的用法:
可以看到這里的raw參數是True,意為返回原始16字符二進制格式。
也就是說如果md5值經過hex轉成字符串后為 'or'+balabala這樣的字符串,則拼接后構成的SQL語句為:
select * from `admin` where password=''or'balabala'
當'or'后面的值為True時,即可構成萬能密碼實現SQL注入,這里我們需要知道的是MySQL的一個特性:
在mysql里面,在用作布爾型判斷時,以1開頭的字符串會被當做整型數。要注意的是這種情況是必須要有單引號括起來的,比如password=‘xxx’ or ‘1xxxxxxxxx’,那么就相當於password=‘xxx’ or 1 ,也就相當於password=‘xxx’ or true,所以返回值就是true。當然在我后來測試中發現,不只是1開頭,只要是數字開頭都是可以的。
當然如果只有數字的話,就不需要單引號,比如password=‘xxx’ or 1,那么返回值也是true。(xxx指代任意字符)
select * from `admin` where password=''or'1abcdefg' ---> True select * from `admin` where password=''or'0abcdefg' ---> False select * from `admin` where password=''or'1' ---> True select * from `admin` where password=''or'2' ---> True select * from `admin` where password=''or'0' ---> False
只要'or'后面的字符串為一個非零的數字開頭都會返回True,這就是我們的突破點。
我們可以通過這個腳本來獲得滿足我們要求的明文:
<?php for ($i = 0;;) { for ($c = 0; $c < 1000000; $c++, $i++) if (stripos(md5($i, true), '\'or\'') !== false) echo "\nmd5($i) = " . md5($i, true) . "\n"; echo "."; } ?> //引用於 http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/
這里提供一個最常用的:ffifdyop,該字符串md5加密后若raw參數為True時會返回 'or'6<trash> (<trash>其實就是一些亂碼和不可見字符,這里只要第一位是非零數字即可被判定為True,后面的<trash>會在MySQL將其轉換成整型比較時丟掉)
所以如果這里我們輸入ffifdyop,后端的SQL語句會變成:
select * from `admin` where password=''or'6<trash>' ---> True
成功構成SQL注入,我們在本題直接輸入ffifdyop即可進入下一關
2、PHP md5弱類型比較
進入第二關后右鍵查看源代碼可以從注釋中得到后端PHP的一部分源碼:
$a = $GET['a']; $b = $_GET['b']; if($a != $b && md5($a) == md5($b)){ // wow, glzjin wants a girl friend.
可以看到,趙師傅又在征婚了 這里要求a和b明文值不同,但md5值相同,注意這里是兩個等於號,是弱相等,所以我們可以利用PHP的弱類型比較突破,尋找兩個明文不同但md5值為"0exxxxx"的字符串,可以參考我之前的一篇文章:https://www.cnblogs.com/yesec/p/12232075.html
這里直接提供兩個QNKCDZO和s214587387a,用GET傳值直接過關
3、數組繞過
進入第三關給出了源碼:
<?php error_reporting(0); include "flag.php"; highlight_file(__FILE__); if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){ echo $flag; }
可以看到依舊是md5比較,但是不同於第二關,這一關是“===“強相等,很明顯2中的方法沒辦法通過
剛才推薦的那一片文章里文末也提到了這種方法,這里需要知道的是PHP的一些特性:
md5(array()) = null
sha1(array()) = null
ereg(pattern,array()) = null vs preg_match(pattern,array) = false
strcmp(array(), "abc") = null
strpos(array(),"abc") = null
引用自 https://blog.csdn.net/q1352483315/article/details/89469928
md5()函數無法處理數組,如果傳入的為數組,會返回NULL,所以兩個數組經過加密后得到的都是NULL,也就是相等的。
所以直接POST傳入param1[]=1¶m2[]=2即可得到Flag: