pwn学习--collision

pwn-test-collision

本题来自https://pwnable.kr,是第二道题——collision。
  首先通过ssh连过去,有三个文件,一个可执行文件,一个C源文件,一个没有读权限的flag文件。尝试运行这个可执行文件,直接运行该程序,提示后面需要添加参数passcode,随便输入几个字符运行,得到提示需要输入20个字符,再输入20个字符,提示passcode错误。如图所示

来看一下源码,

由于我是一个学pwn的萌新,所以我把我遇到的问题作为相关知识记录了下来,如果基础比较好的朋友,可以直接跳过这部分,下面有题的原理。

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

其中,argc 是命令行参数的个数;
argv[] 为保存命令行参数的字符串指针,其中第0个参数是程序的全名,以后的参数为命令行后面跟的用户输入的参数,argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数argc。如图所示,

然后再来看看check_password()函数,这个函数的参数为一个指向字符的指针(char*),而在第一步这个指针进行了强制类型转换,转换成指向整数的指针(int*),并将ip指针指向p指针指向的位置。

我这里写了一个类似的函数,参数为“abcdefghijkl”(原题是20个字符,我这里为了说明,用的12个字符),可以看到我的p指针指向的地址为0xb52c45,指向的内容为“abcdefghijkl”,然后我用了一个for循环,输出q[i],i自增1,可以看到他将我的字符串一个字节一个字节的读出来了,因为char类型占一个字节,q指针又是指向char类型的,所以就会一个字节一个字节的读。

再来看这个图,ip为指向int类型的指针,int类型占四个字节,所以他会将我输入的12个字节的内容分成3组,同样以ip[i]的形式输出,会得到三个大整数,内存中字符串是以ascii码的形式存储的,并且是小端模式(不清楚的可以去百度查一下,这里我就不介绍了),所以abcd对应61,62,63,64,p被强制类型转换为(int)后程序会将这四个字节当成整数来处理,0x64636261=1684234849,所以就出现如图的三个大整数。

好了,言归正传,相关知识介绍完了,回到这个题,他有一个if语句判断你输入的参数是不是20个字节,如果是的话调用check_password()函数,将20个字节分成5组,每个组当成整数来处理,并求和,返回一个res,如果返回的结果与他定义的hashcode相等,就能得到flag。
给出的hashcode = 0x21DD09EC,十进制是568134124,无法被5整除,所以我们需要进行一次形式上的变换,0x4733E77 * 4 + 0x10101010 = 0x21DD09EC,形式不唯一,只要你让这5组数加起来为hashcode就可以,然后利用python直接写入内存

./col $(python -c "print '\x77\x3e\x73\x04' * 4 +'\x10' * 4")  

其中$() 的作用是括号内的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个$(),整个语句的意思是将参数’\x77\x3e\x73\x04\x77\x3e\x73\x04\x77\x3e\x73\x04\x77\x3e\x73\x04\x10\x10\x10\x10’直接写入到内存。

大家也可以看看DeelMind的视频,讲的比较细。本人是一个萌新,有什么写的不对的地方,还望指出与批评。

猜你喜欢

转载自blog.csdn.net/Casuall/article/details/88716826
pwn
今日推荐