[BUUOJ記錄] [BJDCTF2020]Easy MD5


各種關於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&param2[]=2即可得到Flag:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM