浅谈md5弱类型比较和强碰撞

前言

在CTF中,md5的题目太常见了,虽然有很多这方面的文章,但相对来说比较零散,这里主要将自己学习和比赛时遇到的md5弱类型和强碰撞的题目从浅到深地梳理一下。

本文涉及知识点实操练习:浅谈md5弱类型比较和强碰撞 相关实验:Weekly CTF(本课程旨在提供一些CTF题目给对CTF感兴趣的朋友们,让大家通过这些题目学习到相关知识。)

基本知识

php中有两种比较的符号==与=====在进行比较的时候,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。

===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较。

0e开头且都是数字的字符串,弱类型比较都等于0。

==比较

测试代码

<?phpif (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加密相等的字符串,也可以自己编写代码,提供以下脚本。

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

s1885207154a0e509367213418206700842008763514

s1836677006a0e481036490867661113260034900752

s155964671a0e342768416822451524974117254469

s1184209335a0e072485820392773389523109082030

===比较

<?phpif (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%C·4P%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.

<?phpif((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只能是数字,且最后$a == $b,但md5_1 != md5_2,所以我们不能传入两个md5加密后以0e开头的字符串。

又因为会将md5加密后的str1和str2中的cxhp替换成0123,也就是说c会被替换成0,所以一个ce开头的字符串会被替换成0e开头的字符串。

可以想到只要找到两个md5加密后是ce开头的字符串,或者一个md5加密后是ce开头的字符串,一个md5加密后是0e开头的字符串就可以绕过过滤。

构造脚本

这是一开始的脚本,返回值少,且执行速度慢。

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

这是进一步优化的脚本

<?phpfor($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";   }}?>

实战演练

<?phpfunction 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开头的字符串即可。

(0)

相关推荐

  • 这些常见的PHP漏洞,如果你不知道,就别说自己是个攻城狮

    这些常见的PHP漏洞,如果你不知道,就别说自己是个攻城狮

  • PHP支付接口签名生成数据

    <?php //作者主页 https://www.woailunwen.com $pay_memberid = '商户号'; $pay_orderid = '订单号'; $pay_amount ...

  • PHP的Hash信息摘要扩展框架

    PHP的Hash信息摘要扩展框架 今天我们主要学习的是 PHP 中一些 Hash 散列加密相关的扩展函数的使用,而不是 Hash 算法,这种加密其实也只是一种更复杂一些的密钥算法,与 Hash 算法类 ...

  • 【MD教程】MD衣服制作

    57:20 [MD教程]MD衣服制作,Marvelous Designer衣服制作,MD布料建模基础 8412 6

  • PHP的Mhash扩展函数的学习

    PHP的Mhash扩展函数的学习 这次我们要学习的又是一个 Hash 加密扩展.不过这个扩展 Mhash 已经集成在了 Hash 扩展中.同时也需要注意的是,这个扩展已经不推荐使用了,我们应该直接使用 ...

  • 浅谈酒店弱电机房的管理和维护

    以下文章来源于大中华酒店工程师 作者:大中华酒店工程师 酒店网络机房维护管理或多或少都存在一些问题,网络故障频发,设备老旧影响工作,人员冗杂,工作安排不合理等等,而且网络机房的维护工作也具有很多难点, ...

  • 浅谈小区弱电系统维护发现的问题

    专业的电工电气领域自媒体,不容错过 欢迎转发朋友圈,欢迎文末留言 智能化楼宇中的安防监控管理系统属于弱电系统,主要功能是对建筑内部及周边安防情况进行自动监控,同时具备自动报警和一定的防御功能.在安防监 ...

  • 也浅谈下弱电箱到客厅一条网线的解决之道

    本内容来源于@什么值得买APP,观点仅代表作者本人 |作者:值友7646592903 不少家庭光纤入户到家里弱电箱,而大多情况弱电箱都比较狭小,弱电箱到客厅又只有一条网线,但是光猫出来是两条网线,it ...

  • 浅谈二板竞价弱转强的机会和买点(图解)

    最近看到一种手法,二板竞价弱转强,被游资做到极致,直接从试盘到大单顶死涨停,赚钱效应在惨淡的四月下旬行情里好到爆棚. 接触超短打板的时间比较短,真正试着打板买入也就正是从4月15开始的.或许是我见识少 ...

  • 浅谈二板竞价弱转强的机会和买点——只有也只能竞价打板(案例图解)

    最近看到一种手法,二板竞价弱转强,被游资做到极致,直接从试盘到大单顶死涨停,赚钱效应在惨淡的四月下旬行情里好到爆棚. 接触超短打板的时间比较短,真正试着打板买入也就正是从4月15开始的.或许是我见识少 ...

  • 浅谈演播文艺作品如何获得较强代入感

    代入,就是数学里面的代换,例如:式子A+B=C,当A=1.现在广泛使用的含义是:指在小说.影视作品或游戏中读者.观众或玩家产生一种自己代替了小说或游戏之中的人物而产生的一种身临其境的感觉.套用此定义, ...

  • 英国步战车数量比坦克多,浅谈英国唯一步战车,同类产品中最弱

    ▔▔▔▔▔ 根据相关查询,截止至2020年中旬,英国现役主战坦克数量仅有615辆,其中"挑战者"的数量有227辆,"勇士"的数量有388辆.然而根据英国现役团属 ...

  • 卫小国:浅谈强基校考中的不定方程求解

    卫小国:浅谈强基校考中的不定方程求解

  • 再谈日线弱转强模式

    日线弱转强 弱转强,是短线的精华模式之一,是市场情绪的教科书.核心就在于超预期,在分歧中走强,让持筹者安心,让抢筹者疯狂,从而享受高溢价. 正所谓,与人斗,其乐无穷,市场永远是变化的,人性也是最难捉摸 ...