zwesty
Write-ups / Day 29 / Warmups
Day 29 · Thu, Oct 29 · Warmups

Rotten Base

Prey slaughtered

Layered blob decoding: ROT13 over Base64; the labelled 29-line Mastery blob

STTMClaude Homebase Both

Flags are shortened to their first 8 and last 4 characters because they're unique per team.

Challenge ID
warmups-day-29 (+ /time_trial, /mastery)
Solved
2026-10-29: all three modes CORRECT on the first submit, both timed modes ranked. Single 09:04:13.1 ET, Time Trial 09:04:20.7, Mastery 09:04:29.9: 17.3 s from the Single's start (09:04:12.6) to the Mastery CORRECT, 4 min 29.9 s after release. The lane started late because the solver worked the Metadata lane first
Player
Zwesty (solo), with Claude Code (Opus 5.5): our automated morning solver (a scheduled script on our Kali VM) solved all three modes on its own with our existing Warmups solver. No one worked this challenge by hand, and no code was changed

The challenge

"Sixty-four invited thirteen over. Things got scrambled."

answer_id Question Format
message "Decode the assigned blob completely. What exact answer slug does its final non-empty decoded line instruct you to submit?" pattern: "three lowercase words separated by hyphens, followed by a hyphen and a two-digit number; submit the slug only" (normalization trim)

The Time Trial asked the same. The Mastery asked it once per blob: 143 sets (set1.message … set143.message).

Reading the prompt: what it said we'd need

Clue What it pointed to What the solver did about it
"Sixty-four" Base64 Base64 is part of Day 1's peel, one of the solver's oldest steps
"thirteen" ROT13 (Day 2's layer, Half a Turn) ROT13 is one of the solver's moves too
"invited … over" One layer applied on top of the other Undo the outer layer first: ROT13, then Base64
"Things got scrambled." A letter rotation over Base64 text, so it no longer decodes as Base64 The blob looks like Base64 but isn't valid until it is rotated back
"Rotten Base" (title) ROT + Base Confirmed the reading

What was in the files

  • Single Solve: blob.txt, 148 bytes, one line beginning GzywMFO3o3We…. ROT13 turns it into Base64 (TmljZSB3b3Jr…), and that decodes to the usual sentence: "Nice work decoding this warmup! To solve, submit this exact answer to the Game Master:" plus the slug jovial-comet-nugget-31.
  • Time Trial: blob.txt, 144 bytes, the same template with a different slug, spry-piano-marble-41.
  • Mastery: warmups-day-29-mastery.zip, 402,218 bytes, 143 blobs (blob-01.txt … blob-143.txt). Each blob has 29 tab-labelled lines, 01 to 29, and line N is in Day N's layer (line 27 is Ook!, line 28 hex written backwards). Line 29 is ROT13 over Base64 (for example 29, a tab, then rP01Zj==).

So the Single and Time Trial were the whole sentence in two old layers; the Mastery was the event's history, one day per line.

Single Solve, Time Trial, and Mastery: the automated solver

All three CORRECT on the first submit, with no stop. The solver was still running the Day 27 Warmups chain. That chain carries the earlier days' layers, including a bounded search we pre-built on Day 16 over Day 1's peel (Base64 and friends), reversal, Atbash, and ROT13. ROT13 then Base64 is two moves of that search, so nothing new was needed. The solver's output doesn't say which branch of the chain answered.

The Mastery also passed without a day-29 strict layer. Our strict per-day layer list had no entry for Day 29 that morning; it was added on Day 30. The chain's older readings still found all 143 slugs.

Single Solve
started_at  09:04:12.6 ET   deadline none
answers     1   jovial-comet-nugget-31
start        669 ms
artifact     313 ms   (148 bytes)
solve          2 ms
submit      1249 ms
TOTAL       2234 ms   (submit +1,728 ms after started_at)
result      CORRECT   flag a8e70b6f…b70f   (09:04:13.1 ET)
Time Trial (ranked, fresh variant)
started_at  09:04:20.0 ET   deadline 09:04:50.0 (30 s clock)
answers     1   spry-piano-marble-41
start        724 ms
artifact     392 ms   (144 bytes)
solve          1 ms
submit       833 ms
TOTAL       1951 ms   (submit +1,323 ms after started_at)
result      CORRECT   flag fa0df9cf…7131   (09:04:20.7 ET)
Mastery (ranked, fresh variant)
started_at  09:04:27.0 ET   deadline 09:07:07.0 (2 min 40 s clock)
answers     143 sets
start        604 ms
artifact    1141 ms   (402,218 bytes)
solve       1483 ms
submit       745 ms
TOTAL       3973 ms   (submit +3,490 ms after started_at)
result      CORRECT   flag 039ab205…40cc   (09:04:29.9 ET)

Speed boards (final boards; time = server start to solve): - Time Trial: 11th of 63, 0.683 s (fastest 0.214 s). - Mastery: 21st of 44, 2.886 s (fastest 0.395 s).

Time to solve

All three modes went through on the first submit: the Single at 09:04:13.1 ET, the ranked Time Trial at 09:04:20.7, and the ranked Mastery at 09:04:29.9, 17.3 s after the Single's start and 4 min 29.9 s after release. Most of that wait was the solver finishing the Metadata lane first.

Takeaways

  • A "new" layer can be two old ones. ROT13 and Base64 were both in the chain since the first week, and the pre-built search already tries stacks of moves, so a combined layer needed no code.
  • The labelled Mastery still passed without a strict day-29 layer, but only because the older readings happened to cover it. The gap showed up on Day 30, when a new reading needed Days 28 and 29.
  • Solver order costs time. The solve took 17 s; most of the 4½ minutes to finish was waiting behind the Metadata lane.