neven@dimitri-dev:~$
cd ../hacknite-2021

$cat python.mdReversingHacknite 2.0

Python

A short Python script scrambles the flag with a reversible shift and base32. Running each step backwards restores it.

  • #python
  • #base32
  • #encoding

$man python

What this one teaches:

  • Reading a short program to list the exact steps it performs.
  • That each step (a shift, a join, base32) can be undone in reverse order.
  • What base32 and ASCII codes are.

Task description

Ema likes programming in Python. As a challenge, she’s giving you one of her compact scripts that turns your solution into a pile of meaningless characters. Reverse her process and find the flag.

The original was in Croatian; this is my translation.

The script

We get the script and its output:

import base64
flag = open("flag.txt").readline().rstrip()
result = ""
for i in range(len(flag)):
    result += chr(ord(flag[i]) + (i % len(flag)))
print(base64.b32encode(("|").join(list(result)).encode()))
# b'IN6FK7CIPQ2XYND4G56DO7DCPQ7HYQD4HZ6DW7CDPRAXYPT4IR6EI7CGPREXYS34OE'

Reversing anything like this is just doing its steps backwards. In order, it:

  1. reads the flag from a file;
  2. shifts each character: ord gives a character’s number (its ASCII code), it adds the position i, and chr turns the number back into a character. (i % len(flag) is just i here, since i never reaches the length.)
  3. puts a | between every character;
  4. encodes the whole thing with base32, a way of writing data using 32 plain characters.

Undoing it

We run those steps in reverse: base32-decode, drop the | separators, then shift each character back by its position.

encoded = "IN6FK7CIPQ2XYND4G56DO7DCPQ7HYQD4HZ6DW7CDPRAXYPT4IR6EI7CGPREXYS34OE"

import base64
joined = base64.b32decode(encoded).decode()   # e.g. "C|U|H|5|..."
shifted = joined.replace("|", "")              # drop the separators

flag = ""
for i in range(len(shifted)):
    flag += chr(ord(shifted[i]) - i)           # shift each one back
print(flag)

Base32 decoding gives C|U|H|5|4|7|7|b|.... Removing the | leaves the shifted characters, and subtracting each one’s position undoes step 2. The first few come out as C, then T, then F: the start of the flag. The rest follows, giving the full flag.

$cat flag.txt revealCTF2021[674074054578]

Written by Neven Marić. This writeup was written with the help of Claude Code (Anthropic).