RET2LIBC3做题
合理利用recvuntil和sendlineafter,可以和远程程序IO同步,减少BUG可能

解释上面这一行代码,意思是接收到"\n"这里,并且drop意思是丢弃接收到的这个\N,只保留签名接收的数据
同时cyclic可以快节省成本垃圾数据
打开PIE的程序,IDA显示的就是偏移地址,而非虚拟空间的地址了。
下面这行代码就是一个debug相当于。

One_gadget
one_gadget就是用来去查找动态链接库里execve("/bin/sh", rsp+0x70, environ)函数的地址的,专职。--one_gadget 下载 安装 与使用_gadget配置下载-CSDN博客
一个在libc中找可利用地方的工具,给的就是偏移量,但是需要看运气,因为还需要满足相应的条件,如下图。比如要esp指定地方是空之类,可以多尝试几次。

当
libc.so
被加载到内存中时,会被映射到一个特定的内存区域,这个区域的起始地址就是libc
的基址。而libc
中函数的真实地址则是在基址的基础上加上该函数在.so
文件中的偏移地址得到的。--豆包AI
如何理解,就是libc基址+so的偏移量=真实地址。
练习题巩固
理论题部分已经讲解完毕,接下来会进行习题讲解。
pwn0(ret2text)
基本上什么保护都没有,而且是ret2text。这个是64位,就是ebp偏移
recvline用于持续接收数据直至碰到换行符 \n
。
pwn1(ret2shellcode)

这马上反映出来绝对是ret2shellcode。
最后脚本就是如下所示

这是用\0x90也就是nop来填充,俩十六进制=一个字节。
pwn2(ret2libc)
一般思路,略了。
一个梗:0xdeedbeef一般填充返回地址
pwn2_x64(64位rop)

64位传参前6个通过寄存器来,后来的才压栈。参数不都压栈了,这就是区别了。
pwn3(ret2libc较难)
小技巧:ret2csu
在libc_csu_init函数这里,有一串连续大量控制寄存器的代码

而且不仅如此,在别的地方还有寄存器的赋值操作,让r开头的这些寄存器可以作为中间车站,间接控制其他更多的寄存器。而且是先执行上图的代码,接着就执行下图的代码。
但是需要注意只可以控制edi,也就是rdi的低32位。64位地址分为4字节和6字节,其中栈和动态链接库地址一般是6字节。我们可以灵活用IDA查看相应地址长度,有时候edi完全够用。

pwn3实战
题目给了libc,要泄露地址了。这道题目难点有俩,第一,并未给出libc的某函数真实地址。第二,没有bin/sh。解决办法除了自己ROP个gets(需要确保如bss段有个已知地址可以存放),也可以看看有没有某个符号含有sh(用linux的strings命令)。但这里必须保证sh后面存在截断符。
还有第三办法,直接在libc看看有没有/bin/sh,这道题就可以这样做。
这道题目有write函数,我们就可以考虑用ROP,把某个libc地址通过调用write,泄露出来。但是这个方法也不行了,动态链接,本身的gadget就很少

其实既然有动态链接,那么就可以栈溢出ret2libc执行write,这时候write已经被调用过一次(因为read函数在write后面)所以可以利用write泄露出来write的got表项。
具体怎么写,且听下回分解。