Dog Simulator
Dog Simulator
Platform: Broncoctf2026 | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-07-11 | Status: Solved Techniques: fnv1a_preimage_z3, macho_arm64_reversing, state_machine_recovery, string_analysis
Summary
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.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
broncoctf2026| ID:20260711_broncoctf2026_dog_simulator - Tags: state_machine, fnv1a, arm64, stripped_binary, macho, hash_preimage
- Indicators: stripped ARM64 Mach-O game/simulator, fixed routine in the right order, FNV-1a offset 0x811c9dc5 prime 0x01000193, wrong length' failure message, owner-name echoed in dialogue
- Source:
20260711_broncoctf2026_dog_simulator.md
Foothold
Vulnerability / Misconfiguration
- Fnv1a_preimage_z3
- Macho_arm64_reversing
- State_machine_recovery
- String_analysis
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- fnv1a_preimage_z3
- macho_arm64_reversing
- state_machine_recovery
- string_analysis
- Tags: state_machine, fnv1a, arm64, stripped_binary, macho, hash_preimage
Original Writeup
<details><summary>Click to expand original content</summary>Description
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.
Analysis
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:
- exactly one Bark, one Fetch, one Sit, one Eat; zero Zoomies; two Speak actions
- final
Score == 55,Bond > 24,Energy > 20,Mood != overstimulated - combo state reaches 4 (right actions in the right order)
- total alphabetic Speak letters == 19
- two FNV-1a hash constants must match (combo hash + transcript hash)
Speak normalizes input to lowercase alphabetic and hashes it with FNV-1a
(offset basis 0x811c9dc5, prime 0x01000193):
- The first Speak (at combo state 3) must hash to
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. - The second Speak must normalize exactly to
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!)
Solution
The correct six-day routine (menu sequence 2,3,1,6,4,6):
- Fetch
- Sit
- Bark
- Speak:
naxxzpxhhzgk(12-letter FNV-1a preimage of0x9f58d866) - Eat
- Speak:
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}"
</details>
Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR