pwnable.kr 2-col

pwnable.kr 2-col

过程

首先建立链接 盲输入pw
pwnable.kr 2-col
然后还是一样的去查找文件 发现可读文件 cat出来
pwnable.kr 2-col
if(strlen(argv[1]) != 20){
printf(“passcode length should be 20 bytes\n”);
return 0;
}
从main函数中可以看出argv[]的长度不等于20时 会提示passcode的长度必须时20字节的

if(hashcode == check_password( argv[1] )){
system("/bin/cat flag");
return 0;
}
else
printf(“wrong passcode.\n”);
return 0;
}
下句if说hashcode如果等于给出的argv[1]时 系统输出flag 返回值0 否则输出passcode错误

unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
在语句中argv[]引用了password函数 看上去上面password函数里三个变量
for语句中说res为ip数组的和 ip数组的个数为5 而刚刚说到一共需要20个字节 则每个数组下应该就是4个字节
pwnable.kr 2-col
这时就会想到令前四个字节为\x00\x00\x00\x00 *4 + 0xEC09DD21 1 这样子进行输入 失败的原因从网上查询到的是
{\x09是HTab,输入会被阻断。}
所以自然而然的想去改变前四个字节换成\x01
16+\xe8\x05\xd9\x1d
然后就得到flag=daddy! I just managed to create a hash collision ????

↓看看大佬的描述:from 参商ck 博客园
{源码的逻辑是从终端运行程序,输入一个值,第一步检查其长度是否为20,然后把这个数据经过一个check_password函数变化之后进行比较,所以突破点在于check_password这个函数。
现在我们看看check_password这个函数:
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
函数功能是将char类型的指针,转为int类型的指针,然后在将其相加,返回这五个值的和。char类型的为1个字节,int类型指针所占为4个字节,所以这用户输入的20个字符串将被分为5个组,然后相加值为0x21DD09EC,所以我们只需要构造一个字符串,这个字符串由五个16进制数据拼接而成}