地址: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构造的算法均对此类攻击显示出脆弱性。
如果一个应用程序是这样操作的:
- 准备了一个密文和一些数据构造成一个字符串里,并且使用了MD5之类的哈希函数生成了一个哈希值(也就是所谓的signature/签名)
- 让攻击者可以提交数据以及哈希值,虽然攻击者不知道密文
- 服务器把提交的数据跟密文构造成字符串,并经过哈希后判断是否等同于提交上来的哈希值
这个时候,该应用程序就易受长度扩展攻击,攻击者可以构造出{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
就可以通过了。
-------