← Back to Writeups
HTBEasyCryptography

Grandma's Secret

D3v0o0Nu119/2/20264 min read
#cryptography#htb#easy#adfgvx_decryption#columnar_transposition_undo#polybius_square_lookup

Grandma's Secret

Platform: Broncoctf2026 | Category: Cryptography | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-07-11 | Status: Solved Techniques: adfgvx_decryption, columnar_transposition_undo, polybius_square_lookup

Summary

Task: a handwritten JPEG letter names the ADFGVX cipher, draws its 6x6 Polybius square, and embeds a ciphertext plus the transposition keyword SUGAR. Solution: undo the columnar transposition (columns read in alphabetical key order), split the ADFGVX-pair stream, and look up each pair in the square to recover JELLYDONUT.

Recon

Port scan

bash
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: broncoctf2026 | ID: 20260711_broncoctf2026_grandmas_secret
  • Tags: classical_cipher, polybius_square, columnar_transposition, adfgvx, fractionating_cipher
  • Indicators: cipher named explicitly in prose (ADFGVX), 6x6 Polybius square drawn with headers A D F G V X, ciphertext uses only the letters A/D/F/G/V/X, keyword hidden in phrase 'alphabetically sorted SUGAR
  • Source: 20260711_broncoctf2026_grandmas_secret.md

Foothold

Vulnerability / Misconfiguration

  1. adfgvx_decryption
  2. columnar_transposition_undo
  3. polybius_square_lookup
bash
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

bash
sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
bash
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • adfgvx_decryption
  • columnar_transposition_undo
  • polybius_square_lookup
  • Tags: classical_cipher, polybius_square, columnar_transposition, adfgvx, fractionating_cipher

Original Writeup

<details><summary>Click to expand original content</summary>

Grandma's Secret — broncoctf2026

Description

Grandma wants to protect her wifi password. Can you find out what it is before grandpa does?

A single JPEG (Letter.jpeg) is provided — a handwritten letter from Grandma. The letter itself is the whole challenge: it names the cipher, draws the substitution square, embeds the ciphertext, and hides the transposition keyword. The goal is to recover the WiFi password and wrap it as bronco{...}.

Analysis

Recon (ruling out steganography)

The file is a JPEG, so stego is the obvious first guess — but it is a red herring:

  • exiftool — ordinary EXIF, nothing hidden.
  • binwalk — only JPEG/JFIF + TIFF (EXIF) signatures, no appended/embedded data.
  • strings — no flag, password, or steghide/steg markers.

Conclusion: nothing is hidden in the file. The puzzle is entirely the text of the letter — a classical ADFGVX cipher.

Key excerpts from the letter

  • "I used my favorite ADFGVX cipher from long ago for you my child."
  • "I know you always loved my alphabetically sorted SUGAR filled treats."
  • "Especially GVXX FVXV AFXF XVGA DAFF. Have fun surfing the Web!"

So the letter hands you everything:

  • Cipher name: ADFGVX.
  • Substitution table: the 6×6 Polybius square drawn on the page (row/column headers A D F G V X).
  • Ciphertext: GVXXFVXVAFXFXVGADAFF (20 chars — only A/D/F/G/V/X, the ADFGVX signature).
  • Transposition keyword: SUGAR (in "alphabetically sorted SUGAR").

The Polybius square

    A D F G V X
A   B 3 M R L I
D   A 6 F 0 8 2
F   C 7 S E U H
G   Z 9 D X K V
V   1 Q Y W 5 P
X   N J T 4 G O

(The 0 cell is drawn as a slashed-zero glyph ø.)

How ADFGVX works

ADFGVX is a fractionating cipher, encryption in two stages:

  1. Substitution — each plaintext character maps via the 6×6 Polybius square to a pair of the six letters A/D/F/G/V/X (its row header + column header).
  2. Columnar transposition — the resulting pair-stream is written under a keyword and the columns are read out in alphabetical order of the keyword letters.

Decryption reverses this: undo the transposition, then look up each letter pair as (row, col) in the square.

Solution

  • Ciphertext (transposition output): GVXXFVXVAFXFXVGADAFF — 20 chars.
  • Keyword SUGAR, length 5 → 20 / 5 = 4 rows.
  • Alphabetical order of S U G A R gives column read order A(3) G(2) R(4) S(0) U(1), i.e. index order [3, 2, 4, 0, 1].
  • Refilling the columns in that alphabetical order and reading row-by-row reconstructs the pre-transposition ADFGVX-pair stream: XDFGAVAVVFGFXXXAFVXF.
  • Splitting into pairs and looking up (row, col) in the square yields JELLYDONUT — which fits Grandma's "sugar filled treats" theme.
python
#!/usr/bin/env python3
# Solve: undo ADFGVX columnar transposition, then Polybius-square lookup.

ct  = 'GVXXFVXVAFXFXVGADAFF'
key = 'SUGAR'

# Column read order = alphabetical order of keyword letters -> [3,2,4,0,1]
order = sorted(range(len(key)), key=lambda i: key[i])

n = len(ct) // len(key)          # 4 rows per column
cols = [''] * len(key)
p = 0
for i in order:                  # ciphertext was read out in alphabetical column order
    cols[i] = ct[p:p+n]
    p += n

# Read the grid row-by-row to recover the ADFGVX pair-stream
stream = ''.join(cols[c][r] for r in range(n) for c in range(len(key)))
# stream == 'XDFGAVAVVFGFXXXAFVXF'

labels = 'ADFGVX'
grid = [list('B3MRLI'),
        list('A6F082'),
        list('C7SEUH'),
        list('Z9DXKV'),
        list('1QYW5P'),
        list('NJT4GO')]

pt = ''.join(grid[labels.index(stream[i])][labels.index(stream[i+1])]
             for i in range(0, len(stream), 2))
print(pt)                        # JELLYDONUT
print("bronco{%s}" % pt)         # bronco{REDACTED}
</details>

signed by XESXOR