$ cat writeup.md…
$ cat writeup.md…
broncoctf2026
Task: stripped ARM64 Mach-O 'Dog Simulator' game requiring a correct 6-day action routine. Solution: reverse the state machine, recover the fixed action order plus two Speak commands — a 12-letter FNV-1a preimage of 0x9f58d866 (via Z3) and the owner-name 'gremlin' from day-6 dialogue.
If you can survive 6 dog-days of walkies, tricks, and zoomies, you might uncover a secret (if you can stick to the right routine in the right order)!
A "Dog Simulator" game binary (stripped ARM64 Mach-O, PIE, dynamically linked to libSystem). Over 6 days you choose menu actions. State (Score, Bond, Energy, Mood) is tracked, and at the finale the owner either prints a garbled failure message or reveals the flag if the correct routine was followed in the correct order. Goal: recover the exact six-day routine.
The whole program logic lives in a single stripped function (0x100000500).
Actions deterministically update Score, Bond, Energy, and Mood
(calm/hyped/overstimulated/sleepy), and advance a four-stage combo counter. The
finale gates the flag on all of the following:
Score == 55, Bond > 24, Energy > 20, Mood != overstimulatedSpeak normalizes input to lowercase alphabetic and hashes it with FNV-1a
(offset basis 0x811c9dc5, prime 0x01000193):
0x9f58d866. Any 12-letter
lowercase preimage works — this explains the "the words feel the wrong length"
failure when a baseline (e.g. six barks) is used: the spoken letters never reach
the expected total length of 19.gremlin — the name the owner
calls the dog in the day-6 line "Last day of the week, little gremlin." This
triggers "(He seems to fixate on what your owner called you.)" and adds the
final 7 letters (12 + 7 = 19).Key finale strings recovered:
Owner: awww he said "%s" — success path prints the flagOwner: he tried to say it, but it came out garbled.Owner: the routine felt right, but the timing was off.Owner: he keeps trying to say something... but the words feel the wrong length.(Good boy! combo completed!)The correct six-day routine (menu sequence 2,3,1,6,4,6):
naxxzpxhhzgk (12-letter FNV-1a preimage of 0x9f58d866)gremlin (owner-name from day-6 dialogue)Recover the 12-letter preimage with Z3:
#!/usr/bin/env python3 from z3 import * c = [BitVec(f'c{i}', 32) for i in range(12)] s = Solver() for x in c: s.add(x >= ord('a'), x <= ord('z')) h = BitVecVal(0x811c9dc5, 32) # FNV-1a offset basis for x in c: h = (h ^ x) * 0x01000193 # FNV-1a prime s.add(h == 0x9f58d866) # target combo hash print(s.check()) m = s.model() print(''.join(chr(m[x].as_long()) for x in c)) # -> naxxzpxhhzgk
Drive the binary (press Enter to begin, then feed choices/commands):
printf '\n2\n3\n1\n6\nnaxxzpxhhzgk\n4\n6\ngremlin\n' | ./dog-sim-mac
Final state on success: Score=55 Bond=30 Energy=36 Mood=calm, Speak total
letters 19, and the finale prints:
Owner: awww he said "bronco{REDACTED}"
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar