淺談md5弱類型比較和強碰撞

2021-03-02 合天智匯

知識點實操概要

CTF多種類型題目一應俱全

連結指路:

https://www.hetianlab.com/cour.do?w=1&c=CCID2d51-5e95-4c58-8fc9-13b1659c1356&pk_campaign=weixin-wemedia    

複製上方連結馬上體驗

前言

在CTF中,md5的題目太常見了,雖然有很多這方面的文章,但相對來說比較零散,這裡主要將自己學習和比賽時遇到的md5弱類型和強碰撞的題目從淺到深地梳理一下。

基本知識

php中有兩種比較的符號==與=====在進行比較的時候,如果比較一個數字和字符串或者比較涉及到數字內容的字符串,則字符串會被轉換為數值並且比較按照數值來進行。

===在進行比較的時候,會先判斷兩種字符串的類型是否相等,再比較。

==比較

測試代碼

 <?php
if (isset($_POST['a']) and isset($_POST['b']))
{
    if ($_POST['a'] != $_POST['b'])
    {
     if (md5($_POST['a']) == md5($_POST['b']))
      echo 'flag';
     else
      echo 'you are wrong';
 }
 else echo "請輸入不同的a,b值";
}

解法1

由於md5不能加密數組,在加密數組的時候會返回NULL

所以,我們可以傳入兩個數組

解放2

可以傳入兩個md5加密後是0e開頭的字符串,需要注意的地方是,這個以0e開頭的字符串只能是純數字,這樣php在進行科學計算法的時候才會將它轉化為0。可以查找以0e開頭md5加密相等的字符串,也可以自己編寫代碼,提供以下腳本。

<?php
for($a=1;$a<=1000000000;$a++){
   $md5 = md5($a);
   if(preg_match('/^0e\d+$/',$md5)){
      echo $a;
      echo "\n";
      echo $md5;
      echo "\n";
   }
}

s1502113478a
0e861580163291561247404381396064
  
s1885207154a
0e509367213418206700842008763514
  
s1836677006a
0e481036490867661113260034900752
  
s155964671a
0e342768416822451524974117254469
  
s1184209335a
0e072485820392773389523109082030
  

===比較
<?php
if (isset($_POST['a']) and isset($_POST['b']))
{
    if ($_POST['a'] != $_POST['b'])
    {
     if (md5($_POST['a']) === md5($_POST['b']))
      echo 'flag';
     else
      echo 'you are wrong';
 }
 else echo "請輸入不同的a,b值";
}
?>

解法1:

也可以傳入兩個數組,但不再適合傳入兩個0e開頭的字符串,因為===是md5的強碰撞,進行了嚴格的過濾。

解法2:

使用md5加密後兩個完全相等的兩個字符串來繞過過濾。

如何生成兩個不一樣的字符串,但是MD5是一樣的呢。參考如何用不同的數值構建一樣的MD5後,我們可以使用快速MD5碰撞生成器來構建兩個MD5一樣,但內容完全不一樣的字符串。

fastcoll_v1.0.0.5.exe.zip

構造

創建一個文本文件,寫入任意的文件內容,命名為ywj.txt (源文件)

運行fastcoll輸出以下參數。-p 是源文件,-o是輸出文件

fastcoll_v1.0.0.5.exe -p ywj.txt -o 1.txt 2.txt

測試

對生產的1.txt和2.txt文件進行測試

<?php 
function  readmyfile($path){
    $fh = fopen($path, "rb");
    $data = fread($fh, filesize($path));
    fclose($fh);
    return $data;
}
echo '二進位md5加密 '. md5( (readmyfile("1.txt")));
echo "</br>";
echo  'url編碼 '. urlencode(readmyfile("1.txt"));
echo "</br>";
echo '二進位md5加密 '.md5( (readmyfile("2.txt")));
echo "</br>";
echo  'url編碼 '.  urlencode(readmyfile("2.txt"));
echo "</br>";

二進位md5加密 8e4ef6c69a337c0de0208455ee69a416

url編碼 1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%A3njn%FD%1A%CB%3A%29Wr%02En%CE%89%9A%E3%8EF%F1%BE%E9%EE3%0E%82%2A%95%23%0D%FA%CE%1C%F2%C4P%C2%B7s%0F%C8t%F28%FAU%AD%2C%EB%1D%D8%D2%00%8C%3B%FCN%C9b4%DB%AC%17%A8%BF%3Fh%84i%F4%1E%B5Q%7B%FC%B9RuJ%60%B4%0D7%F9%F9%00%1E%C1%1B%16%C9M%2A%7D%B2%BBoW%02%7D%8F%7F%C0qT%D0%CF%3A%9DFH%F1%25%AC%DF%FA%C4G%27uW%CFNB%E7%EF%B0



