这题做的真的是久,莓办法,太菜了
进去看见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
}
}
看到了源代码就可以知道绕过条件了,username一定要是admin,password不能是admin,cookie要传一个getmein过去,然后这个getmein是由md5(secret,username,password)构造出来的,这里的secret不知道他的值是什么,只知道长度是15
那么问题来了,不知道secret的值怎么构造符合条件的getmein绕过,这里就涉及到哈希长度扩展攻击
我们传过去的字符串格式都是类似xxxxxxxxxxxxxxxadminadmin这样的,首先对他消息补位,满足字符位数%512==448,这里字符位数不足448,补够448就行了。
然后就是怎么补位了,首先后面加个1,然后一直加0,这里注意,下面的图片是十六进制的,二进制10000000就是十六进制的80好吧,因为是448bit,补到56byte就补完了,然后就是最开始的消息位数的补位,前面的字符是secret+admin+admin,一共25个字符,所以就是25*8=200 bit =c8 byte,所以第57位写上c8,再继续补到64byte,补完的图片是这样的
接下来就是计算信息摘要,大概原理就是有ABCD四个初始渐变量,还有上面的信息,每次都拿512bit的信息去计算,然后多次计算以后变量不停被覆盖,最后计算出的变量接在一起,再高低位互换得到最终的加密结果
顺便给出ABCD四个初始变量的值
A = 0x67542301;
B = 0xEFCDAB89;
C = 0x98BADCFE;
D = 0x10325476;
哈希长度扩展攻击
(可以看下这篇对它的解释https://github.com/iagox86/hash_extender
这里就是这道题最关键的了,我们不知道secret的值,但是它的位数,还有一个simple_hash,得到的哈希值就是最后一次摘要经过高低位互换的链变量,那么就是说,如果还有下一次的计算,用到的,就是现在的这个哈希值,先对现在的哈希值进行高低位互换,然后这题就可以构造一个前面为xxxxxxxxxxxxxxxadminadmin的大于64位的字符串,利用simple_hash,计算他的hash,就能做出来了。
没错,还是这张图,只是后面多了个fish,就是要构造的东西
这个时候,username=admin,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\x00fish
为什么少了前面的xxx和admin,因为原题是拼接了cookie和username嘛
但是还要再改一下,因为它会urldecode
所以最终的是
username=admin,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%00fish
然后hash怎么算呢
这里给出一个脚本
#include
#include
#include
int main(int argc, const char *argv[]){
int i;
unsigned char buffer[MD5_DIGEST_LENGTH];
MD5_CTX c;
MD5_Init(&c);
MD5_Update(&c,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",64);
c.A = htonl(0x571580b2);
c.B = htonl(0x6c65f306);
c.C = htonl(0x376d4f64);
c.D = htonl(0xe53cb5c7);
MD5_Update(&c,"fish",4);
MD5_Final(buffer,&c);
for(i=0; i<16; i++){
printf("%02x",buffer[i]);
}
printf("\n");
printf("here is a fish!\n");
return 0;
}
出来的结果
然后就是bp的抓包改包了
flag get√