ret2syscall
ret2syscall
ROP原理:在栈缓冲区溢出的基础上,利用程序中已有的小片段 (gadgets:以ret为结尾的指令序列) 来改变某些寄存器或者变量的值,从而控制程序的执行流程
核心:利用了指令集中的 ret 指令,改变了指令流的执行顺序
核心指令:ROPgadget --binary 文件名 --only 'pop|ret'(三个空格!!!)
若筛选与指定寄存器(如eax)相关的:ROPgadget --binary 文件名 --only 'pop|ret' | grep 'eax'
关于系统调用:
是一种特殊的函数集合,允许应用程序访问和请求操作系统内核提供的服务(包括但不限于文件操作(如打开、读取、写入文件)、进程管理(如创建、终止进程)、内存管理、设备输入输出控制以及网络通信等)
linux调用系统调用的过程:
1.系统调用编号存到eax中
2.其他参数根据调用的具体需求放入ebx, ecx, edx, esi, edi等寄存器,以及栈上
3.发出中断请求(int 80h是一个软件中断指令,其作用是中断当前的程序执行流程,转而去执行中断处理程序)
4.操作系统内核接收到这个中断请求后,会检查eax寄存器以确定是哪个系统调用。然后,根据这个系统调用号,内核会在系统调用表中找到对应的处理函数并执行它。这个处理函数会访问或修改之前由应用程序放入寄存器和栈中的参数,并执行实际的操作,比如读写文件、创建进程等。
5.系统调用完成之后,其结果(如果有)通常会放入eax寄存器
execve()(用于加载并运行可执行文件)
基本语法
int execve(const char *pathname, char *const argv[], char *const envp[]);
参数说明:
pathname:一个指向要执行的程序文件路径(绝对/相对)的指针。
argv:一个指向字符指针数组的指针,代表传递给新程序的命令行参数。argv[0]通常是程序本身的名称,后续元素是具体的参数。数组以NULL结束。
envp:一个指向环境变量字符串数组的指针。每个环境变量字符串都是一个以等号分隔的键值对,如"VAR=value"。数组同样以NULL结尾。这些环境变量定义了新程序的执行环境,如PATH、USER等。如果传递NULL,新进程将继承调用者的环境变量。
(?)
本题思路:
1.通过系统调用execve("/bin/sh",NULL,NULL)
找到系统调用号存到eax中
execve()在64位系统中编号通常是59(0x3b),在32位系统中通常是11(0xb)
所以eax = 0xb
ebx = binsh_addr
ecx\edx参数都是零
2.找gadget
(1)eax
xyq@xyq-virtual-machine:~/Desktop$ ROPgadget --binary rop --only 'pop|ret'| grep 'eax'
得0x080bb196 : pop eax ; ret
同理可得0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret(一键到位)
(2)/bin/sh
ROPgadget --binary rop --string '/bin/sh'
0x080be408 : /bin/sh
(3)int 0x80
ROPgadget --binary rop --only 'int'
Gadgets information
============================================================
0x08049421 : int 0x80
3.gdb调试找偏移
偏移为112(包含ebp)
4.exp
最后:写的好丑TAT