二進位md5加密 8e4ef6c69a337c0de0208455ee69a416

url編碼 1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%A3njn%FD%1A%CB%3A%29Wr%02En%CE%89%9A%E3%8E%C6%F1%BE%E9%EE3%0E%82%2A%95%23%0D%FA%CE%1C%F2%C4P%C2%B7s%0F%C8t%F28zV%AD%2C%EB%1D%D8%D2%00%8C%3B%FCN%C9%E24%DB%AC%17%A8%BF%3Fh%84i%F4%1E%B5Q%7B%FC%B9RuJ%60%B4%0D%B7%F9%F9%00%1E%C1%1B%16%C9M%2A%7D%B2%BBoW%02%7D%8F%7F%C0qT%D0%CF%3A%1DFH%F1%25%AC%DF%FA%C4G%27uW%CF%CEB%E7%EF%B0

可以看到,1.txt和2.txt文件二進位md5加密後的結果完全相同。由於1.txt和2.txt文件中含有不可見字符,所以需要將其url編碼後使用。可以看到url編碼後的兩個字符串不完全相同,滿足我們輸入兩個不同參數的需要。

當題目限制不能傳入數組,只能傳入字符串時,如下例題,就只能採用解法2.

<?php
if((string)$_GET['a'] !== (string)$_GET['b'] && md5($_GET['a'])===md5($_GET['b'])){
 echo "you are right";
}
else {
 echo "you are wrong";
}

HECTF  ezphp

源碼

<?php 
error_reporting(0);
highlight_file(__file__);
include('flag.php'); 
$string_1 = $_GET['str1']; 
$string_2 = $_GET['str2']; 

if($_GET['param1']!==$_GET['param2']&&md5($_GET['param1'])===md5($_GET['param2'])){
        if(is_numeric($string_1)){ 
            $md5_1 = md5($string_1); 
            $md5_2 = md5($string_2); 
            if($md5_1 != $md5_2){ 
                $a = strtr($md5_1, 'cxhp', '0123'); 
                $b = strtr($md5_2, 'cxhp', '0123'); 
                if($a == $b){
                    echo $flag;
                }
            }  
            else {
               die("md5 is wrong"); 
            }
            } 
        else {
        die('str1 not number'); 
        }
    }

?>

首先查看一些strtr()函數的用法:

strtr() 函數轉換字符串中特定的字符。

觀察源碼,要求傳入四個參數,首先param1===param2,因為沒有別的限制,所以我們可以傳入兩個數組。對於是str1和str2,首先str1隻能是數字,且最後

又因為會將md5加密後的str1和str2中的cxhp替換成0123,也就是說c會被替換成0,所以一個ce開頭的字符串會被替換成0e開頭的字符串。

可以想到只要找到兩個md5加密後是ce開頭的字符串,或者一個md5加密後是ce開頭的字符串,一個md5加密後是0e開頭的字符串就可以繞過過濾。

構造腳本

這是一開始的腳本,返回值少,且執行速度慢。

<?php
for($a=1;$a<=1000000000;$a++){
   $md5 = md5($a);
   if(preg_match('/^ce\d+$/',$md5)){
      echo $a;
      echo "\n";
      echo $md5;
      echo "\n";
   }
}


這是進一步優化的腳本

<?php
for($a = 1; $a <= 100000000; $a++) {
   $md5 = strtr(md5($a),'cxhp', '0123');
   if(preg_match('/^0e\d+$/', $md5)) {
      echo $a;
      echo "\n";
      echo $md5;
      echo "\n";
   }
}
?>

實戰演練
<?php
function random() { 
    $a = rand(133,600)*78;
    $b = rand(18,195);
    return $a+$b;
}
$r = random();
    if((string)$_GET['a']==(string)md5($_GET['b'])){
        if($a.$r == $b) {
            print "Yes,you are right";
        }
        else {
            print "you are wrong";
        }
    }

?>

觀察代碼,有一個rondom方法,返回的是一個隨機數,在這道題中,不需要清楚返回的是什麼內容,我們只要知道返回的是一串數字就可以了。傳入兩個參數a和b,要求傳入的是字符串,b會經過md5加密。最後要讓$a.$r == $b。因為是弱類型比較,且只能傳入字符串,想要的是兩個0e開頭的字符串進行比較,前面我們已經知道,以0e開頭的字符串只能是純數字,這樣php在進行科學計算法的時候才會將它轉化為0。所以保證$a以0e開頭就可以了,因為$r是一串數字,所以$a.$r在php中還是可以被解析為0。因為$b是參數b經過md5加密而來,所以我們傳入md5加密後是0e開頭的字符串即可。

