OverTheWire 'Krypton' Write Up

Level 0 -> Level 1

This is a simple base64 decode of the string S1JZUFRPTklTR1JFQVQ=. We can use the bash base64 -d command to decode the string.

┌─[✗]─[user@parrot]─[~]
└──╼ $echo 'S1JZUFRPTklTR1JFQVQ=' | base64 -d
KRYPTONISGREAT

Password: KRYPTONISGREAT

Level 1 -> Level 2

Upon logging in, the data for all the levels is stored in the /krypton directory. Navigate to /krypton/krypton1 to find the necessary files.

There is a file in here called krypton2. Let’s cat it out to see the contents.

krypton1@bandit:/krypton/krypton1$ cat krypton2 
YRIRY GJB CNFFJBEQ EBGGRA

This is most likely some sort of Caesar cipher, perhaps ROT13? ROT13 shifts each letter by 13 positions, so that A (1) -> N (14), B (2) -> M (15), and so on.

┌─[user@parrot]─[~]
└──╼ $rot13 YRIRY GJB CNFFJBEQ EBGGRA
LEVEL TWO PASSWORD ROTTEN

Password: ROTTEN

Level 2 -> Level 3

There are a bunch of files in /krypton/krypton2, but krypton3 has the encrypted text that we must decipher. It is encrypted with a Caesar cipher. The level gives us other files to help us solve this, but we might not need it.

krypton2@bandit:/krypton/krypton2$ cat krypton3 
OMQEMDUEQMEK

This website allows us to decipher text with any number we feed in: https://cryptii.com/pipes/caesar-cipher

By feeding in our text OMQEMDUEQMEK, we can brute force our Caesar Cipher. Select Decode and in the Shift box, keep pressing the up arrow until we see our Plaintext.

Caesar Cipher

Password: CAESARISEASY

Level 3 -> Level 4

Enumeration

There are multiple intercepted messages to help us crack the cipher. With this amount of text, this problem is most likely related to frequency analysis. Let’s cat out what we need to decipher.

krypton3@bandit:/krypton/krypton3$ cat krypton4 
KSVVW BGSJD SVSIS VXBMN YQUUK BNWCU ANMJS

Unigrams

Letters in the English language do not occur evenly. Certain letters such as ‘E’, ‘S’, ‘T’ are used more often than ‘Q’, ‘J’, ‘Z’. We can use this to our advantage by conducting a frequency analysis of the intercepted messages and compare the letter frequencies with what is nominal for English in order to find the 1 for 1 substitution that was used. This is a breakdown of the English frequencies.

  • E: 12.359%
  • T: 8.952%
  • A: 8.050%
  • O: 7.715%
  • N: 6.958%
  • I: 6.871%
  • H: 6.502%
  • S: 6.290%
  • R: 5.746%
  • D: 4.537%
  • L: 4.030%
  • U: 2.805%
  • M: 2.591%
  • C: 2.378%
  • W: 2.354%
  • F: 2.181%
  • Y: 2.119%
  • G: 2.042%
  • P: 1.682%
  • B: 1.494%
  • V: 1.032%
  • K: 0.853%
  • X: 0.145%
  • J: 0.127%
  • Q: 0.099%
  • Z: 0.088%

Using this website https://www.boxentriq.com/code-breaking/frequency-analysis, we can analyze the frequencies of the three messages that we intercepted.

Found 1:

  • S: 12.062%
  • C: 8.327%
  • Q: 8.249%
  • J: 7.938%
  • U: 7.782%
  • B: 6.770%
  • G: 6.304%
  • N: 5.759%
  • D: 5.370%
  • Z: 4.436%
  • V: 4.358%
  • W: 3.658%
  • Y: 3.268%
  • T: 2.490%
  • X: 2.257%
  • M: 2.257%
  • L: 2.101%
  • K: 1.946%
  • A: 1.556%
  • E: 1.323%
  • F: 0.856%
  • O: 0.545%
  • H: 0.156%
  • I: 0.156%
  • R: 0.078%

Found 2:

  • S: 13.698%
  • Q: 10.485%
  • J: 8.906%
  • N: 7.610%
  • U: 7.328%
  • B: 7.272%
  • D: 6.708%
  • G: 6.257%
  • C: 4.848%
  • W: 3.720%
  • Z: 3.326%
  • V: 2.988%
  • M: 2.537%
  • T: 2.086%
  • E: 1.917%
  • X: 1.860%
  • Y: 1.860%
  • K: 1.691%
  • L: 1.522%
  • A: 1.466%
  • I: 0.789%
  • F: 0.676%
  • O: 0.169%
  • H: 0.113%
  • R: 0.113%
  • P: 0.056%

