SEEDLab-缓冲区溢出2
SEEDLab-缓冲区溢出2
任务一
以下的程序有一个缓冲区溢出漏洞,我们的任务就是利用这个漏洞。注意需要打开地址随机化保护,利用jmp esp或者call esp(不要使用nop)。
1 | |
如图1所示,将漏洞程序进行编译,关闭栈保护,打开栈可执行。再设置Set-UID位,打开地址随机化。
观察代码,可以发现程序中存在可利用的全局变量someint,变量中存储了jmp
esp指令,同时程序中还打印了someint的地址,全局变量不受地址随机化的影响,因此可以利用。如图2、3、4,运行stackesp程序,得到someint的地址,同时使用gdb调试程序,获取返回地址在栈中的位置,计算得到返回地址在buffer+172的位置。
有了以上条件,可以构造程序输入badfile。如图5所示,首先用someint的地址覆盖bof()函数的返回地址,需要172字节的填充字符。在bof()函数执行完毕之后将会执行leave;
ret的操作,leave指令首先将ebp的值赋给esp,此时esp指向主调函数main()的栈底地址在栈中的位置,再执行一次pop指令,将esp指向的值赋给ebp,同时esp增加4。此时,ebp指向main()函数的栈底,esp指向bof()的返回地址。再执行ret指令,执行一次pop操作,将eip的值设置为返回地址,同时,esp再增加4,指向了返回地址所在位置-4的位置。
覆盖之后,在bof()函数执行结束之后,会执行jmp
esp的操作,从而从esp指向的位置继续执行,返回地址所在位置-4的位置被覆盖为shellcode,因此成功获取root
shell,如图6所示。
任务二
下面的程序有一个缓冲区溢出漏洞。编译该程序时,需要开启栈不可执行。
1 | |
观察漏洞程序,发现hmm()函数可以获得shell,同时程序中打印出了hmm()函数的地址。main()中使用函数指针调用good(),因此可以覆盖栈中的函数指针来调用hmm()函数。
如图7,编译代码并设置Set-UID位,运行程序得到hmm()的地址。再使用GDB进行调试。查看good()函数的地址,再在main()函数中设置断点查看栈中的情况,可以看到指向good()的函数指针距离buf36字节,如图8所示。由此可以构造输入,如图9所示,成功获得root
shell。