Writeup: EBCTF 2013 - Espionage

Information

  • Category: crypto

Description

We suspect an employee of one of the embassies has leaked
confidential information to a foreign intelligence agency.
We’ve managed to capture an individual whom we assume to
be the recipient of the info. Our forensics department has
managed to recover two messages from his outbox, which
appear to be encrypted using some crypto tool. Along with
each email our suspect also received an SMS message
containing a password, however we were only able to recover
one - “SieR1mephad7oose”.
Could you help us decrypt both messages?

Files:

1
2
3
4
5
6
cry100_espionage.tar.gz
|-- cry100_espionage/
|-- cry100_espionage/crypto.py
|-- cry100_espionage/msg001.enc
|-- cry100_espionage/msg002.enc
|-- cry100_espionage/README

Writeup

The challenge offers a python script used for encryption and decryption.
The crypt process performs a block-cipher, using a different key for each block:

1
2
3
4
5
6
7
8
9
def crypt(msg, passwd):
k = h(passwd)
for i in xrange(ROUNDS):
k = h(k)
out = ''
for i in xrange(0, len(msg), 16):
out += xor(msg[i:i+16], k)
k = h(k + str(len(msg)))
return out

However, unlikely a secure block cipher, this algorithm doesn’t perform some kind of message permutation and we can exploit this as an entry point.

The first decrypted message (using the script and the key given by the admins) is:

1
2
3
4
5
6
7
8
9
10
11
From: Vlugge Japie <vl.japie@yahoo.com>
To: Baron van Neemweggen <b.neemweggen@zmail.com>
Subj: Weekly update

Boss,

Sorry, I failed to get my hands on the information you
requested. Please don't tell the bureau - I'll have it
next week, promise!

Vlugge Japie

We can safely assume that the second message has the same header of the first.
So by xoring the first 16 bytes of the encoded message with "From: Vlugge Jap", we obtain the key of the first message block.
The rest of the key can be obtained automatically.

1
2
3
4
5
6
7
8
9
os.system("./crypto.py decrypt SieR1mephad7oose msg001.enc msg001.res")
header = open("msg001.res").read()[0:16]
inp = open("msg002.enc").read().decode('base64')
keytmp = xor(inp[0:16], header)
res = ''
for i in xrange(0, len(inp), 16):
res += xor(inp[i:i+16], keytmp)
keytmp = h(keytmp + str(len(inp)))
print res

Result:

1
2
3
4
5
6
7
8
9
10
11
12
From: Vlugge Japie <vl.japie@yahoo.com>
To: Baron van Neemweggen <b.neemweggen@zmail.com>
Subj: Found it!

Boss,

I found some strange code on one of the documents.
Is this what you're looking for?

ebCTF{21bbc4f404fa2057cde2adbf864b5481}

Vlugge Japie

Done :)

Flag

1
ebCTF{21bbc4f404fa2057cde2adbf864b5481}