This document provides a summary of five challenges in a cryptoCTF competition:
1. The first challenge involved breaking a poor AES-CBC cryptolocker by bruteforcing the encryption key.
2. The second challenge exploited key reuse in a simple stream cipher to reveal the encryption keystream and decrypt ciphertexts.
3. The third challenge leaked data through AES encryption in ECB mode.
4. The fourth challenge performed a length extension attack to forge the MAC in a SHA256 challenge.
5. The final challenge involved bruteforcing a string to match a target hash prefix using SHA256 proof of work.
2. Intro
What this talk is about
What this talk is NOT about
google “vladimir garbuz cryptography” for
dec0de01 talk and slides with more technical
details
Ok… The cryptoCTF!
solve 5 challenges to win 10000$
well, 100.00$...
Still available at the link: http://goo.gl/tuKku7
3. Intro
CTF consisted of 5 tasks:
1. Poor AES-CBC cryptolocker (bruteforce)
2. Simple stream cipher (pad reuse)
3. AES-ECB encryption (data leaking)
4. SHA256 MAC (length extension attack)
5. SHA256 proof of work (bruteforce)
4. AES-CBC cryptolocker
2 files available:
very_bad_encryptor is VERY bad:
Very slow (~1MB/sec)
Can encrypt and decrypt
Uses SHA256 hash as AES encryption key
Hash of a 8 digit numeric user entered code…
Uses CBC encryption mode
10. Simple stream cipher
Stream cipher basics
Sender computes Message ⊕ Keystream and
sends the Ciphertext
Receiver computes Ciphertext ⊕ Keystream to get
Message
In our case, the key stream was generated via
Python random, initialized with constant
“0xdec0de01”
11. Simple stream cipher
Basic vulnerabilities: key reuse
What’s so terrible about key reuse?
So we have 2 plaintexts P1 and P2, and we
encrypt them separately under the same Key:
C1=P1⊕F(Key)
C2=P2⊕F(Key)
When attacker intercepts them, he can then
compute:
C1⊕C2=P1⊕P2
“Oh, please! How bad could that possibly
13. Simple stream cipher
Basic vulnerabilities: key reuse
Case 1: if one of the plaintexts, e.g. P1, is
known, restoring the other one is trivial
P1⊕P2⊕P1 = P1⊕P1⊕P2 = 0⊕P2 = P2
Case 2: if a portion of Plaintext is known, the
Keystream in corresponding position is
revealed
C = P⊕E(Key) C⊕P = E(Key)
Now, having the Keystream at some position, we
can decrypt data at that position from other
ciphertexts
15. SHA256 MAC – length
extension
The task was, quote:
d60d6d39c50b85f8a080ab510c2f3402c34ffc8cf09f9f3bfc7fc218d77bb5a
3
This is a MAC (SHA256) of a secret key concatenated with the e-mail
address
that you need to send your results to. The length of the key+e-mail is 53
bytes.
Your task is to add any message you want to this e-mail and compute a
new
SHA256 hash of it - all in such a way that your hash is identical to the
MAC that
I will compute from my key + your message.
As a solution for this task I expect 2 things: forged message AND it's
16. SHA256 MAC – length
extension
Breaking “key + message MAC”
What’s vulnerable?
Hash functions with Merkle–Damgård construction,
e.g. MD4, MD5, RIPEMD-160, WHIRLPOOL, SHA-
0, SHA-1 and even SHA-2
Doesn’t work on other constructions - SHA-3,
poly1305,...
In this construction, the resulting hash is the
internal state of the function at the end of
computation
Which can (and will ) be used as the starting state
17. SHA256 MAC – length
extension
Hash of k+m is actually a hash of k+m+p,
where p is some necessary, but easily
predictable, padding
To illustrate this:
H0(k) = Hk - here, H0 is the initial state of hash
function
Hk(m) = Hkm - Hk is its state after processing k
Hkm (p) = Hkmp
Hkmp = H(k+m+p)
18. SHA256 MAC – length
extension
Since p is predictable and end state Hkmp is
known
We chose any arbitrary m´
Set the hash function’s initial state to Hkmp
And make it process the bytes of message m´
Hkmp(m´) = Hkmpm´
Curiously, this is EXACTLY what happens when
you hash m+p+m´ under a known key!
Now, our hash is forged but will check out as
valid!
19. SHA256 MAC – length
extension
Example solution:
Using https://github.com/iagox86/hash_extender we can append
string '0wn3d',
$ hash_extender -d '' -s
d60d6d39c50b85f8a080ab510c2f3402c34ffc8cf09f9f3bfc7fc218d
77bb5a3 -a '0wn3d' -f sha256 -l 53
Type: sha256
Secret length: 53
New signature:
787f169dcb032ada7dbdfc7906eeccc6701f7c0cdf4ee1e09da441e
9351d6f53
New string: 80000000000000000001a830776e3364
20. SHA256 proof of work
The task was to find a string such that it’s
SHA256 in hex encoding would start with
dec0de01
How to?..
Just bruteforce it!
Example string is “3928979165”
It’s sha256 in hex encoding is:
dec0de01646730a1e0f2d6d34a0833be52df6e05
52fe16f04ab66610b70321f1