DeadFace CTF: Lytton Labs Cryptoware 1

Reading time ~5 minutes

Another great CTF this week with a lot of variety of challenges and very helpful admins. For the second week in a row I’m writing about a solution which was not my first pathway. This challenge was in the Reverse Engineering category but if taken as a Crypto category challeng it solves much more easily.

Decrypting Lytton Labs Cryptoware 1 - Reverse Engineering - 400 points

This challenge reads:

Decrypting Lytton Labs Cryptoware 1

DEADFACE has launched a ransomware attack against Lytton Labs. Luciafer was 
responsible for writing the Windows version, and TheZeal0t wrote the version 
for Linux.

We've recovered a file that was encrypted by Luciafer's ransomware, but 
we are unable to decrypt it. The BLUEzer's Club has been asked to help 
decrypt the file.

We haven't been able to decrypt the file, or determine what the key or 
encryption algorithm is. We are going to need your expertise on this one!

HINT: This ransomware attacks specific files used only by Lytton Labs. 
It is harmless against all others.

66 solves

With this challenge comes two files:

  • fkduohv-d-jhvfklfnwhu-wr-gdun-dqjho-01.oodev
  • zealotcrypt-01.exe

A quick check shows that the binary is a Windows PE32 originally written in Golang.

$ file zealotcrypt-01.exe
zealotcrypt-01.exe: PE32 executable (console) Intel 80386 (stripped to 
external PDB), for MS Windows

Loading the binary in Ghidra shows the typical issue with reversing Golang binary but the basic program flow can still be divined. I removed a bunch of useless lines from the decompilation to show the basics:

int main.main(void) {
	main.fetchKey(&key);			// Get a RC4 key from somewhere...
    main.findFilesWithExt(...);		// Find any *.llabs files in the path...
    for (filelist) {				// Loop through the llabs files
        main.rotateText(...); 		// Rot3 the filename...  aaa.llabs -> ddd.oodev
        os.ReadFile(&buf);			// Read the contents of the file.
        main.encryptRc4(buf, key);	// Encrypt the the key given using RC4
        os.WriteFile(...);			// write encrypted contents to the renamed file.
        os.Remove(...);				// remove original file.
    }
}

So its a typical ransomware type process. Encrypt files and ransom the owner, except this one only targets *.llabs files.

Our job is to:

  • figure out the encryption
  • somehow reverse the encryption
  • recover the file given in the clue which contains a flag

Solving Theories

I tried a few methods at first, I knew that the main.fetchKey() function was worth investigating to recover the key material. Here’s what it looks like:

int main.fetchKey(char *key) {
	net/http.NewRequestWithContext(...);
	net/http.(*Client).do(...);
}

So it clearly grabs a key from the internet via Go’s standard net/http library. We can look at the network calls it makes when we run it with Wine and find that it grabs a GIF file from the web:

$ tcpdump -w zealot.pcap -i eth0 port 80
...
GET /pretty-lady.gif HTTP/1.1
Host: insidious.deadface.io
User-Agent: DEADFACE-LLABS-CRYPTOWARE/6.66
Accept-Encoding: gzip

HTTP/1.1 200 OK
Date: Mon, 18 Oct 2021 06:57:52 GMT
Server: Apache/2.4.49 (Unix)
Last-Modified: Sat, 20 Jun 2020 20:21:59 GMT
ETag: "295f3-5a889c2fe87c0"
Accept-Ranges: bytes
Content-Length: 169459
Content-Type: image/gif

GIF89a..,.....................

The pretty-lady.gif is an animated GIF with nothing specific about it. In Golang the RC4 library can use any byte slice as a key so its possible that the ransomware just indexes into the pretty-lady.gif by some integer and uses a random slice of bytes of length between 1 and 256.

