SKIP TO MAIN CONTENT

[ WRITEUP NODE / FIELD REPORTS ]

SOLVED CHALLENGES & FIELD ANALYSIS

SECURITY RESEARCH KNOWLEDGE TECHNIQUES
B3S/WRITEUPS/GASLIGHTCTF-2026-WHERE-THE-DREAMS-START-1
← BACK TO ARCHIVE
EVENT: gaslightCTF 2026CATEGORY: CryptographyPOINTS: 500 PTS

GaslightCTF 2026 - Where the dreams start 1

AUTHORED BY:@bealthguy8/15/2026

Writeup: Caesar Cipher Challenge

Challenge Overview

We are given two files:

  • encrypt.py: Python script that implements a Caesar cipher (shift cipher) with a secret key K.
  • output.txt: Contains the resulting ciphertext.

The goal is to recover the original plaintext and submit it as a flag in the format gaslightCTF{...}.


Understanding the Encryption

The encrypt.py script does the following:

from string import ascii_lowercase

def encrypt(pt: str, K: int) -> str:
    pt = list(map(lambda x: ascii_lowercase.index(x), list(pt)))
    ct = []
    for x in pt:
        ct.append((x + K) % 26)
    ct = list(map(lambda x: ascii_lowercase[x], ct))
    ct = class="hljs-string">''.join(ct)
    return ct

with open(class="hljs-string">'gaslight-where-the-dream-starts-1/flag_and_key.txt', class="hljs-string">'r') as file:
    flag, K = file.readline().split()
    K = int(K)

print(encrypt(flag, K))

It reads a plaintext flag and an integer key K from a file, then:

  1. Converts each lowercase letter to its zero‑based index (a=0, b=1, …, z=25).
  2. Adds K to each index modulo 26.
  3. Converts the resulting numbers back to letters.

This is a classic Caesar cipher – each letter is shifted forward by K positions in the alphabet.

The provided ciphertext is:

fdhvduuhdoobolnhgdvkliwriwkuhh

Solution Strategy

Since a Caesar cipher has only 26 possible shifts (including 0), we can simply try every possible key and look for the result that produces readable English text. This is a trivial brute‑force attack.

We write a small Python script to:

  • Read the ciphertext from output.txt.
  • For each shift K from 0 to 25, decrypt by subtracting K (mod 26).
  • Optionally, score each candidate based on English letter frequency to automatically detect the correct shift.
  • Print the result that looks like English.

Solver Script

# solve.py
def decrypt(cipher, shift):
    return class="hljs-string">''.join(chr((ord(c) - 97 - shift) % 26 + 97) for c in cipher)

# Read ciphertext from the file
with open(class="hljs-string">'output.txt', class="hljs-string">'r') as f:
    cipher = f.read().strip()

# English letter frequency order (most common first)
freq_order = class="hljs-string">"etaoinshrdlcumwfgypbvkjxqz"

def score(text):
    # Give higher score if the text contains more common English letters
    return sum((26 - freq_order.index(c)) for c in text if c in freq_order)

best_plain = class="hljs-string">""
best_score = -1

for shift in range(26):
    plain = decrypt(cipher, shift)
    sc = score(plain)
    if sc > best_score:
        best_score = sc
        best_plain = plain

print(fclass="hljs-string">"Decrypted: {best_plain}")
print(fclass="hljs-string">"gaslightCTF{{{best_plain}}}")

Output:

Decrypted: caesarreallylikedashiftofthree
gaslightCTF{caesarreallylikedashiftofthree}

Identifying the Correct Shift

Running the script gives us the only English‑looking result:

caesarreallylikedashiftofthree

Inserting spaces for readability:

caesar really liked a shift of three

This confirms that the encryption key K is 3 (since “shift of three” is mentioned). The plaintext is a direct description of the cipher and its key.

No other shift produced a coherent English sentence.


Final Flag

Following the given flag format (gaslightCTF{...}), we wrap the plaintext:

gaslightCTF{caesarreallylikedashiftofthree}

Takeaways

  • Caesar ciphers are extremely weak – only 26 possible keys.
  • Always try brute‑force; it’s fast and effective.
  • The plaintext may hint at the key itself (“shift of three”).
  • Always preserve the exact format expected by the CTF (here gaslightCTF{}).