Let's do pwnable.kr

pwnable.kr collision

2018-05-29  本文已影响29人  CodeRambler

今天咱们来继续玩 pwnable.kr

pwnable.kr collision

image

同样的,我们远程连接上服务器,然后查看一下当前目录中的文件。


$ ls

col  col.c  flag

和第一题一样,这里我们直接查看源代码。


$ cat col.c

#include 

#include 

unsigned long hashcode = 0x21DD09EC;

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;

}

int main(int argc, char* argv[]){

if(argc<2){

printf("usage : %s [passcode]\n", argv[0]);

return 0;

}

if(strlen(argv[1]) != 20){

printf("passcode length should be 20 bytes\n");

return 0;

}

if(hashcode == check_password( argv[1] )){

system("/bin/cat flag");

return 0;

}

else

printf("wrong passcode.\n");

return 0;

}

这题比较简单,只需传一个长度为 20 字符串使得字符串经过强制类型转换后的和等于 hashcode 即可。

简单谈一下碰撞(collision)的概念:不同的字符串经过一系列处理得到同一结果串。举个例子:一个数经过加号规则处理得到一个等式,如 3 = 1+1+1 也可以得到 3 = 0+1+2,这就是碰撞原理。(读者可以自己去百度一下 hash 碰撞,前面的解释为个人的见解!)

说一下强制类型转换


sizeof(int) = 4;

sizeof(char) = 1;

所以,char * 转 int *的时候需要循环五次,懂了吧?什么不懂?好吧,咱们继续解释一下。

char hashcode[20]; // 一个大小为20的char型数组

char * p = hashcode; // 一个指向 大小为20的char型数组的首地址 的 指针

上面代码的意思,一个指针 p 指向一个数组,数组中的每一个元素都是 char 类型(其实我想说的是,要是你不懂指针你就看成数组吧)。系统在声明变量的时候会为其开辟相应大小的内存空间,这里 char hashcode[20] 就是为其开辟一个 20 * sizeof(char) = 20 大小的空间。而 sizeof(int) = 4,所以同样的 20 个字节的大小空间只需要 5 * sizeof(int) ,这就是为什么后面循环的时候循环了五次的原因。

下面我们来构造一下等式:

0x21DD09EC = (0x21DD09EC - 0x010101014) + 0x010101014

下面是利用 python 的解题步骤:


$ ls

col  col.c  flag

$ python

Python 2.7.12 (default, Jul  1 2016, 15:12:24)

[GCC 5.4.0 20160609] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> hex(0x21DD09EC - 0x01010101*4)

'0x1dd905e8'

>>>

$ ./col $(python -c "print '\xe8\x05\xd9\x1d'+'\x01'*16")

daddy! I just managed to create a hash collision :)

最终得到 flag: daddy! I just managed to create a hash collision :)

上一篇下一篇

猜你喜欢

热点阅读