Found 3:

  • S: 12.420%
  • Q: 10.278%
  • J: 8.779%
  • G: 7.495%
  • C: 7.281%
  • N: 6.638%
  • B: 6.424%
  • U: 5.782%
  • D: 4.711%
  • V: 4.497%
  • W: 3.426%
  • Z: 3.426%
  • E: 2.784%
  • M: 2.570%
  • K: 2.570%
  • Y: 1.927%
  • A: 1.927%
  • X: 1.927%
  • L: 1.285%
  • T: 1.285%
  • F: 1.071%
  • I: 0.642%
  • O: 0.428%
  • P: 0.214%
  • R: 0.214%

These are the unique letters from the krypton4 file that we need to find the substitutions for:

  • S, B, I, D, C, M, J, U, Y, Q, G, X, V, N, A, K, W

We only need to map these letters to find the password. Let’s go through the frequencies of the three messages to find them out.

  1. S is over 12% in all the three messages, so is most likely mapped to the letter E
  2. Q is the second most common in two out of the three messages, so is most likely A or T
  3. J is the third most common in two out of the three messages, so is most likely A or T

The rest of the letters are all similar in frequency. Let’s try finding other ways to find letters.

Bigrams

We can analyze bigrams (pairs of two letters) and trigrams (groups of three letters) using the same website to see which letters appear together frequently.

Most common bigrams (in order): th, he, in, en, nt, re, er, an, ti, es.

Found 1:

  • DS: 2.570%
  • JD: 2.103%
  • SU: 2.025%
  • JC: 1.947%
  • SN: 1.869%
  • CU: 1.713%
  • CG: 1.636%
  • SW: 1.636%
  • UJ: 1.402%

Found 2:

  • JD: 3.158%
  • DS: 2.200%
  • SN: 2.030%
  • DQ: 2.030%
  • NS: 1.918%
  • SU: 1.918%
  • QN: 1.805%
  • JS: 1.636%
  • SW: 1.579%

Found 3:

  • JD: 2.790%
  • DS: 2.361%
  • CG: 2.146%
  • SQ: 1.931%
  • SN: 1.717%
  • NS: 1.717%
  • BG: 1.717%
  • QG: 1.717%
  • GW: 1.717%
  • QN: 1.717%

Looking at these frequencies, we can assume:

  • JD = TH
  • DS = HE
  • SQ = EA
  • SN = ER
  • SU = ES

Trigrams

We can do the same things for groups of three letters.

Most common trigrams (in order): the, and, tha, ent, ing, ion, tio, for, nde, has.

Found 1:

  • JDS: 1.481%
  • DSN: 0.857%
  • QGW: 0.857%
  • SUQ: 0.779%
  • JCB: 0.779%
  • CBG: 0.779%
  • DCU: 0.779%
  • ZCY: 0.624%
  • CYD: 0.624%
  • YDS: 0.624%

Found 2:

  • JDS: 1.862%
  • SQN: 0.903%
  • UDQ: 0.677%
  • JSN: 0.677%
  • SNS: 0.621%
  • QNS: 0.621%
  • DQF: 0.564%
  • QFS: 0.564%
  • FSU: 0.564%
  • SUY: 0.564%

Found 3:

  • JDS: 1.935%
  • QGW: 1.505%
  • SNS: 0.860%
  • CGE: 0.860%
  • DSN: 0.645%
  • NQG: 0.645%
  • GWQ: 0.645%
  • JDQ: 0.645%
  • UZQ: 0.645%
  • SCG: 0.645%

Looking at these frequencies, we can assume:

  • JDS = THE
  • QGW = AND
  • CGE = ING
  • DQF = HAS
  • CBG = ION
  • JCB = TIO

Filling in the Letters

Let’s start solving the letters:

  • S = E
  • B = O
  • I
  • D = H
  • C = I
  • M
  • J = T
  • U = S
  • Y
  • Q = A
  • G = N
  • X
  • V
  • N = R
  • A
  • K
  • W = D

This is what our passphrase looks like:

  • KSVVW BGSJD SVSIS VXBMN YQUUK BNWCU ANMJS
  • ?E??D ONETH E?E?E ??O?R ?ASS? ORDIS ?R?TE

We can start filling in the gaps:

  • K = W

  • V = L

  • I = V

  • Y = P

  • X = F

  • M = U

  • KSVVW BGSJD SVSIS VXBMN YQUUK BNWCU ANMJS

  • WELLD ONETH ELEVE LFOUR PASSW ORDIS ?RUTE

