Home BJDCTF2020 Easy MD5
Post
Cancel

BJDCTF2020 Easy MD5

访问靶机,初始页面如图所示:

image-20220915183338824.png

看上去像是SQL注入,尝试注入后并没有反应,F12查看源码,看到其中存在提示:Hint: select * from 'admin' where password=md5($pass,true)

因此需要找到使password=md5($pass, true)返回值为true的$pass。

md5函数的用法:

参数描述
string必需
raw可选,raw为true,16位二进制形式;raw为false,32位二进制形式
  

根据SQL注入的经验,只要md5的返回值为’xxx’ or ‘1xxxxx’(根据MySQL规则,只要以数字开头,返回值就为true,并且纯数字不需要使用引号),就可以使返回值为true。存在一个最常用的pass:ffifdyop,其对应的32位md5码为276f722736c95d99e921722cf9ed621c,转换为ASCII编码后为'or'6<trash>*(为乱码),(*Mysql将hex编码转换为ASCII处理*)因此输入ffifdyop后条件判断为true,跳转到新的页面:

image-20220915184639309.png

同样查看网页源代码,可以看到存在提示:

1
2
3
4
5
6
7
<!--
$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
    // wow, glzjin wants a girl friend.
-->

要求通过get方式上传a和b两个变量,要求a!=b并且md5(a) == md5(b)。PHP中==表示弱等于,在进行比较时,会先将两边的变量转换成相同的类型,而以0e开头的数字/字符会被视为科学计数法,无论e后跟随的字符是什么都会被视为0,因此只要传递两个md5码均为0e开头的字符串作为变量即可。有两个常用的QNKCDZO和s214587387a,作为参数构建payload:/levels91.php?a=QNKCDZO&b=s214587387a,进入下一关。

这一关给出的提示为:

1
2
3
4
5
6
7
8
9
<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    echo $flag;
}

与上一关不同的地方在于,这里使用了===,即强等于进行判断。上面提到的绕过弱等于的办法不适用于强等于,因此需要采用其他绕过办法。

PHP的md5函数存在这样一个特性,如果输出的参数为数组,那么会返回NULL,因此只要使用POST方法传递两个不同的数组,即可获得最后的flag。使用hackbar构造POST请求,得到最终的flag:

image-20220915185602957.png

REFERENCE

[BUUOJ记录] [BJDCTF2020]Easy MD5 - Ye’sBlog - 博客园 (cnblogs.com)

PHP弱类型hash比较缺陷 - Ye’sBlog - 博客园 (cnblogs.com)

BUUCTF BJDCTF2020 Easy MD5 详解 - junlebao - 博客园 (cnblogs.com)

This post is licensed under CC BY 4.0 by the author.