Agni Pariksha

By Team Cryptonite · 3 min read

About the CTF: Pinaka CTF

An ancient painting of Sita's trial by fire has survived millennia... but it carries more than art. The ancients of Bharat were masters of hidden knowledge - from Vatsyayana's 64 arts of secret writing to the…

Agni Pariksha

**Pinaka CTF 2026** · Forensics · Team Cryptonite · All 44 Pinaka write-ups


Challenge

> An ancient painting of Sita's trial by fire has survived millennia... but it carries more than art.

>

> The ancients of Bharat were masters of hidden knowledge - from Vatsyayana's 64 arts of secret writing to the mathematical encoding systems of Sanskrit scholars. They hid truths within beauty, numbers within poetry, and secrets within fire.

>

> This painting holds a secret encoded using techniques from the golden age of Indian cryptography. No modern tool will simply hand you the answer - you must think like the ancients.

We're given one image, agni_pariksha.png (1400x1000 RGB, 2.3 MB). It's a painting of Sita at the fire with Rama on the other side.

Recon

First thing, exiftool. Most of the metadata is in Sanskrit, so I've put the translations next to each field:


exiftool agni_pariksha.png
...
Description  : || Agni Pariksha || - proof of Sita's purity
Author       : the ancient painter
Comment      : the secret is hidden in the Panchavati exile. search with binwalk.
Hint         : read it in a spiral, along the kundalini path. start from the fire-coil and go outward.
Software     : PINAKA CTF v3.0 - CyberHX
PNG Warning  : where there is fire, there is truth
Warning      : [minor] Trailer data after PNG IEND chunk

That's a lot of hints at once. There's data after IEND, the comment literally says binwalk, and the hint says the actual secret is read in a spiral starting from the fire. So it's steg.

The zip

binwalk finds a zip right after the PNG ends, at offset 0x232099 (684 bytes), with one file in it: agnikundalmantra.txt. I carved it out and it's password protected. The comment already gave the password away: Panchavati, so PANCHAVATI. The zip uses AES (method 99), so plain unzip just skips the file, but 7z opens it:


dd if=agni_pariksha.png of=hidden.zip bs=1 skip=2302105
7z x -pPANCHAVATI hidden.zip

The mantra

The text file is all Sanskrit again. The numbers are written in Bhutasankhya, where words stand for digits: sagara (ocean, as in the seven seas) = 7, shunya (void) = 0, indriya (the senses) = 5, agni (the fires) = 3, and bindu (dot) is the decimal point. Going line by line:


read it in a spiral, going outward from the centre of the fire like a kundalini

centre:   sagara-shunya-shunya, indriya-shunya-shunya   ->  x = 700, y = 500
growth:   agni-bindu-sagara pixels per turn             ->  3.7 px per turn
colour:   in red (position zero), in the lowest part    ->  red channel, LSB

hidden with mlecchita vikalpa, the Kamasutra's art of secret writing:
  A<->N, B<->O, ... M<->Z
  digits too: 0<->5, 1<->6, ... 4<->9

So: walk an Archimedean spiral out from (700, 500), growing 3.7 px every full turn, and read the LSB of the red channel at each pixel. The cipher at the end is ROT13 for letters and ROT5 for digits. Didn't expect the Kamasutra to show up in a CTF, but ok.

Reading the spiral

I stepped the angle by 0.5 rad, used r = 3.7 theta / (2pi), floored the coordinates, skipped anything off the image, and kept only the first visit to each pixel (the spiral hits the same pixel several times near the centre). Then I packed the bits MSB first:


from PIL import Image
import numpy as np, math

a = np.array(Image.open("agni_pariksha.png"))
R = a[:, :, 0] & 1
H, W = R.shape

t = np.arange(5000) * 0.5
r = 3.7 * t / (2 * math.pi)
x = np.floor(700 + r * np.cos(t)).astype(int)
y = np.floor(500 + r * np.sin(t)).astype(int)
m = (x >= 0) & (x < W) & (y >= 0) & (y < H)
x, y = x[m], y[m]
_, i = np.unique(y * W + x, return_index=True)
i = np.sort(i)

b = np.packbits(R[y[i], x[i]]).tobytes()
print(b[:40])

python3 x.py
b'\x00\x00\x00\x1eCVANXN{thcg9_y6c6_9ta6_f9gl9z}\x89\xf9\xa7\x8ai\x91'

The first 4 bytes are a big-endian length, 0x1e = 30, which is exactly the length of CVANXN{thcg9y6c69ta6_f9gl9z}. CVANXN is PINAKA in ROT13, so that confirms the cipher.

Decoding

ROT13 on the letters and ROT5 on the digits:


echo 'CVANXN{thcg9_y6c6_9ta6_f9gl9z}' | tr 'A-Za-z0-9' 'N-ZA-Mn-za-m5-90-4'
PINAKA{gupt4_l1p1_4gn1_s4ty4m}

Flag


PINAKA{gupt4_l1p1_4gn1_s4ty4m}

(gupta lipi, agni satyam: "secret script, fire is truth")

Summary

  1. exiftool shows trailer data after IEND, plus Sanskrit hints pointing at binwalk, Panchavati and a spiral read.
  2. binwalk finds an AES zip after IEND. The password is PANCHAVATI, and it holds agnikundalmantra.txt.
  3. The mantra encodes its numbers in Bhutasankhya: centre (700, 500), 3.7 px per turn, red channel LSB, and mlecchita vikalpa (ROT13 + ROT5).
  4. Read the red LSBs along the spiral to get a 4-byte length plus CVANXN{thcg9y6c69ta6_f9gl9z}, then undo ROT13/ROT5 for the flag.

Read this post on CyberHx →