by n0_1
Posted on Aug 29, 2017 at 05:00 AM
Workshop / Tutorial on Cipher Block Chaining @ UNSW, featuring a blackbox approach for breaking blocks.
Similarly to white and black box testing techniques, white box and black box cryptanalysis refers to Cryptanalysis where the availability of certain aspects of the protocol are revealed. If we have access to the source code of the encryption server, the keys, the IV and the client, the entire protocol and encryption technique is revealed to the attacker. This is white box cryptanalysis.
On the other hand, and in this tutorial we will not have access to the Key, IV or (theoretically) the server source code. What we do have is the ability to encode anything we like using the encryption service, and we will have access to the resulting ciphertext afterwards.
Plaintext -> E(k,iv) -> Ciphertext
)The term Crib
was used at Bletchley Park to denote any known plaintext, or suspected plaintext at some point in an enciphered message. Cryptanalysts leverage Cribs to discern additional information about the ciphertext.
Let's cover the basics of blockchain first. Blockchaining is a growing list of records, each of which are linked together and secured with cryptography. Each record (block) typically contains a hash pointer to a previous block. The decryption of subsequent blocks is dependent on the data integrity of the blocks that came before. A single bit modification of any preceeding block causes all subsequent blocks to be decrypted incorrectly.
Blockchain technology hinges on record keeping, and data integrity.
Cipher block chaining is a primitive encoding mode of the modern day 'Blockchain' definition. The plaintext is partitioned into equal sized blocks. Each plaintext block is encrypted using a cipher
to create a corresponding ciphertext block for that plaintext. Each generated ciphertext block is then XOR'd with the next plaintext block BEFORE the cipher
is applied to create the next ciphertext block. Rinse repeat.
Same Key, Same IV.
Block Num | Plaintext Block | Ciphertext Block |
---|---|---|
1 | AAAAAAAAAAAAAAAA | 4a900a8ecf2d6fb472428bc9ee9662b7 |
2 | CCCCCCCCCCCCCCCC | 0e59fa3e137576a1a36a69f609e39317 |
Block Num | Plaintext Block | Ciphertext Block |
---|---|---|
1 | AAAAAAAAAAAAAAAB | 63c02cff46df0a27831129395bb6066d |
2 | CCCCCCCCCCCCCCCC | b850c611ba186c86f5a07d84b943a478 |
We have some ciphertext. We control the first 15 bytes of plaintext. We need these 15 bytes in order to nudge future values to brute force. We have the encryption mechanism, so we can encrypt whatever plaintext we would like.
Block Num | Plaintext Block | Ciphertext Block |
---|---|---|
1 | AAAAAAAAAAAAAAAA | 4a900a8ecf2d6fb472428bc9ee9662b7 |
2 | etctf{reuse_sin} | 0b428bd0877ee4436ab448646cf51225 |
Block Num | Plaintext Block | Ciphertext Block |
---|---|---|
1 | AAAAAAAAAAAAAAAe | aa9683917bed5713b88ae5662452c56f |
2 | tctf{reuse_sin}? | d0bb390563dd69bfd94cdcc73d1fb6bb |
Block Num | Plaintext Block | Ciphertext Block |
---|---|---|
1 | AAAAAAAAAAAAAAet | fb50aafbdb19ab643abf0ad052655398 |
2 | ctf{reuse_sin}?? | 2f0c88ffe8e33c8a5e0e5d21201ff24f |
Block Num | Plaintext Block | Ciphertext Block |
---|---|---|
1 | AAAAAAAAAAAAAetc | 049c5f621ccb69ca3273d95813eff828 |
2 | tf{reuse_sin}??? | 8d3744eaf0e4e546dfe3cdb959996528 |
#!/usr/bin/python
from Crypto.Cipher import AES
import math
BLOCK_SIZE = 16
EncodeAES = lambda c, s: c.encrypt(pad(s, BLOCK_SIZE)).encode('hex')
DecodeAES = lambda c, e: c.decrypt(e.decode('hex'))
key = 'etctf{pwn_2_w1n}'
cookie = 'etctf{0_m41_g0d}'
iv = 'etctf{reuse_sin}'
flag1 = 'etctf{flagone}'
flag2 = 'etctf{f1agtwo}'
flag3 = 'etctf{fl4g_thr3}'
flag4 = 'etctf{F14G_F0UR}'
flag5 = 'try_for_padding_oracle'
def pad(text, block_size):
no_of_blocks = math.ceil(len(text)/float(block_size))
pad_value = int(no_of_blocks block_size - len(text))
if pad_value == 0:
return text + chr(block_size) block_size
else:
return text + chr(pad_value) * pad_value
def AES128_CBC_ENEX(msg):
cipher = AES.new(key, AES.MODE_CBC, iv)
exMsg = msg
exMsg += iv
exMsg += flag1
exMsg += flag2
exMsg += flag3
exMsg += flag4
exMsg += flag5
return EncodeAES(cipher, exMsg)
def AES128_CBC_DEEX(msg):
cipher = AES.new(key, AES.MODE_CBC, iv)
return DecodeAES(cipher, msg)