MD5长度拓展攻击学习记录(附有两道例题和参考资料)

参考自:
https://www.jianshu.com/p/241e7

https://github.com/mstxq17/cryptograph-of-web/blob/master/%E6%B5%85%E8%B0%88MD5%E6%89%A9%E5%B1%95%E9%95%BF%E5%BA%A6%E6%94%BB%E5%87%BB.md

一、加密原理

这个不会,,,看上面两个参考吧

二、使用条件

  1. 知道salt的长度
  2. 知道任意一个由salt加密后的md5的值,并且知道没有加盐的明文
  3. 用户可以提交或者修改 md5 的值 通常可以burp抓包修改

三、MD5拓展攻击的目的

攻击场景:

  1. 假设我们实现文件下载 file=filename&hash=md5($key.filename)
    然后判断 hash 是都等于md5($key.filename),如果相等,就下载
    也就是说我们只要推出config.php的md5($key.‘config.php’)的hash
    那么就可以实现任意下载config.php的功能了
  2. 使用条件: 上面有

四、注意事项:

  1. 明确盐的长度,明文的值,该明文加盐后的md5的值
  2. 用hashpump。出来 md5 和 那个任意值。其中的填充字符,记得将 \x换成% 。这个好像是叫做url反编码,可能是都要进行一次urldecode解码的过程,所以我们才这样的吗?。不管了,记住怎么用先。
  3. 通常我们构造的任意值前面的明文 与 一直明文 是一样的,然后后面是 填充字符串,在后面就是 我们构造的任意的 balbalabla的 字符了。
  4. 注意点:secret的长度可能又混淆,
  5. 任意加的数据,很可能就是题目要检测的关键字。

五、例题练练手

1. 一道ctf例题,

看一下注释的代码审计。

这是我本地复现的。可以学习一下那些cookie的东西。什么cookie,session对我来说是我的薄弱点,,总是有点害怕。。。

源码贴出来,是为了便于大家便于进行本地复现。key的长度题目会告诉的。至于在那个地方告诉,还是要细心一点来发现的。

secret.php

<?php
$key="adam";
$flag="flag{you_tried_MD5}";

test.php:

<?php
include "secret.php";
@$username=(string)$_POST['username'];
function enc($text){
    
    
	global $key;
	return md5($key.$text);//注意,这个MD5长度攻击,盐要在明文的前面
}
if(enc($username) === $_COOKIE['verify']){
    
    
	if(is_numeric(strpos($username,"admin"))){
    
    //username中一定要又admin的字段
		die($flag);
	}
	else{
    
    
		die("you are not admin");
	}
}
else{
    
    //然后setcookie之后,guest的cookie我们也能在浏览器中看到
	setcookie("verify",enc("guest"),time()+60*60*25*7);//这里盐$key的长度暴露出来了,
	setcookie("len",strlen($key),time()+60*60*24*7);//还有这个长度我们也能够看到
}
show_source(__FILE__);

尝试着做了一下,很难受啊:

首先你传入的uername的参数值,经过加盐的md5之后要等与那个后面的cookie中的某个值(尽管这个值能够在网页中看到)。而且还有你原本输入的参数中又admin的字段。

本来就不知道盐是多少,然后你输入的参数加盐md5之后要等与一个特殊的md5的值,然后那个特殊的md5的值的参数是 guest 。但是你输入的参数必须包含 admin 的字段。这,,,难搞啊

然后就需要用到MD5长度拓展攻击了

MD5拓展攻击:
就是在不知道key的具体值的时候。如果我们知道了 key的长度 某个已知明文 以及MD5($key.已知明文)的值。我们就能够去推导出MD5($key.任意值)的MD5

注意,这里始终是 key 在前, 任意值 在后。
试着解题:
在这里插入图片描述
明文:guest
verfy = 91d7a4fc03bcd2bd9ec6369771f32c2d
len = 4
这个文章中的md5原理可知
key+guest的md5为91d7a4fc03bcd2bd9ec6369771f32c2d,它是由 key + ‘guest’ + 填充数据 再经过运算得来的。(可以看一下文章中的原理)

