参考自:
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
一、加密原理
这个不会,,,看上面两个参考吧
二、使用条件
- 知道salt的长度
- 知道任意一个由salt加密后的md5的值,并且知道没有加盐的明文
- 用户可以提交或者修改 md5 的值 通常可以burp抓包修改
三、MD5拓展攻击的目的
攻击场景:
- 假设我们实现文件下载 file=filename&hash=md5($key.filename)
然后判断 hash 是都等于md5($key.filename),如果相等,就下载
也就是说我们只要推出config.php的md5($key.‘config.php’)的hash
那么就可以实现任意下载config.php的功能了 - 使用条件: 上面有
四、注意事项:
- 明确盐的长度,明文的值,该明文加盐后的md5的值
- 用hashpump。出来 md5 和 那个任意值。其中的填充字符,记得将 \x换成% 。这个好像是叫做url反编码,可能是都要进行一次urldecode解码的过程,所以我们才这样的吗?。不管了,记住怎么用先。
- 通常我们构造的任意值前面的明文 与 一直明文 是一样的,然后后面是 填充字符串,在后面就是 我们构造的任意的 balbalabla的 字符了。
- 注意点:secret的长度可能又混淆,
- 任意加的数据,很可能就是题目要检测的关键字。
五、例题练练手
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))相等,才能够通过验证。
以下为有用信息:
- secret 也就是 密文 的长度为 15
- md5(secret.“adminadmin”)的哈希
- 用户名为 admin。
- 综上,就已知明文为adminadmin 哈希也知道了,长度为15+5 = 20 注意吧username的长度也算上。
整理一下我们知道的数据
- Serrect的长度为15,再加上第一个admin就是20。
- 哈希值为571580b26c65f306376d4f64e53cb5c7。
- data为第二个admin。
- 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