I tried writing some Go that tried to use that method to successfully encrypt a string of AAAAAA which possibly could have worked. I would only need to take a sliding 6 byte key stream window from pretty-lady.gif and see if it worked. However I didn’t end up needing to because before that finished running I thought of another idea.

Solving in Practice

While testing out how the ransomware worked I just did a standard “run it and see what happens…”

$ echo -n "AAAA" > test.llabs
$ wine zealotcrypt-01.exe
Pinkie Print = cfa5:6af7
LYTTON LABS: Your sins have finally caught up to you!  Your files have been encrypted!
$ ls *.oodev                                                                                                                     
fkduohv-d-jhvfklfnwhu-wr-gdun-dqjho-01.oodev  whvw.oodev
$ cat whvw.oodev | hex
71a6eceb

So our test.llabs file has become whvw.oodev and the contents changed from \x41\x41\x41\x41 to \x71\xa6\xec\xeb

Next I wanted to try 2 things:

  • What happens when I re-encrypt an already encrypted file?
  • What happens when I encrypto \x00\x00\x00\x00 and XOR it with our existing encrypted file?

As it turns out, both methods work to solve this riddle because of the flawed way in which the ransomware re-uses the RC4 key. Since the key is the same every time it is invoked and RC4 is basically XOR with a fancy keystream generator the solution is rather simple.

Solution 1, XOR with Encrypted Null Bytes

Since the encrypted file we want is 892 bytes long, we need to encrypt 892 zeros first:

$ python -c "print('\x00' * 892, end='')" > zeros.llabs
$ wine zealotcrypt-01.exe
Pinkie Print = cfa5:6af7
LYTTON LABS: Your sins have finally caught up to you!  Your files have been encrypted!
$ ls -la *.oodev
ls -la *.oodev
-rw-r--r-- 1 root root 892 Oct 18 21:20 churv.oodev
-rw-r--r-- 1 root root 892 Oct 16 00:03 fkduohv-d-jhvfklfnwhu-wr-gdun-dqjho-01.oodev

Then xor these together for the flag:

$ xortool-xor -f churv.oodev -f fkduohv-d-jhvfklfnwhu-wr-gdun-dqjho-01.oodev                                                                 
Dear Dark Angel,

We need your help (again).  It seems that those pesky little twerps
at DEADFACE have targetted Lytton Labs with their hacking activities.
I'm worried that they'll get their hands on information that could
cause Lytton Labs embarrassment or financial harm.

We need your hacking and incident response skills to help us to
keep DEADFACE out or to divert them away from the really important
records of our activities, as well as to notify us of any attempts,
successful or otherwise, to breach our systems.

We will pay your standard fee, plus a 25% bonus when you have 
presented us with proof that you have managed to counter-hack one
of the DEADFACE operative's computers.

Please let me know if you have any questions.


Ever at your service,


Dr. Charles A. Geschickter
Head of MKULTRA Research
Lytton Labs

P.S. flag{RC4-IS-REVERSIBLE-BUT-AES-IS-NOT-GO-BACK-GO-BACK!!!}

Solution 2, Re-encrypt Ciphertext

This one is even easier than the first, just rename the file and run the ransomware:

$ mv fkduohv-d-jhvfklfnwhu-wr-gdun-dqjho-01.oodev win.llabs
$ wine zealotcrypt-01.exe
Pinkie Print = cfa5:6af7
LYTTON LABS: Your sins have finally caught up to you!  Your files have been encrypted!
$ cat zlq.oodev

...

P.S. flag{RC4-IS-REVERSIBLE-BUT-AES-IS-NOT-GO-BACK-GO-BACK!!!}

Both worked and we’re faster than reversing the binary in the end.

Interviewing in Tech: Security Engineer & Security Analyst

Landing a job as a security engineer or analyst at a tech company is a significant feat. It requires not only technical acumen but also s...… Continue reading

BSides Sydney 2023 Writeups

Published on November 24, 2023

DUCTF 2023 Writeups

Published on August 31, 2023