Cryptography

CCT2019 — crypto1

Medium → Hard TryHackMe 3 Parts 2019

A three-part cryptography challenge covering keyboard layout ciphers, rail fence transposition, and a custom run-length encoding scheme. Each part unlocks the next, progressively increasing in complexity.

Challenge Overview

This challenge has three progressive parts:

  • crypto1a: Keyboard substitution cipher → unlocks crypto1b
  • crypto1b: Rail fence transposition cipher → unlocks crypto1c
  • crypto1c: Custom run-length binary encoding
A

Keyboard Layout Cipher

Dvorak to QWERTY substitution

Analysis

We're given crypto1a.txt with garbled text:

plaintext
Ab .aof y.jdbc'g. urp ornkcbi Ja.oap ogxoycygycrb jcld.po ,cnn rbnf 
i.y frg or uap x.jago. ru lgbjygaycrb ofmxrnov  Oycnnw cy odrgne i.y 
frg jnro. .brgid yr ucigp. rgy yd. p.oyv  Xgy jab frg ucigp. rgy yd. 
t.f ,dcjd dall.bo yr x. yd. bam. ru yd. _nafrgy_ ,dcjd jp.ay.e ydcov 
Ajygannfw frg dae x.yy.p .by.p cy ydpcj. hgoy yr x. oau. (ann nr,.p
[jao. cu frg ln.ao.)v

Using dcode.fr's keyboard change cipher tool, converting from Dvorak to QWERTY layout:

plaintext
An easy technique for solving Caesar substitution ciphers will only get you 
so far because of punctuation symbols. Still, it should get you close enough 
to figure out the rest. But can you figure out the key which happens to be 
the name of the "layout" which created this. Actually, you had better enter 
it thrice just to be safe (all lower-case if you please).
Key Insight
The key is dvorak — the keyboard layout that created the cipher. Enter it three times as the password.

Flag

bash
unzip crypto1a.zip -P dvorakdvorakdvorak
cat crypto1a_flag.txt
CCT{crypto1a_flag}
B

Rail Fence Cipher

Transposition with 5 rails, bottom-up

Analysis

crypto1b.txt contains the hint:

plaintext
A word of advice for the next one. Don't straddle the fence or you'll end 
up riding a rail or five. It'll hurt from the bottom up.
Hint Interpretation
"Rail or five" → Rail fence with 5 rails.
"From the bottom up" → Start from bottom direction.

The ciphertext is a long block of transposed text. Using dcode.fr's Rail Fence Cipher tool with:

  • Rails: 5
  • Direction: Start from Bottom (left)
  • Offset: 1

Decrypted message:

plaintext
Moving right along through a different challenge. How are you at ciphers 
like these? Solvable by hand and made easier because of the placement of 
the upper case letters and punctuation throughout the message, no? How 
about this for a key. The way the goose spells terrific from the 1973 
animated movie of Charlotte's web. I've seen a misspelling in the title 
of a clip on youtube. At the very least it's four Cs, but it's probably 
six. All lower case for goodness' sake, but not that it matters, oui oui?

Custom Python Decoder

python
enc = "n h newuhe eddre nect tota ufyaolim7ter val lcy vsf slAro..."
rails = 5
offset = rails - 1

def railNumber(position, rails, offset):
    position = (position + offset) % (rails * 2 - 2)
    if position < rails:
        return position
    else:
        return 2 * rails - position - 2

def decrypt(enc, rails, offset):
    result = ['+'] * len(enc)
    k = 0
    for i in range(rails):
        for j in range(len(enc)):
            if railNumber(j, rails, offset) == i:
                result[j] = enc[k]
                k += 1
    return "".join(result)

print(decrypt(enc, rails, offset))

Finding the Key

The goose from Charlotte's Web (1973) spells "terrific" as "teerrrriiffiicccccc" (with 6 C's).

bash
unzip crypto1b.zip -P teerrrriiffiicccccc
CCT{crypto1b_flag}
C

Run-Length Binary Encoding

Custom compression to binary flag

Analysis

crypto1c.txt contains a long string of digits:

plaintext
11122112141311112123131222211121621211124112213221112162112113114163...
Hints
"But is it compression, encoding, or encryption?" and "start with 0, not 1".

This is a custom run-length encoding where:

  • Even indices → 0 bits
  • Odd indices → 1 bits
  • The digit value = number of consecutive bits

Decryption Script

python
from Crypto.Util.number import long_to_bytes

enc = "1112211214131111212313122221112162121112411221322111216..."

result = ""
for i in range(len(enc)):
    binary = '0' if i % 2 == 0 else '1'
    result += binary * int(enc[i])

flag = long_to_bytes(int(result, 2)).decode("ASCII")
print(flag)

Output:

plaintext
You've made it this far. You've solved all of the crypto challenges from 
the basic batch, but there are more challenges ahead. How will you fare 
against those I wonder. At any rate, well done and here is your flag:
CCT{crypto1c_flag}
CCT{crypto1c_flag}

Key Takeaways

Keyboard Layout Ciphers

Dvorak/QWERTY mapping creates substitution ciphers; use dcode.fr for quick decoding.

Rail Fence Cipher

Transposition cipher with configurable rails, offset, and direction — watch for hints in the text.

Custom Encodings

CTF challenges often invent novel encoding schemes; analyze the pattern methodically.

Run-Length Encoding

Simple compression that can encode binary data using digit counts — always check for binary output.

Progressive Challenges

Each part's solution unlocks the next, building complexity — keep notes as you go.

Pop Culture References

Movie/TV references (Charlotte's Web) can contain keys — research is part of the challenge.