summaryrefslogtreecommitdiffstats
path: root/solve/solve
blob: 3f2739ffd35ed283f29e72ab3e59abfe77bd9799 (plain) (blame)
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
#!/usr/bin/env python3

from pwn import *
from hashlib import md5
from ctypes import CDLL

import subprocess
import sys

# context.log_level = "DEBUG"

args = sys.argv[1:]
if args == []:
    args = ["nc", "localhost", "1024"]

libc = CDLL("libc.so.6")

def connect():
    io = process(args)
    io.readuntil(b"After ")
    leak = int(io.readline().split()[0])

    flips = ""
    for _ in range(5):
        io.sendline(b"H")
        io.readuntil(b"The coin lands on ")
        flips += io.readline().decode()[0]

    return io, leak, flips

def gen_key(seed, flips):
    libc.srand(seed)
    libc.rand()
    for _ in flips:
        libc.rand()
    key = flips
    value = libc.rand() & 0x7fff
    for _ in range(32):
        concat = (key + str(value) + "\n").encode()
        key = md5(concat).hexdigest() + "  -"
    return key

def test_seed(seed, leak, flips):
    libc.srand(seed)
    value = libc.rand() & 0x7fff
    if value != leak:
        return False
    nflips = ""
    for _ in flips:
        value = libc.rand() & 0x7fff
        nflips += 'H' if value % 2 == 1 else 'T'
    return flips == nflips

def main():
    while True:
        io, _, _ = connect()
        io.sendline(b"P")
        io.sendline(b"H")
        io.readuntil(b"The coin lands on")
        io.readline()
        if b"Fortune smiles upon you" in io.readline():
            io.readuntil(b"light is the flag part:")
            flag_suffix = io.readline().split(b"'")[1].decode()
            io.close()
            break
        io.close()

    while True:
        timestamp = int(time.time())
        io, leak, flips = connect()
        io.sendline(b"O")
        io.sendline(b"H")
        io.readuntil(b"The coin lands on ")
        flips += io.readline().decode()[0]
        if b"Fortune smiles upon you" in io.readline():
            io.readuntil(b"cipher:\n")
            flag_prefix_enc = b""
            while True:
                line = io.readline()
                if b"  " not in line:
                    break
                print(line)
                parts = line.decode().split("  ")
                hexline = (parts[1] + parts[2]).replace(" ", "")
                flag_prefix_enc += bytes.fromhex(hexline)
            print(flag_prefix_enc)
            io.close()
            break
        io.close()

    flag_prefix = None
    for offset in range(-2000000, 2000001):
        seed = timestamp + offset
        if test_seed(seed, leak, flips):
            key = gen_key(seed, flips)
            cmd = ["openssl", "enc", "-aes-256-cbc",
                   "-d", "-pass", f"pass:{key}"]
            out = subprocess.run(cmd, stdout=subprocess.PIPE,
                    input=flag_prefix_enc).stdout
            print(out)
            if b"CSCG" in out:
                flag_prefix = out.decode().strip()
                break
    assert(flag_prefix)

    print(flag_prefix + flag_suffix)

if __name__ == "__main__":
    main()