def getBlockSize(oracle): startCounting = -1 extraBytes = 1 baseLength = len(oracle(Binary())) while 1: newLength = len(oracle(Binary('A' * extraBytes, 128))) if newLength > baseLength and startCounting == -1: startCounting = extraBytes elif newLength > baseLength: return newLength - baseLength extraBytes += 1
def encryptionOracle(data): randomKey = Binary.random(8 * 16) addBefore = Binary.random(random.randrange(5, 11) * 8) addAfter = Binary.random(random.randrange(5, 11) * 8) data = addBefore + data + addAfter IV = Binary.random(8 * 16) c = Crypto(data) if random.randrange(2): c.encAES_ECB(randomKey) mode = 'ECB' else: c.encAES_CBC(randomKey, IV) mode = 'CBC' return (mode, c.data)
def encryptionOracle(data): extraData = Binary( 'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK', 64) data = data + extraData c = Crypto(data) c.encAES_ECB(randomKey) return c.data
def createProfileAndProvide(email): if isinstance(email, Binary): email = email.toAscii() profile = profile_for(email) c = Crypto(Binary(profile, 128)) c.encAES_ECB(randomKey) cipher = c.data return cipher
def detectMode(cipher): blocks = [ Binary(cipher[x:x + 8 * 16]) for x in range(0, len(cipher), 8 * 16) ] repeated = 0 i = 0 while i < len(blocks) - 1: ii = i + 1 while ii < len(blocks): if blocks[i] == blocks[ii]: blocks = blocks[:ii] + blocks[ii + 1:len(blocks)] repeated += 1 ii -= 1 ii += 1 i += 1 if not repeated: return 'CBC' return 'ECB'
while i < len(blocks) - 1: ii = i + 1 while ii < len(blocks): if blocks[i] == blocks[ii]: blocks = blocks[:ii] + blocks[ii + 1:len(blocks)] repeated += 1 ii -= 1 ii += 1 i += 1 if not repeated: return 'CBC' return 'ECB' data = Binary('A' * 16 * 10, 128) nTests = 25 count = 0 for i in range(nTests): cipher = encryptionOracle(data) passed = False detectedMode = detectMode(cipher[1]) if detectedMode == cipher[0]: passed = True count += 1 print('({:>2}/{}) Used: {} Detected: {} --> Passed: {}'.format( i + 1, nTests, cipher[0], detectedMode, passed))
from Tools import Crypto from Tools import Binary text = 'Burning \'em, if you ain\'t quick and nimble\nI go crazy when I hear a cymbal' key = Binary('ICE', 128) e = Crypto(text, 128) e.xor(key) result = e.toHex() expected = '0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f' if result == expected: print('Passed!') else: print(result) print(expected)
from Tools import Binary b = Binary('YELLOW SUBMARINE', 128) padded = b.pkcs_7(21*8) print('Before padding: {}'.format(b.toHex())) print('After padding: {}'.format(padded.toHex()))
from Tools import Binary, Crypto data = '' key = Binary('YELLOW SUBMARINE', 128) with open('./ch10.txt') as file: for line in file: data += line.rstrip() data = Binary(data, 64) IV = Binary('0' * 32, 16) c = Crypto(data) c.decAES_CBC(key, IV) print(c.toAscii())
from Tools import Binary b1 = Binary('1c0111001f010100061a024b53535009181c', 16) b2 = Binary('686974207468652062756c6c277320657965', 16) expected = Binary('746865206b696420646f6e277420706c6179', 16) if expected == b1 ^ b2: print('Passed!') else: print('Expected:', expected) print('Got:', b1 ^ b2)
from Tools import Binary, Crypto import random # constant random key randomKey = Binary.random(8 * 16) def encryptionOracle(data): extraData = Binary( 'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK', 64) data = data + extraData c = Crypto(data) c.encAES_ECB(randomKey) return c.data def __main__(): print(Crypto.decECB(encryptionOracle)) if __name__ == "__main__": __main__()
from Tools import Crypto from Tools import Binary data = '' key = Binary('YELLOW SUBMARINE', 128) with open('./ch7.txt') as file: for line in file: data += line.rstrip() binary = Crypto(Binary(data, 64)) binary.decAES_ECB(key) print(binary.toAscii())
from Tools import Binary s = '49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d' expected = 'SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t' data = Binary(s, 16) result = data.toBase64() if result == expected: print('Passed!') else: print(result)
from Tools import Binary with open('./ch8.txt') as file: lineCounter = 0 for line in file: lineCounter += 1 line = line.rstrip() data = Binary(line, 16) repeatedGroups = 0 step = 8 * 16 # 16 bytes for i in range(0, len(data) - step, step): group = data[i:i + step] for ii in range(i + step, len(data) - step, step): anotherGroup = data[ii:ii + step] if group == anotherGroup: repeatedGroups += 1 if repeatedGroups > 0: print('Number: {}\nLine: {}\nRepeated:{}'.format( lineCounter, data.toHex(), repeatedGroups))
from Tools import Crypto, Binary b = Binary('ICE ICE BABY', 128) print(Binary(Crypto.removePadding(b + Binary('04040404', 16))).toAscii()) try: Crypto.removePadding(b + Binary('05050505', 16)) except: print('Caught exception') try: Crypto.removePadding(b + Binary('01020304', 16)) except: print('Caught exception') print('Passed!')
from Tools import Binary, Crypto randomKey = Binary().random(8 * 16) def parseParams(params): result = {} pairs = params.split('&') for pair in pairs: content = pair.split('=') result[content[0]] = content[1] return result def profile_for(email): email = email.replace('&', '') email = email.replace('=', '') return 'email={}&uid={}&role=user'.format(email, 10) def createProfileAndProvide(email): if isinstance(email, Binary): email = email.toAscii() profile = profile_for(email) c = Crypto(Binary(profile, 128)) c.encAES_ECB(randomKey) cipher = c.data
from Tools import Crypto from Tools import Binary data = '' with open('./ch6.txt') as file: for line in file: data += line.rstrip() binary = Crypto(data, 64) keys = binary.decXOR() binary.xor(Binary(keys[0], 128)) print(binary.data.toAscii())
from ch12 import encryptionOracle from Tools import Binary, Crypto import random randomPrefix = Binary().random(random.randrange(0, 30 * 8, 8)) def wrapper(data): return encryptionOracle(randomPrefix + data) print(Crypto.decECB(wrapper))