实验吧之【让我进去】(哈希长度扩展攻击)

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

地址:http://ctf5.shiyanbar.com/web/kzhan.php

看看数据包和源代码

看见cookie有个source值很奇怪,把他改成1试一下就收到这段代码

$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") {
        if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
            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.");
    }
}
 
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
    }
}
$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") {
        if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
            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.");
    }
}
 
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
    }
}

看到了源代码就可以知道绕过条件了,username一定要是admin,password不能是admin,cookie要传一个getmein过去,然后这个getmein是由md5(secret,username,password)构造出来的,这里的secret不知道他的值是什么,只知道长度是15

那么问题来了,不知道secret的值怎么构造符合条件的getmein绕过,这里就涉及到哈希长度扩展攻击

关于哈希长度扩展攻击

https://www.freebuf.com/articles/web/69264.html

哈希长度扩展攻击(hash length extension attacks)是指针对某些允许包含额外信息的加密散列函数的攻击手段。该攻击适用于在消息与密钥的长度已知的情形下,所有采取了 H(密钥 ∥ 消息) 此类构造的散列函数。MD5和SHA-1等基于Merkle–Damgård构造的算法均对此类攻击显示出脆弱性。

如果一个应用程序是这样操作的:

  1. 准备了一个密文和一些数据构造成一个字符串里,并且使用了MD5之类的哈希函数生成了一个哈希值(也就是所谓的signature/签名)
  2. 让攻击者可以提交数据以及哈希值,虽然攻击者不知道密文
  3. 服务器把提交的数据跟密文构造成字符串,并经过哈希后判断是否等同于提交上来的哈希值

这个时候,该应用程序就易受长度扩展攻击,攻击者可以构造出{secret || data || attacker_controlled_data}的哈希值

我们传过去的字符串格式都是类似xxxxxxxxxxxxxxxadminadmin这样的,首先对他消息补位,满足字符位数%512==448,这里字符位数不足448,补够448就行了。

然后就是怎么补位了,首先后面加个1,然后一直加0,这里注意,下面的图片是十六进制的,二进制10000000就是十六进制的80好吧,因为是448bit,补到56byte就补完了,然后就是最开始的消息位数的补位,前面的字符是secret+admin+admin,一共25个字符,所以就是25*8=200 bit =c8 byte,所以第57位写上c8,再继续补到64byte,

这里有个现成的工具  hashdump

这里摘至pcat大佬的博客

https://www.cnblogs.com/pcat/p/5478509.html

HashDump

HashPump是一个借助于OpenSSL实现了针对多种散列函数的攻击的工具,支持针对MD5、CRC32、SHA1、SHA256和SHA512等长度扩展攻击。而MD2、SHA224和SHA384算法不受此攻击的影响,因其部分避免了对状态变量的输出,并不输出全部的状态变量。

(至于别的文章提到了MD4、RIPEMD-160、SHA-0、WHIRLPOOL等也可以构造长度扩展攻击,等以后再研究。)

git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install

至于想在python里实现hashpump,可以使用hashpumpy这个插件:

pip install hashpumpy

推荐在linux里使用,使用方法可以这样获取:

python
>>> import hashpumpy
>>> help(hashpumpy.hashpump)

这里回到我们的题目

在题目里可以得到:

md5($secret."adminadmin")的值为571580b26c65f306376d4f64e53cb5c7

稍微整理下我们已经知道的:

$secret是密文,长度为15,如果再算上后面第一个admin,长度就是20
而数据是admin
签名(哈希值)是571580b26c65f306376d4f64e53cb5c7

这时候我们使用HashPump,附加数据至少1位以上:

# hashpump
Input Signature: 571580b26c65f306376d4f64e53cb5c7
Input Data: admin
Input Key Length: 20
Input Data to Add: pcat

或者直接

hashpump -s 571580b26c65f306376d4f64e53cb5c7 -d admin -k 20 -a pcat

就会得到

3e67e8f0c05e1ad68020df30bbc505f5
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\x00pcat

第一个是新的签名,把它设置到cookies的getmein里。

第二个先把\x替换为%后,post提交

password=admin%80%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%c8%00%00%00%00%00%00%00pcat

就可以通过了。

-------

猜你喜欢

转载自blog.csdn.net/qq_17204441/article/details/93551516