$cat friday-13th.mdCryptoHacknite 2.0
Friday 13th
A flag with every character rotated 13 places. Lining it up against the known start of a flag shows how, and undoing it takes one line of Python.
$man friday-13th
What this one teaches:
- What a Caesar cipher and ROT13 are, and why applying ROT13 twice gives back the original.
- Using text you already know (here, the start of every flag) to work out how a cipher works.
- Rotating digits as well as letters, and what happens when you go past the end of 0 to 9.
Task description
Although this string looks a lot like the real solution, Marko made sure to rotate it properly, so you’ll still have to put in a bit of work to get it.
The original was in Croatian; this is my translation.
The string
The task gives one line of text:
PGS5354[407143800150]
It has the shape of a flag (seven characters, then 12 digits in square brackets) but the wrong characters. The task text says Marko “rotated” it, and the title is a date, Friday the 13th. Both point to the same idea.
Rotation ciphers
One of the oldest ways to scramble text is to shift every letter a fixed number of places along the alphabet. With a shift of 3, A becomes D, B becomes E, and so on. When you run off the end, you wrap around to the start, so X becomes A. This is called a Caesar cipher, after Julius Caesar, who is said to have used it.
A shift of 13 has its own name, ROT13 (short for “rotate by 13”). The alphabet has 26 letters, so shifting by 13 twice brings every letter back to where it started. That makes ROT13 its own reverse: the same operation scrambles and unscrambles.
Checking the guess
Every flag in this competition starts with CTF2021[, so we know what the first eight characters should be. Putting them side by side with the scrambled ones shows how far each was moved:
| Scrambled | Original | Shift |
|---|---|---|
P |
C |
13 letters |
G |
T |
13 letters (wrapping round the alphabet) |
S |
F |
13 letters |
5 |
2 |
3 digits |
3 |
0 |
3 digits |
5 |
2 |
3 digits |
4 |
1 |
3 digits |
The letters are plain ROT13. The digits look like a different shift, but they were rotated by 13 too. There are only ten digits, so 13 steps around 0 to 9 is one full lap plus 3. Rotating a digit by 13 is the same as moving it 3 places, with 7 becoming 0, 8 becoming 1 and 9 becoming 2.
Undoing it
To get the flag back, each digit inside the brackets moves 3 places the other way, wrapping below 0 back to 9:
| Scrambled | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| Original | 7 | 8 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Twelve digits is quick by hand with that table. In Python it’s one line, where % 10 handles the wrap-around:
print("".join(str((int(d) - 3) % 10) for d in "407143800150"))
The prefix doesn’t need decoding, since we already know it’s CTF2021. The 12 digits that come out go inside CTF2021[...], and that’s the flag.
$cat flag.txt reveal
CTF2021[174810577827]