brainrot

- 3 mins read

tamu2025 - rev Challenge: brainrot

Description

This challenge involves reverse engineering a custom “brain” simulation to extract a flag. The brain operates on a set of neurons and performs transformations using a combination of hashing, rotation, and matrix operations. The goal is to deduce the input that produces the required outputs.

Solution

The solution involves implementing the brain simulation in Python and using the Z3 solver to reverse the transformations. Below is the code and explanation:

Brain Class

import hashlib
from z3 import *

class Brain:
    def __init__(self, neurons):
        self.neurons = neurons
        self.thought_size = 10
        
    def brainstem(self):
        return hashlib.sha256(",".join(str(x) for x in sum(self.neurons, [])).encode()).hexdigest()
        
    def rot(self, data):
        for i in range(len(data)):
            self.neurons[(3 * i + 7) % self.thought_size][(9 * i + 3) % self.thought_size] ^= data[i]
            
    def think(self, data):
        thought = [0] * self.thought_size
        for i in range(self.thought_size):
            thought[i] = sum(self.neurons[i][j] * data[j] for j in range(self.thought_size))
        self.neurons[:-1] = self.neurons[1:]
        self.neurons[-1] = thought
        return thought

Initialization

The brain is initialized with the following neuron values:

healthy_brain = [
    [71, 101, 18, 37, 41, 69, 80, 28, 23, 48], 
    [35, 32, 44, 24, 27, 20, 34, 58, 24, 9], 
    [73, 29, 37, 94, 27, 58, 104, 65, 116, 44], 
    [26, 83, 77, 116, 9, 96, 111, 118, 52, 62], 
    [100, 15, 119, 53, 59, 34, 38, 68, 104, 110], 
    [51, 1, 54, 62, 56, 120, 4, 80, 60, 120], 
    [125, 92, 95, 98, 97, 110, 93, 33, 128, 93], 
    [70, 23, 123, 40, 75, 23, 104, 73, 52, 6], 
    [14, 11, 99, 16, 124, 52, 14, 73, 47, 66], 
    [128, 11, 49, 111, 64, 108, 14, 66, 128, 101]
]

The brainrot data is a reversed string:

brainrot = b"gnilretskdi ,coffee ,ymotobol ,amenic etulosba ,oihO ni ylno ,oihO ,pac eht ..."[::-1]

Solving for the Flag

The required thoughts for each chunk are provided:

required_thoughts = [
    [59477, 41138, 59835, 73146, 77483, 59302, 102788, 67692, 62102, 85259],
    [40039, 59831, 72802, 77436, 57296, 101868, 69319, 59980, 84518, 73579466],
    [59783, 73251, 76964, 58066, 101937, 68220, 59723, 85312, 73537261, 7793081533],
    [71678, 77955, 59011, 102453, 66381, 60215, 86367, 74176247, 9263142620, 982652150581],
]

Using Z3, we solve for each 10-byte chunk of the flag:

flag = bytearray(40)

for chunk_index in range(4):
    current_brain = Brain([row[:] for row in brain.neurons])
    solver = Solver()
    flag_chunk = [BitVec(f'flag_{chunk_index}_{i}', 8) for i in range(10)]
    
    for i in range(10):
        solver.add(flag_chunk[i] >= 32)
        solver.add(flag_chunk[i] <= 126)
    
    expected_thought = required_thoughts[chunk_index]
    thought = [0] * current_brain.thought_size
    
    for i in range(current_brain.thought_size):
        thought_expr = 0
        for j in range(current_brain.thought_size):
            thought_expr += current_brain.neurons[i][j] * flag_chunk[j]
        solver.add(thought_expr == expected_thought[i])
    
    if solver.check() == sat:
        model = solver.model()
        for i in range(10):
            flag[chunk_index * 10 + i] = model[flag_chunk[i]].as_long()
        brain.think([model[flag_chunk[i]].as_long() for i in range(10)])
    else:
        print(f"No solution found for chunk {chunk_index}")
        exit(1)

solved_flag = bytes(flag)
print(f"Found flag: {solved_flag.decode()}")

Verification

The solution is verified by reapplying the transformations:

brain = Brain([row[:] for row in healthy_brain])
brain.rot(brainrot)

failed_to_think = False
for i in range(0, len(solved_flag), 10):
    thought = brain.think(solved_flag[i:i + 10])
    if thought != required_thoughts[i//10]:
        failed_to_think = True
        print(f"Verification failed for chunk {i//10}")

if failed_to_think or brain.brainstem() != "4fe4bdc54342d22189d129d291d4fa23da12f22a45bca01e75a1f0e57588bf16":
    print("Solution is incorrect")
else:
    print("Solution verified! Flag is correct")

Flag

The extracted flag is:

gigem{whats_up_my_fellow_skibidi_sigmas}