WELL DONE THE LEVEL FOUR PASSWORD IS BRUTE

Password: BRUTE

Level 4 -> Level 5

Solving a vignere cipher is easy if you use resources! This link had a great tool to help you auto-solve one of the intercepted messages https://www.boxentriq.com/code-breaking/vigenere-cipher.

Vignere Cipher Auto-Solve

We can use the same tool to decode using “frekey” as our key.

Vignere Cipher Decoded

Password: CLEARTEXT

Level 5 -> Level 6

This is very similar to the previous level, but we will set a smaller min key length of 3 and max key lenth of 16 to test for many possible options.

Vignere Cipher 2 Auto-Solve

We got our answer! We can use “keylength” to decode our password.

Vignere Cipher 2 Decoded

Password: RANDOM

Level 6 -> Level 7

This level requires us to break a stream cipher. We are not given any intercepted messages, but we are given an executable that allows us to test the cipher. Let’s use it to our advantage!

File Enumeration

Let’s start by checking to see what files we are given.

krypton6@bandit:/krypton/krypton6$ ls
encrypt6  HINT1  HINT2  keyfile.dat  krypton7  onetime  README

krypton6@bandit:/krypton/krypton6$ ./encrypt6 
usage: encrypt6 foo bar 
Where: foo is the file containing the plaintext and bar is the destination ciphertext file.

krypton6@bandit:/krypton/krypton6$ cat ./krypton7 
PNUKLYLWRQKGKBE

It looks like we have the executable ready for use, along with its corresponding keyfile. We also have the encrypted password.

Using the Executable

If we can run the executable on our own input, we can potentially crack the key! Let’s start by creating a temp directory to work in. We will also need to create a symlink of the keyfile and give it exec permissions.

krypton6@bandit:/krypton/krypton6$ mktemp -d
/tmp/tmp.NbLQP1FLjD

krypton6@bandit:/krypton/krypton6$ cd /tmp/tmp.NbLQP1FLjD

krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ ln -s /krypton/krypton6/keyfile.dat 

krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ ls
keyfile.dat

krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ chmod 777 .

Next, we can create an input of all ‘A’s to test the executable.

krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" > input

Finally, let’s run the executable a few times to see how our output reacts.

krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ /krypton/krypton6/encrypt6 ./input ./output
krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ cat output
EICTDGYIYZKTHNSIRFXYCPFUEOCKRNEICTDGYIYZKTHNSIRFXYCPFUEOC

krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ /krypton/krypton6/encrypt6 ./input ./output
krypton6@bandit:/tmp/tmp.NbLQP1FLjD$ cat output
EICTDGYIYZKTHNSIRFXYCPFUEOCKRNEICTDGYIYZKTHNSIRFXYCPFUEOC

It looks like the executable encrypts the text the same way every time it is run. Additionally, we can see a repeated pattern of EICTDGYIYZKTHNSIRFXYCPFUEOCKRN. Sounds like an easy job for Python!

Decryption

Let’s start by saving our output to a variable and creating an empty list to store our cipher. For each letter in our output, we want to store the difference between the letter and ‘A’ in the list.

>>> output = "EICTDGYIYZKTHNSIRFXYCPFUEOCKRN"
>>> cipher = []
>>> for letter in output:
...     cipher.append(ord(letter) - ord("A"))
... 
>>> cipher
[4, 8, 2, 19, 3, 6, 24, 8, 24, 25, 10, 19, 7, 13, 18, 8, 17, 5, 23, 24, 2, 15, 5, 20, 4, 14, 2, 10, 17, 13]

We have our cipher! Now, we can use our krypton7 ciphertext and work backwords to get the plaintext.

  • For each letter in the ciphertext, we want to subtract the cipher difference at each respective position.

  • If the new value is less than 65 (the ASCII value of ‘A’), we should add 26 to the value to roll it back to a capital letter.

>>> krypton7 = "PNUKLYLWRQKGKBE"
>>> solution = ""
>>> i = 0
>>> for letter in krypton7:
...     c = ord(letter) - cipher[i]
...     if c < ord("A"):
...         c += 26
...     solution += chr(c)
...     i += 1
... 
>>> solution
'LFSRISNOTRANDOM'

We have our solution!

Password: LFSRISNOTRANDOM

Level 7

We completed the game!

krypton7@bandit:~$ cd /krypton/krypton7

krypton7@bandit:/krypton/krypton7$ ls
README

krypton7@bandit:/krypton/krypton7$ cat README 
Congratulations on beating Krypton!