Skip to main content

scheduler

Challenge

Imported from local notes.md.

Solution

Original Notes

scheduler

Challenge Summary

  • Given: a stripped ELF plus remote service at ctf.axiosiiitl.dev 1337.
  • Goal: make the internal 64-word scheduler buffer hash to the target checked by 0x4f8284.
  • Constraints: 1-4 tasks, payloads must be one of X77/Y88/Z99/W66, burst values must be distinct and positive, total burst budget must stay within 4000.

Initial Recon / Triage

  • Observations:
    • main is a state machine ending in 0x4083c1 then 0x4f8284.
    • Payload callbacks write constants into the shared buffer at 0x717060:
      • X77 -> 0x13371337
      • Y88 -> 0xdeadbeef
      • Z99 -> 0xcafebabe
      • W66 -> 0xbaadf00d
    • The hash core at 0x4f7f84 computes sum ^ xor over all 64 words and flips with 0x1337beef if adjacent changes exceed 0x2c.
    • 0x4083c1 rejects duplicate burst values, not duplicate priorities.
  • File identification:
    • Main binary: starting_files/scheduler_challenge
    • Key reversing artifacts: artifacts/check_r2.txt, artifacts/main_r2.txt, artifacts/state_funcs.txt
  • Entry points:
    • Scheduler launcher: 0x408355
    • Task spawn wrapper: 0x4f7255
    • Task picker: 0x4f734a

Hypotheses & Approach

  • Hypothesis 1: distinct priorities would produce a valid full buffer.
    • Result: false for the target. Distinct priorities produce long blocks, which keep the transition count too low.
  • Hypothesis 2: equal priorities with distinct burst values would round-robin tasks enough to exceed the transition threshold.
    • Result: true. Equal priorities are allowed, and the scheduler rotates among equal-priority runnable tasks.

Execution Steps (Reproducible)

Stage 1

Commands:

r2 -AA -q -c 'pdf @ main' starting_files/scheduler_challenge
gdb -q starting_files/scheduler_challenge \
-ex 'set pagination off' \
-ex 'disassemble 0x4f734a,0x4f7656' \
-ex 'disassemble 0x4f7f84,0x4f82fd' \
-ex quit

Results:

  • Recovered the scheduler model:
    • smallest numeric priority wins
    • equal priorities are scanned round-robin from the previously running task
    • each timer tick decrements the selected task's remaining burst
    • a finished 64-word buffer with 16 copies of each payload value has the correct base sum/xor, and only needs more than 44 transitions to hit the target hash.

Stage 2

Commands:

python3 artifacts/local_runner.py 0 300 0 450 0 600 0 750 60
printf '4\n1\n0\n300\n2\n0\n450\n3\n0\n600\n4\n0\n750\n' | nc ctf.axiosiiitl.dev 1337

Results:

  • Local run:
    • idx=64
    • changes=57
    • hash=0xe903d23a
    • target_match=True
  • Remote run returned:
    • IIITL{pr10r1ty_b005t_4ct1v4t3d_52194357123987345}

Artifacts Produced

  • artifacts/local_runner.py - runs a local candidate schedule, samples the final buffer, and computes the checker hash.
  • artifacts/native_sampler.py - lower-level live sampler used during local schedule discovery.
  • artifacts/check_r2.txt, artifacts/main_r2.txt, artifacts/state_funcs.txt - disassembly notes.

Flag

IIITL{pr10r1ty_b005t_4ct1v4t3d_52194357123987345}