def f1(): block_len = 16 global key data = INPUT[randint(0, len(INPUT) - 1)] #padding is added by the encryption function key = random_aes_key(16) iv = random_aes_key(16) aes_ecb = AES.new(key, AES.MODE_ECB) return (cbc_encrypt(aes_ecb, bytearray(data, "ascii"), iv), iv)
def main(): blocksize = 16 global key global IV key = random_aes_key(blocksize) IV = random_aes_key(blocksize) #Detecting block size a = len(f1("A")) for i in range(2, 40): b = len(f1("A" * i)) if a != b: blocksize = b - a print("Block size: %d bytes" % (blocksize, )) break text = chr(ord(";") ^ 0x1) + "admin" + chr(ord("=") ^ 0x1) + "true" + chr( ord(";") ^ 0x1) + "AAAA" #this will be inserted on the third block # the idea is to modify the first (0) and the third (11) Xs to ; and the second (6) X to = # We need to change the bytes on the second block to propagate the changes on the third ciphertext = f1(text) pre = ciphertext[0:16] a = bytearray([ciphertext[16] ^ 0x1]) mid1 = ciphertext[17:22] b = bytearray([ciphertext[22] ^ 0x1]) mid2 = ciphertext[23:27] c = bytearray([ciphertext[27] ^ 0x1]) post = ciphertext[28:] x = pre x.extend(a) x.extend(mid1) x.extend(b) x.extend(mid2) x.extend(c) x.extend(post) #x = pre + a + mid1 + b + mid2 + c + post #I miss C if f2(x): print("Success!!!") exit()
def encryption_oracle(plaintext): block_len = 16 key = random_aes_key(block_len) aes_ecb = AES.new(key, AES.MODE_ECB) data = bytearray(random_str(5, 10)) data.extend(bytearray(plaintext, "ascii")) data.extend(random_str(5, 10)) if randint(0, 1) == 0: #ECB data = bytes(pkcs7_add( data, block_len)) #turning into bytes so aes_ecb won't bitch test = (aes_ecb.encrypt(data), "ECB") else: #CBC iv = random_aes_key(block_len) test = (cbc_encrypt(aes_ecb, data, iv), "CBC") #Detection if detect_ecb(test[0]): print("ECB detected!") else: print("Guessed \"%s\" as CBC" % (test[1], ))
def main(): global key #put it here for the edit_api() function global nonce #put it here for the edit_api() function INPUT = recover_input() key = random_aes_key() nonce = 0 ciphertext = ctr(INPUT, key, nonce) #print ctr(ciphertext,key,nonce)[:255] junk = bytearray("A" * len(ciphertext), "ascii") mask = edit_api(ciphertext, 0, junk) keystream = xor(junk, mask) plaintext = xor(ciphertext, keystream) print(plaintext)
def main(): global key global nonce key = random_aes_key() nonce = 0 text = chr(ord(";")^0x1)+"admin"+chr(ord("=")^0x1)+"true"+chr(ord(";")^0x1)+"AAAA" #this will be inserted on the third block ciphertext = f1(text) fake = ciphertext fake[32] ^=0x1 fake[38] ^=0x1 fake[43] ^=0x1 if f2(fake): print ("Success!!!") exit()
def main(): block_len = 16 key = random_aes_key(block_len) aes_ecb = AES.new(key, AES.MODE_ECB) email = "*****@*****.**" #[email protected] is the exact size to force "user" to be on its own block user_token = encrypt(aes_ecb,profile_for(bytearray(email,"ascii"))) fake_email = bytearray("X"*(16-len("email=")),"ascii") fake_email.extend(pkcs7_add(bytearray("admin","ascii"),block_len)) fake_email.extend(bytearray("@whatever.com","ascii")) fake_token = encrypt(aes_ecb,profile_for(fake_email)) #the second block contains "admin" encrypted with padding admin_token = user_token[:-16] + fake_token[16:32] print ("Original token (decrypted): ",pkcs7_remove(decrypt(aes_ecb,user_token))) print ("Fake token (decrypted): ",pkcs7_remove(decrypt(aes_ecb,admin_token)))
assert equals( cryptopals.cbc_mode( cryptopals._string_from_file("testfiles/10.txt"), "YELLOW SUBMARINE", b'\x00', "decrypt" ).decode('utf-8'), solutions.soln_10 ) # Problem 2.3 (11): An ECB/CBC detection oracle for i in range(0, 10): input = solutions.soln_10 encrypted, mode = cryptopals.encryption_oracle(input) assert equals(cryptopals.detect_ecb_or_cbc(encrypted), mode) # Problem 2.4 (12): Byte-at-a-time ECB decryption (Simple) consistent_key = cryptopals.random_aes_key() assert equals( cryptopals.decrypt_magic_text(solutions.problem_12, consistent_key), solutions.soln_12 ) # TODO: Problem 2.5 (13): ECB cut-and-paste cryptopals.copypasta_attack() # TODO: Problem 2.6 (14): Byte-at-a-time ECB decryption (Harder) # Googling ``stimulus'' and ``response'' totally helped here :P # http://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Eng.pdf consistent_key = cryptopals.random_aes_key() random_prepend = cryptopals.random_length_bytes() assert equals( cryptopals.decrypt_magic_text_harder(solutions.problem_12, consistent_key, random_prepend),
def main(): p = 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff g = 2 ################################################################################ ###### MITM attack - Scenario 01: g = 1 ################################################################################ #User A generates A a = randint(0, p) A = pow(g, a, p) #User A sends (p,g,A) to M m_data = (p, g, A) #Use M send (p,g,A) to M g_m = 1 b_data = (p, g_m, A) #User B generates B b = randint(0, b_data[0]) B = pow(b_data[1], b, b_data[0]) #the result will be 1 #User B sends B to M m_data2 = B a_data = m_data2 #let's send this 1 forward #User A calculates s, iv, key and encrypt a message #print a_data s_a = pow(a_data, a, p) #s_a = 1 #print s_a iv_a = random_aes_key(16) msg_a = bytearray("Super Secret Stuff123", "ascii") #print hex(s_a) key_a = sha1(int_to_bytes(s_a))[:16] aes_ecb_a = AES.new(key_a, AES.MODE_ECB) enc_a = cbc_encrypt(aes_ecb_a, msg_a, iv_a) #test = cbc_decrypt(aes_ecb_a, enc_a, iv_a) #print test #User A sends encrypted message and iv to M m_data3 = enc_a + iv_a #M can recalculate the key and decrypt the message: key_m = sha1(b"\x01")[:16] #print key_m aes_ecb_m = AES.new(key_m, AES.MODE_ECB) msg_m = cbc_decrypt(aes_ecb_m, m_data3[:-16], m_data3[-16:], validation=True) #M knows the message (DONE) print("Retrieved by M (scenario 1):", msg_m) ################################################################################ ###### MITM attack - Scenario 02: g = p ################################################################################ #User A generates A a = randint(0, p) A = pow(g, a, p) #User A sends (p,g,A) to M m_data = (p, g, A) #Use M send (p,g,A) to M g_m = p b_data = (p, g_m, A) #User B generates B b = randint(0, b_data[0]) B = pow(b_data[1], b, b_data[0]) #the result will be 0 #User B sends B to M m_data2 = B a_data = m_data2 #let's send this 0 forward #User A calculates s, iv, key and encrypt a message #print a_data s_a = pow(a_data, a, p) #s_a = 0 #print s_a iv_a = random_aes_key(16) msg_a = bytearray("Super Secret Stuff123", "ascii") #print hex(s_a) key_a = sha1(int_to_bytes(s_a))[:16] aes_ecb_a = AES.new(key_a, AES.MODE_ECB) enc_a = cbc_encrypt(aes_ecb_a, msg_a, iv_a) #test = cbc_decrypt(aes_ecb_a, enc_a, iv_a) #print test #User A sends encrypted message and iv to M m_data3 = enc_a + iv_a #M can recalculate the key and decrypt the message: key_m = sha1(b'\x00')[:16] #print key_m aes_ecb_m = AES.new(key_m, AES.MODE_ECB) msg_m = cbc_decrypt(aes_ecb_m, m_data3[:-16], m_data3[-16:], validation=True) #M knows the message (DONE) print("Retrieved by M (scenario 2):", msg_m) ################################################################################ ###### MITM attack - Scenario 03: g = p-1 ################################################################################ #User A generates A a = randint(0, p) A = pow(g, a, p) #User A sends (p,g,A) to M m_data = (p, g, A) #Use M send (p,g,A) to M g_m = p - 1 b_data = (p, g_m, A) #User B generates B b = randint(0, b_data[0]) B = pow(b_data[1], b, b_data[0]) #(p-1)^x % p == (-1)^x % p # if x is even: 1, if x is odd, p-1 #User B sends B to M m_data2 = B a_data = m_data2 #sending the information forward #User A calculates s, iv, key and encrypt a message #print a_data s_a = pow(a_data, a, p) #s_a is either p-1 or 1 #print s_a iv_a = random_aes_key(16) msg_a = bytearray("Super Secret Stuff123", "ascii") #print hex(s_a) key_a = sha1(int_to_bytes(s_a))[:16] aes_ecb_a = AES.new(key_a, AES.MODE_ECB) enc_a = cbc_encrypt(aes_ecb_a, msg_a, iv_a) #User A sends encrypted message and iv to M m_data3 = enc_a + iv_a #M can calculate both possible keys and decrypt the message: key_m1 = sha1(b'\x01')[:16] key_m2 = sha1(int_to_bytes(g_m))[:16] for key_m in (key_m1, key_m2): aes_ecb_m = AES.new(key_m, AES.MODE_ECB) try: msg_m = cbc_decrypt(aes_ecb_m, m_data3[:-16], m_data3[-16:], validation=True) #M knows the message (DONE) except: #this is me being lazy. Note that it might break if the wrong key decrypts some garbage with the right padding pass print("Retrieved by M (scenario 3):", msg_m)
print("Size of random string:", size_random_string) offset = (-size_random_string % blocksize) padding = "X" * offset print("Length of padding:", len(padding), "\n") #Retrieving unknown text: table = [ encryption_oracle(padding + "B" * (blocksize - i)) for i in range(1, blocksize + 1) ] secret = "" skip = int((offset + size_random_string) / blocksize) for j in range(skip, len(table[-1])): for i in range(1, blocksize + 1): cipher = table[i - 1][j * blocksize:(j + 1) * blocksize] for c in range(256): temp = encryption_oracle(padding + "B" * (blocksize - i) + secret + chr(c))[j * blocksize:(j + 1) * blocksize] if temp == cipher: secret += chr(c) break print(secret) KEY = random_aes_key(16) main()
def main(): p = 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff g = 2 #User A generates A a = randint(0,p) A = pow(g, a, p) #User A sends (p,g,A) to B b_data = (p,g,A) #User B generates B b = randint(0,b_data[0]) B = pow(b_data[1], b, b_data[0]) #User B sends B to A a_data = B #User A calculates s, iv, key and encrypt a message s_a = pow(a_data, a, p) iv_a = random_aes_key(16) msg_a = bytearray("Super Secret Stuff123","ascii") key_a = sha1(int_to_bytes(s_a))[:16] aes_ecb_a = AES.new(key_a, AES.MODE_ECB) enc_a = cbc_encrypt(aes_ecb_a, msg_a, iv_a) #test = cbc_decrypt(aes_ecb_a, enc_a, iv_a) #print test #User A sends encrypted message and iv to B b_data2 = enc_a+iv_a #User B calculates s, key, retrieves iv and decrypts the message: s_b = pow(b_data[2],b,p) #print s_a == s_b key_b = sha1(int_to_bytes(s_b))[:16] aes_ecb_b = AES.new(key_b, AES.MODE_ECB) msg_b = cbc_decrypt(aes_ecb_b,b_data2[:-16],b_data2[-16:],validation=True) #User B generates an IV, encrypts the message retrieved and send it with the IV to A iv_b = random_aes_key(16) enc_b = cbc_encrypt(aes_ecb_b, msg_b, iv_b) a_data2 = enc_b+iv_b #A gets the iv, decrypts the data and verify the message: msg_temp = cbc_decrypt(aes_ecb_a,a_data2[:-16],a_data2[-16:],validation=True) print (msg_a == msg_temp) ################################################################################ ###### MITM attack ################################################################################ #User A generates A a = randint(0,p) A = pow(g, a, p) #User A sends (p,g,A) to M m_data = (p,g,A) #Use M send (p,g,p) to M b_data = (m_data[0],g,m_data[0]) #User B generates B b = randint(0,b_data[0]) B = pow(b_data[1], b, b_data[0]) #User B sends B to M m_data2 = B #User M sends p to A a_data = p #User A calculates s, iv, key and encrypt a message s_a = pow(a_data, a, p) # (p ** a) % p == (0 ** a) % p == 0 iv_a = random_aes_key(16) msg_a = bytearray("Super Secret Stuff123","ascii") print (hex(s_a)) key_a = sha1(int_to_bytes(s_a))[:16] aes_ecb_a = AES.new(key_a, AES.MODE_ECB) enc_a = cbc_encrypt(aes_ecb_a, msg_a, iv_a) #test = cbc_decrypt(aes_ecb_a, enc_a, iv_a) #print test #User A sends encrypted message and iv to M m_data3 = enc_a+iv_a #User M relays message to B b_data2 = m_data3 #User B calculates s, key, retrieves iv and decrypts the message: s_b = pow(b_data[2],b,p) #print s_a == s_b key_b = sha1(int_to_bytes(s_b))[:16] aes_ecb_b = AES.new(key_b, AES.MODE_ECB) msg_b = cbc_decrypt(aes_ecb_b,b_data2[:-16],b_data2[-16:],validation=True) #User B generates an IV, encrypts the message retrieved and send it with the IV to M iv_b = random_aes_key(16) enc_b = cbc_encrypt(aes_ecb_b, msg_b, iv_b) m_data4 = enc_b+iv_b #User M relays message to A a_data2 = m_data4 #A gets the iv, decrypts the data and verify the message: msg_temp = cbc_decrypt(aes_ecb_a,a_data2[:-16],a_data2[-16:],validation=True) print (msg_a == msg_temp) #M can decrypt the message as well: key_m = sha1(b'\x00')[:16] aes_ecb_m = AES.new(key_m, AES.MODE_ECB) msg_m = cbc_decrypt(aes_ecb_m,m_data4[:-16],m_data4[-16:],validation=True) print (msg_a == msg_m)