def send(self): s = str(self.key) sha_s = util_4.SHA1(s, len(s)).hexdigest() iv = util_2.get_random_string(16) return util_2.AES_CBC_encrypt( util_2.pkcs7_padding(self.msg, self.blocksize), sha_s[0:16], iv, self.blocksize) + iv
def main(): try: if sys.argv[1] == "25": plaintext = (''.join([line.strip() for line in open('out_7.txt') ])).decode('hex') cipher = util_3.ctr_stream( plaintext, 'c62a824f5d01d4bca11d4382cddfca19'.decode('hex')) assert break_read_write_ctr(cipher) == plaintext elif sys.argv[1] == "26": assert ctr_bitflipping_attack() == True elif sys.argv[1] == "27": assert cbc_key_as_iv() == True elif sys.argv[1] == "28": message, key = 'A' * 15, util_2.get_random_string(16) mac = sha1_authentication(key, message) assert tamper(key, message, mac) == False assert reproduce(message, mac) == False elif sys.argv[1] == "29": assert sha1_length_extension() == True elif sys.argv[1] == "30": assert md4_length_extension() == True else: raise ArgumentError("Give argument between 25 and 32") except ArgumentError, e: print e
def md4_length_extension(): key = util_2.get_random_string(16) def md4_sign(message): md = MD4() md.add(key + message) return md.finish().encode('hex') def md4_glue_padding(message_length): l = (message_length % 64) + 64 * int(message_length / 64) return ("\x80" + "\x00" * ((55 - l) % 64) + struct.pack("<Q", l * 8)) def attack(message, mac): new_msg = ";admin=true" keylength = 1 while True: message_length = len(message) + keylength glue_padding = md4_glue_padding(message_length) md_modified = MD4(list(struct.unpack("<4I", mac.decode('hex'))), message_length + len(glue_padding + new_msg)) md_modified.add(new_msg) new_mac = md_modified.finish().encode('hex') if md4_sign(message + glue_padding + new_msg) == new_mac: return True keylength += 1 return False message = "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon" mac = md4_sign(message) return attack(message, mac)
def sha1_length_extension(): key = util_2.get_random_string(16) def sha_sign(message): return SHA1(key + message, len(key + message)).hexdigest() def sha_glue_padding(message_length): length = bin(message_length * 8)[2:].rjust(64, "0") msg_remains = ((message_length % 64) * 8) + 1 return ("1" + "0" * ((448 - msg_remains % 512) % 512) + length) def attack(message, mac): mac_chunk = [int(mac[i:i + 8], 16) for i in xrange(0, len(mac), 8)] new_msg = ";admin=true" keylength = 1 while True: message_length = len(message) + keylength glue_padding = sha_glue_padding(message_length) glue_padding = ''.join([ chr(int(glue_padding[i:i + 8], 2)) for i in xrange(0, len(glue_padding), 8) ]) new_mac = SHA1(new_msg, message_length + len(glue_padding + new_msg), mac_chunk[0], \ mac_chunk[1], mac_chunk[2], mac_chunk[3], mac_chunk[4]).hexdigest() if sha_sign(message + glue_padding + new_msg) == new_mac: return True keylength += 1 return False message = "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon" mac = sha_sign(message) return attack(message, mac)
def cbc_key_as_iv(): blocksize = 16 key = util_2.get_random_string(blocksize) def recover_key(cipher): new_cipher = cipher[:16] + '\x00' * blocksize + cipher[:16] + cipher[ 48:] msg = util_2.pkcs7_unpadding( util_2.AES_CBC_decrypt(new_cipher, key, key, blocksize), blocksize) if not (all(each in string.printable for each in msg)): return util_1.fixed_xor(msg[:16].encode('hex'), msg[32:48].encode('hex')).decode('hex') return 0 message = "comment1=cooking%20MCs;userdata=testuser;comment2=%20like%20a%20pound%20of%20bacon" cipher = util_2.AES_CBC_encrypt(util_2.pkcs7_padding(message, blocksize), key, key, blocksize) return (key == recover_key(cipher))
def ctr_bitflipping_attack(): AES_KEY = util_2.get_random_string(16) def encrypt_modify(input_string): pre = "comment1=cooking%20MCs;userdata=" post = ";comment2=%20like%20a%20pound%20of%20bacon" if (';' in input_string) or ('=' in input_string): input_string = input_string.replace(';', '').replace('=', '') return util_3.ctr_stream(pre + input_string + post, AES_KEY) def decrypt_search_admin(cipher): message = util_3.ctr_stream(cipher, AES_KEY) return (";admin=true;" in message) cipher = encrypt_modify(" admin true") for i in xrange(256): for j in xrange(256): new_cipher = cipher[:32] + chr(i) + cipher[33:38] + chr( j) + cipher[39:] if decrypt_search_admin(new_cipher): return True return False
def reproduce(message, mac): for _ in xrange(5000): if SHA1(util_2.get_random_string(16) + message, 16 + len(message)).hexdigest() == mac: return True return False
def random_CBC_encrypt(blocksize=16): input_string = random_strings[index] padded_string = util_2.pkcs7_padding(input_string, blocksize) IV = util_2.get_random_string(blocksize) return util_2.AES_CBC_encrypt(padded_string, AES_KEY, IV, blocksize), IV