如果我们想在不知道 key 的情况下获得 key 加密之后的 md5 ,也就是 key + ‘guest’ +填充数组 + 'balbalbalablabl ’ 的md5值,就可以对 上面的

这是 使用说明
在这里插入图片描述

在这里插入图片描述记得将 \x 替换成为 %

在这里插入图片描述
现在再看这个是不是就好多了 key + ‘guest’ +填充数组 + 'balbalbalablabl ’ 的md5值
填充数据,就是md5本身的操作,然后 那些balabalablablabla就是 我们想要构造的值。

在这里插入图片描述

2. 又一道ctf例题:

例题来自:实验吧

# 井号注释,是我自己加的注释, // 斜杠注释时 题目自带的注释
<?php
<html>
<body>

<pre>
$flag = "XXXXXXXXXXXXXXXXXXXXXXX";
$secret = "XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!

$username = $_POST["username"];
$password = $_POST["password"];

if (!empty($_COOKIE["getmein"])) {
    
    
    if (urldecode($username) === "admin" && urldecode($password) != "admin") {
    
    #username是admin,password不能是admin
        if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
    
    
            # 出flag的条件是,md5(盐+我们输入的值)等于cookie的值,
            echo "Congratulations! You are a registered user.\n";
            die ("The flag is ". $flag);
        }
        else {
    
    
            die ("Your cookies don't match up! STOP HACKING THIS SITE.");
        }
    }
    else {
    
    
        die ("You are not an admin! LEAVE.");
    }
}
# cookie的sample-hash的键值就是一个md5. 知道这个明文了,知道md5的值了,知道盐的长度了。然后burp抓包可以改md5.所以可以md5长度攻击了
setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));

if (empty($_COOKIE["source"])) {
    
    
    setcookie("source", 0, time() + (60 * 60 * 24 * 7));
}
else {
    
    
    if ($_COOKIE["source"] != 0) {
    
    
        echo ""; // This source code is outputted here
    }
}
    </pre>
<h1>Admins Only!</h1>
<p>If you have the correct credentials, log in below. If not, please LEAVE.</p>
<form method="POST">
    Username: <input type="text" name="username"> <br>
    Password: <input type="password" name="password"> <br>
    <button type="submit">Submit</button>
</form>

</body>
</html>

有个PHP的 != 和 !== 的辨析:

!=:不等于(数值 ==!==:不恒等于(数值和类型 ===$a=2;     $b="2";   那么$a !== $b 成立。  $a != $b 不成立
两个等号的时 == 。后面的都为 真 :0==false  1==true  "sfdqwe"==true
三个等号=== ,后面都为假 :0===false  1===true  "sfdqwe"===true
同理 0!==false 为真 ,0!=false为假

分析可知:用户名必须为admin,密码不能为admin。且cookie的 getmian 的值需要和 md5(secret.urldocode(username.password))相等,才能够通过验证。

以下为有用信息:

  1. secret 也就是 密文 的长度为 15
  2. md5(secret.“adminadmin”)的哈希
  3. 用户名为 admin。
  4. 综上,就已知明文为adminadmin 哈希也知道了,长度为15+5 = 20 注意吧username的长度也算上。

整理一下我们知道的数据

  1. Serrect的长度为15,再加上第一个admin就是20。
  2. 哈希值为571580b26c65f306376d4f64e53cb5c7。
  3. data为第二个admin。
  4. add数据为任意。
    在这里插入图片描述
    得到password的扩展为
    admin\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00cck 对其进行反url编码,即用%替换\x。并把getmein写入cookie,值为e632fc1f589cbabfef8e847a1ceced90
    在这里插入图片描述

参考自:
https://blog.csdn.net/JBlock/article/details/78448143

猜你喜欢

转载自blog.csdn.net/Zero_Adam/article/details/113813258