Ret2syscall(超详细)

什么是系统调用?

系统调用(System Call)是操作系统提供给应用程序的接口,允许应用程序请求操作系统内核执行某些特权操作。由于操作系统内核运行在更高的特权级别(如x86架构中的内核态),普通应用程序(运行在用户态)无法直接访问硬件资源或执行某些敏感操作(如文件读写、进程管理、网络通信等)。因此,应用程序需要通过系统调用来请求内核完成这些操作。

我用自己的话说就是设置对应寄存器的值,达到调用系统函数的过程

下面是对应的系统调用表

Linux X86架构 32 64系统调用表_32位 syscall-CSDN博客https://blog.csdn.net/Nashi_Ko/article/details/120288385?ops_request_misc=%257B%2522request%255Fid%2522%253A%25228bc310d05bf3dd62541418a587f946b5%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=8bc310d05bf3dd62541418a587f946b5&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-1-120288385-null-null.142^v102^pc_search_result_base3&utm_term=x86%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E8%A1%A8&spm=1018.2226.3001.4187

所以我们要执行对应的系统调用,就要修改对应的寄存器的值


如何修改对应寄存器的值?

我们可以用kali中自带的ROPgadget

用法

ROPgadget --binary 文件名 --only 'pop|ret' |grep '寄存器名'
ROPgadget --binary 文件名 --only 'int'
ROPgadget --binary 文件名 --string '/bin/sh'

Ret2syscall(超详细)_第1张图片

 如何进行系统调用

这里来理解一下pop;ret这个指令

比如 pop eax;ret

将栈顶数据出栈给eax,并将下一个栈中数据作为返回地址

假如我们通过栈溢出将eip覆盖为pop eax的地址,当程序返回的时候就会执行pop eax,将’aaaa’放到eax中,然后执行ret指令,将’bbbb’放入eip寄存器中,然后会执行地址为’bbbb’处的指令,可以看到,bbbb处的指令为xxxx,当执行完xxxx后,继续执行ret指令,然后会返回到cccc指令处,执行xxxx。system函数的本质也是一条条汇编指令的组合,如果我们能找到多个xxxx,ret结构的指令,将其连接在一起,就可以达到执行system函数的效果。

像这样的指令就被成为gadget(以ret结尾的指令)

Ret2syscall(超详细)_第2张图片

比如要执行system("/bin/sh")

根据系统调用表中寄存器数据,我们要执行execve,要将eax设置为0b,设置ebx为"/bin/sh"字符串

所以我们就需要pop eax;ret和pop ebx;ret,然后将后两个ecx,edx设置为0

还有中断int 0x80,这5个地址

然后构造如下playload

payload = flat(['A' * 112, pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret, 0, 0, binsh, int_0x80])

 前面是造成栈溢出的效果,后面栈图看

Ret2syscall(超详细)_第3张图片

返回地址被覆盖后,eip指向pop eax;ret

0xb出栈给eax,(eax)=0xb

然后ret执行,eip指向pop edx;ret

0出栈给edx,(edx)=0

然后一直重复,直到设置完所有的寄存器

最后eip指向int 0x80

触发系统中断,然后根据寄存器的值,触发系统调用


例题

对应的列题没找到,不是结合pie就是结合canary,或者两个都有

但对于pie和canary的保护绕过我还没有深究,等学会了再来做题。

先插个飞雷神苦无

你可能感兴趣的:(服务器,算法,运维)