Skip to main content

Command Palette

Search for a command to run...

BronoCTF : No Laughing Matter

Updated
•2 min read•View as Markdown
BronoCTF : No Laughing Matter
Y
I write detailed writeups on HackTheBox, PicoCTF and other CTF challenges. Passionate about web exploitation, Active Directory attacks and ethical hacking

Challenge

A single file, aha.txt, containing nothing but space-separated 8-letter "words" made up of only two characters: A and H.

$ cat aha.txt
AHHAAAHA AHHHAAHA AHHAHHHH AHHAHHHA AHHAAAHH AHHAHHHH AHHHHAHH
AHAHAHAH AHAAAHHA AHAHAHAH AHAAHHHA AHAAHHHA AHAHHAAH AHAAHHAA
...

Spotting the pattern

Two things give this away immediately:

  1. Only two distinct symbols (A and H) → almost always means binary in disguise (0/1 mapped to two letters).
  2. Every "word" is exactly 8 characters long → 8 bits = 1 byte. That's the strongest tell — this is ASCII, one character per group.

So the plan is: pick a mapping (A → 0, H → 1, or vice versa), convert each 8-character group to a byte, and read it as ASCII.

Solving it

cipher = open("aha.txt").read().split()

decoded = ""
for byte in cipher:
    bits = byte.replace("A", "0").replace("H", "1")
    decoded += chr(int(bits, 2))

print(decoded)

int(bits, 2) parses the 8-character "0"/"1" string as a base-2 number, and chr() turns that number into its ASCII character. Running it against all 35 groups in the file reconstructs the flag directly — no trial and error needed once you notice the two-symbol/8-length pattern.

Flag

bronco{UFUNNYLMAOLOLXDIJBOLROFLHAHA}

Takeaways

  • Alphabet size is a huge clue. A ciphertext using only 2 distinct characters is very likely binary; 16 distinct characters often means hex; 64 (plus +, /, =) means base64.
  • Fixed-width grouping matters. 8-character groups screamed "one byte per group" before a single line of code was written — always check group lengths against 8 (bytes), 2 (hex pairs), 4 (base64 quads), etc.
  • Guessing the 0/1 mapping only has two possibilities (A=0,H=1 or A=1,H=0) — if the first guess produces garbage, just flip it and re-decode; it's a cheap check.
J

I enjoyed this because it shows that you don't always need a complicated approach to solve a challenge. Spending a minute looking for patterns can save a lot of time later.

One thing I'd probably try before writing any code is checking the frequency of the characters and seeing if the block size stays consistent throughout the file. Little observations like that often point you in the right direction before you even know what the encoding is.

Looking forward to seeing more challenges like this. They’re a fun way to practice thinking instead of just memorizing techniques.