HTB Dynastic writeup - Pez1181/CTF GitHub Wiki

🧠 Challenge: Dynastic


πŸ“¦ Challenge Type: Reverse Engineering

🧨 Vulnerability: Progressive Caesar Cipher (Trithemius Variant)

β›” Protection Bypassed: Obfuscated Alphabetic Shift with Positional Index


πŸ“– Description

We’re given a Python script that encrypts a message (the flag) and writes it to output.txt. The encryption shifts each letter forward in the alphabet by its position in the string. Non-letter characters are preserved. Our task is to reverse this process and extract the original flag.


πŸ” Recon

From the script:

def to_identity_map(a):
    return ord(a) - 0x41  # A-Z to 0-25

def from_identity_map(a):
    return chr(a % 26 + 0x41)  # 0-25 back to A-Z

def encrypt(m):
    c = ''
    for i in range(len(m)):
        ch = m[i]
        if not ch.isalpha():
            ech = ch
        else:
            chi = to_identity_map(ch)
            ech = from_identity_map(chi + i)
        c += ech
    return c

Each letter is converted to a number, shifted forward by +i, then converted back to a letter using modulo 26. This is effectively a Trithemius cipher.

The encrypted flag provided is:

DKH_GYG_AFIS_ADSAB_FVU_NNGTJISQEE_SAJDCR?!_QD_WI_MEKINEX_DA_SSYOYR_GOXRQF

πŸ”“ Decryption Strategy

We reverse the transformation:

  • For each character at position i in the ciphertext:
    • If it's alphabetic:
      • Convert to 0–25 index
      • Subtract 2 * i (since the net difference from original to encrypted is +i, and we’re decrypting an encrypted char = original + i)
      • Wrap with modulo 26
    • If not alphabetic, preserve it
  • Reconstruct the string
  • Wrap it in HTB{...}

πŸ§ͺ Decryption Script

def to_identity_map(a):
    return ord(a) - ord('A')

def from_identity_map(a):
    return chr(a % 26 + ord('A'))

def double_shift_decrypt_fixed(ciphertext):
    result = ''
    for i in range(len(ciphertext)):
        ch = ciphertext[i]
        if ch.isalpha():
            chi = to_identity_map(ch)
            shifted = chi - (2 * i)
            decrypted_char = from_identity_map(shifted)
            result += decrypted_char
        else:
            result += ch
    return result

correct_cipher = "DKH_GYG_AFIS_ADSAB_FVU_NNGTJISQEE_SAJDCR?!_QD_WI_MEKINEX_DA_SSYOYR_GOXRQF"
decrypted_message = double_shift_decrypt_fixed(correct_cipher)
print("HTB{" + decrypted_message + "}")

βœ… Output

HTB{F14g_n0t_C4e54r_Bu7_Cr4nk3d}

✍️ Final Notes

  • This encryption is a form of monoalphabetic progressive cipher β€” a direct nod to Trithemius, who generalized Caesar ciphers using variable shifts.
  • The trick was spotting that chi + i (encryption) + chi - i (decryption) meant a total difference of 2 * i between the original and encrypted characters β€” if you tracked i properly.
  • Classic trap: the index i includes all characters, even _, !, ?, etc. β€” not just letters.

🏁 Flag

HTB{F14g_n0t_C4e54r_Bu7_Cr4nk3d}

Mission complete. Encryption busted 🫑