栈溢出常见的利用方法:ret2text,ret2shellcode,ret2syscall,ret2libc等
先从最简单的ret2text开始,还是以上面的程序为例
确定偏移:
可以使用cyclic生成每4位都不重复字符串,将字符串传入gdb调试的程序中,观察eip的值,使用cyclic -l 查看偏移,也可用ida查看
得到偏移为13(十进制)
ida(有时候会不准)
s到ebp偏移9,程序为32位,再加4为13
也可以点进变量s(-9)到r(+4)偏移为13
main里面输出了一些字符然后调用的pwnme函数,明显pwnme函数存在栈溢出,偏移是13
随便点点ida里的函数列表发现,stack函数里存在system("/bin/sh")
只需要把返回地址覆盖成system("/bin/sh")的地址就行了,这块地址是0x08048518
poc
p32是小端传输,可以理解为打包,u32就是解包emmm
运行下确实拿到shell了,还是蛮有意思的
ret2shellcode,一般都是存入shellcode,再用vmmap查看存放shellcode的区域是否具有可执行权限(没权限可以尝试加),return到shellcode的对应的地址就行
ret2syscall,系统调用
32位应用程序调用系统调用的过程是:
1.把系统调用的编号存入 EAX;
2.把函数参数存入其它通用寄存器(EBX(第一个参数),ECX(第二个参数),EDX(第三个参数));
3.触发 0x80 号中断(int 0x80)。
网上有系统调用表,但是我访问域名已经过期了(寄),待解决。。。
一般调用execve("/bin/sh",NULL,NULL),调用号0xb,EBX传/bin/sh,ECX和EDX传0
ret2libc的流程,一般是先通过libc中的函数(__libc_start_main)的地址确认libc版本,system和/bin/sh在libc中的偏移是固定的。
system的地址=__libc_start_main的地址-__libc_start_main在libc中的偏移+system在libc中的偏移,/bin/sh也同理
使用LibcSearcher,可以通过libc.dump('system')、libc.dump('str_bin_sh')
来获得system和、/bin/sh偏移
工具:pwntools、ROPgadget、LibcSearcher、gdb