https://app.hackthebox.com/challenges/43

Description

Brainy likes playing around with esoteric programming. He also likes math and has therefore encrypted his very secure password with a popular encryption algorithm. Claiming that his password cannot be retrieved now, he has sent the ciphertext to some of his friends. Can you prove to Brainy that his password can actually be recovered?

Exploitation

#!/usr/bin/python3
import json

def run_bf(code):
    mem = [0] * 30000
    dp = cp = 0
    output = ""
    brackets = {}
    stack = []
    for i, c in enumerate(code):
        if c == '[': stack.append(i)
        elif c == ']':
            start = stack.pop()
            brackets[start] = i
            brackets[i] = start
    while cp < len(code):
        c = code[cp]
        if c == '>': dp += 1
        elif c == '<': dp -= 1
        elif c == '+': mem[dp] = (mem[dp] + 1) % 256
        elif c == '-': mem[dp] = (mem[dp] - 1) % 256
        elif c == '.': output += chr(mem[dp])
        elif c == '[' and mem[dp] == 0: cp = brackets[cp]
        elif c == ']' and mem[dp] != 0: cp = brackets[cp]
        cp += 1
    return output

def decrypt_rsa_crt(c, p, q, dp, dq):
    def mod_inverse(a, m):
        def egcd(a, b):
            if a == 0: return b, 0, 1
            g, x, y = egcd(b % a, a)
            return g, y - (b // a) * x, x
        _, x, _ = egcd(a, m)
        return x % m
    m1 = pow(c, dp, p)
    m2 = pow(c, dq, q)
    qinv = mod_inverse(q, p)
    h = (qinv * (m1 - m2)) % p
    m = m2 + h * q
    return m

def main():
    with open('brainy.txt', 'r') as f:
        bf_code = f.read().strip()
    output = run_bf(bf_code)
    print("[+] Brainfuck decoded")
    params = {k: int(v) for k, v in 
             (pair.split(':') for pair in 
              output.strip('{}').split(','))}
    print("[+] Extracted RSA parameters")
    m = decrypt_rsa_crt(
        params['c'], params['p'], params['q'],
        params['dp'], params['dq']
    )
    print("[+] Decryption complete")
    try:
        hex_str = hex(m)[2:]
        if len(hex_str) % 2: hex_str = '0' + hex_str
        flag = bytes.fromhex(hex_str).decode()
        print("Flag:", flag)
    except:
        print("[-] Error decoding result")

if __name__ == "__main__":
    main()

Summary

Brainy’s Chyper: exploit the RSA structure, recover the missing secret, and decrypt the flag.