Skip to main content0xAdham

Command Palette

Search for a command to run...

BYUCTF: Angr Management

Written by
Avatar of 0xAdham
0xAdham
Published on
--
BYUCTF: Angr Management

Platform: BYUCTF Challenge: Angr Management Category: Reversing Difficulty: Medium

Flag

byuctf{g3t_w1th_th3_c0ntr01_fl0w}

Target

<remote-host>:1368. Remote serves the real flag; local angr_management_test ships a dummy flag (byuctf{test_flag}) so you can develop offline.

  • ELF 64-bit PIE, x86-64, not stripped, pwn.red/jail (JAIL_TIME=900).
  • Prompt: "I built a maze using goto statements! Navigate through it successfully to get the flag." The name baits you into reaching for angr, which is the slow path here.

Recon

Functions: get_input, main (huge: 0x13170xee14, ~56 KB, the maze), flush_buf.

get_input (0x1270):

So each input is a number (0 to 9999). Running it:

main is 624 repeated "room" blocks. Per-room pattern:

It's a directed graph: each room prints its id, reads a number, and that number selects which room you jump to. Wrong number → exit. Tower of gotos = a maze with one or two exits per room.

Win room = room 0x270 (624) at 0xede5: no get_input, just puts(flag); return:

Why not angr

The challenge name screams symbolic execution, but driving angr through 72 chained fgets/strtol rounds (ASCII→int modeling, deep state) is slow and fiddly. The structure is a static, fully-recoverable CFG: every edge is a literal cmp $immjmp addr. So just parse the graph from the disassembly and BFS. Exact, instant, no SMT.

Solution

Dump disassembly, parse rooms + edges, BFS room 0 → room 624.

Verify locally then replay on the remote:

Path = 72 moves: 256 423 495 307 39 250 391 119 105 499 123 104 536 257 608 253 74 365 543 300 571 506 595 192 383 112 17 556 93 318 114 276 18 216 449 414 124 503 71 407 78 285 481 66 381 531 82 337 600 86 230 327 472 393 348 331 14 207 402 548 528 168 530 490 378 408 518 202 87 342 329 624

Local run ends Arrived at 624 / byuctf{test_flag}; remote gives the real flag.

Takeaways

  • Read the structure before reaching for the heavy tool. A "maze of gotos" with literal cmp immjmp edges is a static CFG. Recover it directly. angr is for when constraints aren't trivially readable; here every edge is a constant.
  • Anchor the parse on a stable signal (the # f019 "Arrived at %d" format ref) to reliably segment 624 near-identical blocks.
  • The flag is the lesson: g3t_w1th_th3_c0ntr01_fl0w. Control-flow recovery beats brute symbolic execution.
  • Dev against the dummy-flag local binary; only the final moves.txt replay needs the network.

0xAdham

Edit on GitHub
Last updated: --