相關焦點

  • md5到md5破解的一些科普
    在密碼學的應用裡,說是單向函數,或者說單向變換,一種是這種多對一不可逆,還有一種是說逆工程會非常困難,舉個例子吧,假設f(x)=x^6-x-1,然後你知道f(1)=-1,在知道x=1和f的情況下計算f(1)是很簡單的,而知道f(x)=-1和f去求x卻是很困難的,這裡就不展開說了,大家有個大體的認識就可以了。
  • CTF中關於md5的一些總結
    $payload[$i];        getstr($payload, $sl, $slen);    }}//字符串長度從3到30,肯定找得到for ($i = 3; $i < 30; $i++) {    getstr($payload, '', $i);}案例6——強網杯2018——Web 籤到
  • MD5 簡介,及其在 Java 中的實現方式
    如百科介紹,MD5 具有如下特點:壓縮性:任意長度的原數據,其 MD5 值都是固定的,即 128 位;易計算:計算原數據的 MD5 值是一個比較容易的過程;抗修改:原數據的任意改動,所得到的 MD5 值都是迥然不同的;防碰撞
  • 淺談Swing和SWT比較
    淺談Swing和SWT比較 本文主要比較Swing和SWT,分別從組件體系,組件繪製,事件模型和包設計方面進行比較。AWT缺少剪貼板、列印支持、鍵盤導航等特性;AWT功能較弱,它甚至不包括彈出式菜單或滾動窗格等基本元素。此外,AWT體系結構還存在著其他一些嚴重的缺陷。
  • Python「強類型」or「弱類型」?90% 的人說不清
    作者 | Python3分鐘 來源 | python3m 靜態類型 vs 動態 程式語言強類型 vs 弱類型 程式語言1 類型檢查類型檢查是一個驗證和施加類型約束的過程,編譯器或解釋器通常在編譯或運行階段做類型檢查。例如,你不能拿一個string類型值除以浮點數。
  • Python 中 MD5 加密
    將數據(如漢字)運算為另一固定長度值,是雜湊算法的基礎原理,MD5 的前身有 MD2、MD3 和 MD4。MD5 的作用是讓大容量信息在用數字籤名軟體籤署私人密鑰前被"壓縮"成一種保密的格式(就是把一個任意長度的字節串變換成一定長的十六進位數字串)。除了 MD5 以外,其中比較有名的還有sha-1、RIPEMD 以及 Haval 等。
  • Python 中 MD5 哈希函數的實現
    可用作校驗和驗證數據完整性。它適用於非加密目的,例如確定分區資料庫中特定密鑰的分區。該哈希函數在Python的hashlib模塊中可用。它以字節序列作為輸入,並返回128位哈希值作為輸出。散列函數的主要用途是檢查數據完整性,但存在安全性問題。
  • 自閉娃:習慣養成要擅用新鮮強刺激和重複弱刺激
    刺激無處不在,自閉娃每天看到、聽到、接觸到的所有事物和感知,都是給大腦的刺激。由於強度的差異和重複出現的頻率差異,會給孩子留下不同的印記。刺激可以分為四種類型,分別是新鮮弱刺激、新鮮強刺激、重複強刺激、重複弱刺激。不同刺激,結果差異很大。
  • 61【Linux】一步一步學Linux——md5sum命令(61)
    命令概述md5sum - 計算檢驗MD5效驗碼md5sum命令採用MD5報文摘要算法(128位)計算和檢查文件的校驗和校驗時,根據已生成的md5來進行校驗。生成當前文件的md5,並和之前已經生成的md5進行對比,如果一致,則返回OK,否則返回錯誤信息 [deng@localhost test]$ md5sum -c d.md5  passwd: 確定 passwd1: 確定 passwd.md5:
  • 一種基於Md5算法的改進加密方法
    由於md5算法的使用不需要支付任何版權費用的,所以在一般的情況下,md5也不失為一種非常優秀的加密算法,被大量公司和個人廣泛使用。2004年8月17日的美國加州聖巴巴拉的國際密碼學會議(Crypto』2004)上,來自中國山東大學的王小雲教授做了破譯MD5、HAVAL-128、 MD4和RIPEMD算法的報告,公布了MD系列算法的破解結果,MD5破解工程權威網站(http://www.md5crk.com)也因此關閉,從此宣布MD5加密算法不再是一種安全的加密算法。
  • Java四種引用類型:強引用、軟引用、弱引用、虛引用
    :強引用、軟引用、弱引用、虛引用。強引用強引用是最普遍的一種引用,我們寫的代碼,99.9999%都是強引用:Object o = new Object();這種就是強引用了,是不是在代碼中隨處可見,最親切。 只要某個對象有強引用與之關聯,這個對象永遠不會被回收,即使內存不足,JVM寧願拋出OOM,也不會去回收。那麼什麼時候才可以被回收呢?
  • 淺談四大基本力:引力、電磁力、弱核力、強核力
    而萬有引力又是各個粒子之間的引力疊加而成的,這種引力非常弱,可以說是四種力中作用最弱的一種了。與此同時,量子力學認為,各個物質之間的引力可以當作為這兩個物體的粒子之間的引力子交換,實際上這個引力子是虛的,但確實創造了自然界的萬有引力,而實引力子則構成了大家所熟知的引力波。
  • CSharp如何運用MD5算法加密密碼?
    使用MD5必須要先 using System.Security.Cryptography源碼如下:MD5 md5 =newMD5CryptoServiceProvider();//創建MDL5對象byte[] data = System.Text.Encoding.Default.GetBytes(textBox3.Text);//將字符編碼成一個字節序列byte[] md5data = md5.ComputeHash(data);//計算data字節的哈希值
  • SIP RFC3261終於更新,Say Goodbye To MD5 digest
    SIP中的認證方式和HTTP對用戶的認證方式是一樣的(Digest Access Authentication)。這種方式使用在一般簡單的伺服器對終端之間的認證過程中。在SIP的帳號默認配置中,我們使用的是MD5 digest的方式來進行用戶的Authentication。但是,MD5存在碰撞不可靠的問題,因此多個RFC規範都需要更新來支持新的安全方式。
  • SAP ABAP和Java裡的弱引用(WeakReference)和軟引用(SoftReference)
    ,分別控制是否清除強引用變量lo_person,和是否用代碼調用ABAP垃圾回收器。下圖這個CRM增強工具Application Enhancement Tool(簡稱AET)工廠類的方法GGET_DATA_TYPE_HANDLER, 根據兩個輸入參數,欄位數據類型和欄位行為類型,返回對應的處理器實例(handler). 這些處理器實例化時需要從若干張資料庫表裡讀取數據並保存在內存裡,因此初始化過程需要花費一定的時間。
  • 電解質和非電解質 強電解質和弱電解質
    從樹狀分類這個角度上可以把化合物分為電解質和非電解質兩類。電解質可分為強電解質和弱電解質兩類。二、強電解質和弱電解質 比較項目強電解質弱電解質定義在水溶液中,完全電離的電解質在水溶液中,部分電離的電解質電離程度完全電離部分電離電解質在水溶液中存在形式
  • 淺談彈簧床墊、棕墊和乳膠床墊之間的差別?
    如今,隨著泰國旅遊的盛行,泰國的天然乳膠床墊引起很多人的關注,對比市面上成名較早的彈簧床墊和棕墊。天然乳膠床墊和彈簧床墊的區別有哪些?它有什麼優勢和前輩們競爭呢?PROOSEN帶大家一起了解下吧。淺談彈簧床墊、棕墊和乳膠床墊的區別一、材質間的差異對比彈簧床墊,顧名思義其床墊內部具有彈簧結構,材質好的彈簧種類有獨立筒和蜂巢式獨立筒兩種,支撐能力較強,軟硬程度不同品牌各不相同,軟的睡下去就容易陷下去,
  • md5校驗工具怎麼用
    如何使用md5校驗工具?1.下載Hash軟體。2.打開驗證工具進行瀏覽。3.有多個選項可供選擇。默認為全選。
  • 第五人格:屠夫到底是強還是弱?低階玩家說強,高階玩家卻說弱
    第五人格有一個問題很有爭議,那就是屠夫到底是強還是弱,現在這個版本到底是監管者陣營比較強勢還是求生者陣營比較強勢。其實對於這一個問題,不同玩家有不同的看法,甚至高階和低階玩家的感覺就有很大差別,高階玩家認為屠夫太弱了,低階玩家卻認為屠夫很強,需要削弱屠夫。其實一個問題本沒有定論,但是不同水平的玩家感受不同確實值得深思,為什麼同樣的角色不同的玩家會有不同的感受呢?屠夫到底是強還是弱呢?