Skip to main content

HackTheBox Challenge sekur julius (Crypto)

Edwin Tok | Shiro
Author
Edwin Tok | Shiro
「 ✦ OwO ✦ 」

This challenge has a 1337-byte “secure” key applied to a Caesar cipher. Sounds scary, but there’s a catch…

$ cat source.py
from random import choices
import os

def julius_encrypt(msg, shift):
    ct = ''
    for p in msg:
        if p == ' ':
            ct += '0'
        elif not ord('A') <= ord(p) <= ord('Z'):
            ct += p
        else:
            o = ord(p) - 65
            ct += chr(65 + (o + shift) % 26)
    return ct

def encrypt(msg, key):
    for shift in key:
        msg = julius_encrypt(msg, shift)
    return msg

msg = open('secret.txt').read().upper()
secure_key = os.urandom(1337)

with open('output.txt', 'w') as f:
    f.write(encrypt(msg, secure_key))
    
$ cat output.txt
JRYPBZR0GB0UNPXGUROBB0GJBGUBHFNAQGJRAGLSBHE!0GUVF0VF0N0CEBBS0BS0PBAPRCG0GB0CEBIR0LBH0GUNG0GUR0PNRFNE0PVCURE0VF0VAFRPHER0AB0ZNGGRE0UBJ0ZNAL0GVZRF0LBH0NCCYL0VG.0GUR0FRPHEVGL0BS0N0GUBHFNAQ0QVFGVAPG0FUVSGF0VF0RIRAGHNYYL0GUR0FNZR0NF0GUNG0BS0N0FVATYR0FUVSG.0RABHTU0ZHZOYVAT,0GNXR0LBHE0SYNT0NAQ0RAWBL0GUR0ERFG0BS0GUR0PBAGRFG.0ZNXR0FHER0LBH0JENC0GUR0SBYYBJVAT0GRKG0JVGU0GUR0UGO0SYNT0SBEZNG0GURRSSRPGVIRXRLFCNPRBSPNRFNEQRCRAQFBAGURFVMRBSGURNYCUNORG.

The thing about Caesar cipher is that it doesn’t matter how many times you apply it - mathematically, it all reduces to a single shift value. Each shift is just adding a number mod 26, so:

((A + s1) + s2 + ... + s1337) mod 26 = (A + S) mod 26

All those 1337 shifts? They just add up to one final shift value between 0-25. So we can just brute force all 26 possibilities:

$ cat solve.py
#!/usr/bin/python3
def julius_decrypt(ct, shift):
    pt = ''
    for c in ct:
        if c == '0':
            pt += ' '  # Replace '0' back to space
        elif not ord('A') <= ord(c) <= ord('Z'):
            pt += c  # Non-alphabetic characters remain unchanged
        else:
            o = ord(c) - 65
            pt += chr(65 + (o - shift) % 26)
    return pt

def decrypt():
    enc = open('output.txt').read()
    for i in range(1, 26):  # Iterate over all possible shift values
        print(f'{i = } | {julius_decrypt(enc, i)}')

if __name__ == "__main__":
    decrypt()
    
$ ./solve.py
...
i = 13 | WELCOME TO HACKTHEBOO TWOTHOUSANDTWENTYFOUR! THIS IS A PROOF OF CONCEPT TO PROVE YOU THAT THE CAESAR CIPHER IS INSECURE NO MATTER HOW MANY TIMES YOU APPLY IT. THE SECURITY OF A THOUSAND DISTINCT SHIFTS IS EVENTUALLY THE SAME AS THAT OF A SINGLE SHIFT. ENOUGH MUMBLING, TAKE YOUR FLAG AND ENJOY THE REST OF THE CONTEST. MAKE SURE YOU WRAP THE FOLLOWING TEXT WITH THE HTB FLAG FORMAT THEEFFECTIVEKEYSPACEOFCAESARDEPENDSONTHESIZEOFTHEALPHABET.
...

Flag: HTB{THEEFFECTIVEKEYSPACEOFCAESARDEPENDSONTHESIZEOFTHEALPHABET}

Related