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

Description

The most famous candy maker in town has developed a secret formula to make sensational and unique candies by just giving the name of the candy. He even added a pinch of randomness to his algorithm to make it even more interesting. As his trusted friend and security enthousiast he has asked you to test it for him. Can you find a bug?

Exploitation

#!/usr/bin/python3
from hashlib import sha512
from random import randint
from pwn import remote
import sys

class ahs512:
    def __init__(self, message):
        self.message = message
        self.key = self.generateKey()

    def generateKey(self):
        while True:
            key = randint(2, len(self.message) - 1)
            if len(self.message) % key == 0:
                break
        return key

    def transpose(self, message):
        transposed = [0 for _ in message]
        columns = len(message) // self.key
        for i, char in enumerate(message):
            row = i // columns
            col = i % columns
            transposed[col * self.key + row] = char
        return bytes(transposed)

    def rotate(self, message):
        return [((b >> 4) | (b << 3)) & 0xff for b in message]

    def hexdigest(self):
        transposed = self.transpose(self.message)
        rotated = self.rotate(transposed)
        return sha512(bytes(rotated)).hexdigest()

def main():
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <ip:port>")
        sys.exit(1)
    host, port = sys.argv[1].split(':')
    p = remote(host, int(port))
    p.recvuntil(b'Find a message that generate the same hash as this one: ')
    target = p.recvline().strip().decode()
    original_message = b"pumpkin_spice_latte!"
    modified_message = original_message.replace(b'_', b'\xdf')
    while True:
        p.sendlineafter(b'Enter your message: ', modified_message.hex().encode())
        p.recvline()
        answer = p.recvline()
        if b'Conditions not satisfied!' not in answer:
            break
    print(answer.decode().strip())
    p.close()

if __name__ == "__main__":
    main()

Summary

AHS512: reconstruct the PRNG state from the leak, replay it, and recover the flag.