8月17日pwn学习

题目:Stack2

题目描述:

题目本来的描述是没有的,但是这个题又是一种全新形式的题目,然后writeup也不是太具体,要新学的和深入理解的地方很多,所以我做了很久很久。题目类型是不检查数组长度造成的的溢出。

题目分析:

1.checksec和file查看文件

 

 

 32位程序,用32位ida打开

2.ida反编译分析文件

 

 

 

 

 

 程序的结果是挺复杂的,但是概括下来的话,就是求平均数,这里虽然对输入的长度没有限制,但是没有开启栈溢出,通过使用scanf普通的栈溢出是不可行的。但是这里我们学到了新的知识,

 

 

 在这里,数组的长度是没有检查的,所以我们可以在离数组首地址任意长度的地方写入任意值,那么我就也就可以用这一点溢出操作,找到一个会return函数的地方,调用我们需要的函数。

左边的函数栏中首先有个hackhere

 

 

 但是参数并非我们想要得到的。但有system调用,我们也就可以用这个system

 

 

 在plt表中,system函数地址为0x08048450

还有要找到参数‘sh”,这里学到了一个新命令行命令ROPgadget --binary [文件名]  --string “查找字符”,就会在内存地址中找到有相应字符的地址,用来查找参数,如下图所示:看了很多writeup都没有把这一点说清楚,所以找了很久的资料,做详细说明。

 

 

找到了想要找的调用的系统函数,但现在的问题又出现了,数组的序号该是多少,也就是说,要找到一个return函数地址,用我们系统函数地址覆盖,也就是说,求数组的首地址到这个return函数的偏移

由于这里需要寻找的内存地址,所以又要用到新的工具了,gdb,当时花了很大的功夫下载下来,这次是第一次使用,适用于程序调试,能查看在运行每一步代码时,查看代码,寄存器和栈的状态

gdb调试的基本操作

我们在进行数组初始化时的代码地址打上断点,看寄存器的状态,查看把数据送去的第一个内存地址就是数组的首地址,

 

 这里就是在数组初始化时的代码地址,这里又要涉及到汇编一块的知识了

我就一步一步来解释一下在我们输入我们的数字后的每一步操作

0x080486C2:add         esp,0x10          ; 堆栈顶部指针加下移长度10h

0x080486C5:mov        eax,DWORD PTR [ebp-0x88]               ;赋值操作,将eax的值存入离栈底88h的地方,也就是变量var_88

0x080486CB:mov   ecx,eax    ;数值交换

0x080486CD:lea      edx,[ebp-0x70]         ;距栈底70h距离的变量为数组,唤起该处的内存地址并存入edx中,这里我们就已经知道了数组的首地址

0x080486D0:mov     eax,DWRD PTR [ebp-0x7c]         ;该变量为i,赋值到eax作为计数器

0x080486D3:add           eax,edx         ;eax加上eax也就是数组首地址。

0x080486D5:mov      BYTE PTR [eax],cl          ;cl是ECX的低位,将一开始存到ECX的输入,赋值到数组首地址

从上面的分析可知,0xffffd218为数组首地址,

另一边找ret的返回地址就方便了许多,由于该程序基本没有函数调用,只有主函数末尾有一个return函数了。

 

 在用gdb在0x080488F2处打断点看栈的状态即可

 

 ESP栈顶指针指的即使返回地址0xffffd29c

所以返回地址距离数组首地址0xffffd29c-0xffffd218=0x84,偏移为0x84

3.写exp

问题解决得都差不多了

 

 注意这里有一点,写地址的时候都是倒着写的。

4.得到结果

 

posted @ 2020-08-17 19:49  三木森林  阅读(125)  评论(0编辑  收藏  举报