def chall_two_phase_1(p, g): # Alice and Bob generate private keys a, b = random.randint(0, p), random.randint(0, p) # Alice and Bob sends public messages A, B = modexp(g,a,p), modexp(g,b,p) print(f"These are public info! \np: \t\t\t{hex(p)} \ng: {g}\nAlice public key: \t{hex(A)}\nBob public key: \t{hex(B)}") # Now, generate shared secret S by computing # S == A^b == B^a S = modexp(A,b,p) bytes_S = hex(S)[2:].encode() assert S == modexp(B,a,p), "Shared secret miscomputed" # 1a) Preparing to send Bob the message iv_a = get_random_int(128) sha_S = sha1(bytes_S,len(bytes_S)*8) print(f"shared secret is: {S}") shared_S = sha_S[2:][:32] alice_msg = "This is the password. Pass it on!".encode().hex() alice_encrypt = cbc_encrypt(alice_msg, shared_S, iv_a) + iv_a print(f"Here is my (alice's) encrypted text: \t\t{alice_encrypt}") print("\n~~~~~SENDING MESSAGE~~~~~~ PLS NO INTERCEPT ~~~~~") print("~~~~~BUT EVEN IF YOU DO THIS IS UNHAXABLE~~~~~~~~\n") # 1b) Bob receives the message # Confirming that Bob received the message from Alice correctly iv_b = alice_encrypt[-32:] alice_ciphertext = alice_encrypt[:-32] bob_decrypt = cbc_decrypt(alice_ciphertext, shared_S, iv_b) padding = int(bob_decrypt[-1], 16)*2 bob_decrypt = bob_decrypt[:-padding] assert bob_decrypt == alice_msg iv_b = get_random_int(128) bob_encrypt = cbc_encrypt(bob_decrypt, shared_S, iv_b) + iv_b print(f"Thanks! Here is my (bob's) encrypted text: \t{bob_encrypt}") # 2) Bob sending message back to Alice iv_b = bob_encrypt[-32:] bob_ciphertext = bob_encrypt[:-32] alice_decrypt = cbc_decrypt(bob_ciphertext, shared_S, iv_b) padding = int(alice_decrypt[-1], 16)*2 alice_decrypt = alice_decrypt[:-padding] assert alice_decrypt == alice_msg return alice_encrypt, bob_encrypt
def honest_server(): salt = get_random_int(32) xH = hashlib.sha256(salt.encode() + creds['pass'].encode()) x = int(xH.hexdigest(), 16) DB.v = modexp(g, x, N) # DB server state DB.salt = salt DB.b = random.randint(0, N) DB.serverKey = modexp(g, DB.b, N) DB.u = int(get_random_int(128), 16) return "OK", 200
def main(): key = get_random_int(16) msg = "attack at dawn" prefix = ''.join([ random.choice(string.ascii_letters + string.digits) for n in range(random.randint(0, 100)) ]) crafted_msg = prefix + msg ciphertext = encrypt(key, crafted_msg.encode().hex()) plaintext = decrypt(key, ciphertext) assert plaintext == crafted_msg.encode().hex() print("Encryption/decryption work correctly") guessed_key = find_16b_mt19937_key("attack at dawn", ciphertext) print(guessed_key) assert guessed_key == int(key, 16) # Now get current time and restrict it to 16 bits import time current_time = int(time.time()) % (2**16) seed_mt(current_time) reset_token = extract_number() msg = "password_reset=" + str(reset_token) from set3.chall_six import get_mt_seed prev_time = get_mt_seed(int(time.time()) % (2**16), reset_token) seed_mt(prev_time) assert reset_token == extract_number() print("Reset token found!")
from set1.chall_six import * from set1.chall_three import xor_single_byte from set1.chall_two import xor_hex_strings from set2.chall_three import get_random_int from set3.chall_two import aes_ctr_operation key = get_random_int(128) nonce = get_random_int(64) ciphertexts = [] def encrypt_lines(lines): for pt in lines: msg = base64.b64decode(pt.strip()) ciphertexts.append(aes_ctr_operation(key, msg.hex(), nonce)) # code ripped from set1.chall_six # I definitely could've made this a function in six... but I didn't def main(): with open('20.txt', 'r') as f: plaintext = f.readlines() encrypt_lines(plaintext) #print(ciphertexts) block_len = len(min(ciphertexts, key=len)) blocks = [ctext[:block_len] for ctext in ciphertexts] potential_keys = [] transposed_blocks = transpose_blocks(bytes.fromhex(''.join(blocks)), int(block_len / 2))
import base64, random encoded_array = [ 'MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=', 'MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=', 'MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==', 'MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==', 'MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl', 'MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==', 'MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==', 'MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=', 'MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=', 'MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93' ] oracle_key = get_random_int(128) oracle_iv = get_random_int(128) rand_msg = encoded_array[random.randint(0, 9)] def encryption_oracle(msg): return (cbc_encrypt(msg, oracle_key, oracle_iv), oracle_iv) def decryption_oracle(ciphertext, iv): plaintext = cbc_decrypt(ciphertext, oracle_key, iv) try: unpadded_data = pkcs7_unpad(bytes.fromhex(plaintext)) return True except: return False
from set2.chall_three import get_random_int, detect_ecb import base64 from set2.chall_one import pkcs7_pad from set1.chall_seven import aes_ecb_encrypt_with_key key = get_random_int(128) def generic_encrypt_ecb(msg, key, block_size): (ciphertext, CipherObj) = aes_ecb_encrypt_with_key( bytes.fromhex(pkcs7_pad(msg, block_size)), bytes.fromhex(key)) return ciphertext.hex() def find_cipher_block_size(unknown_string): padded_lengths = [] for i in range(0, 64): rand_str = ("A" * i).encode().hex() try: (ciphertext, CipherObj) = aes_ecb_encrypt_with_key( bytes.fromhex(rand_str + unknown_string), bytes.fromhex(key)) padded_lengths.append(i) except ValueError: pass #print(f"Invalid block length {i}; trying next length") return padded_lengths def padding_oracle(unknown_hex, block_size, prefix): # added "prefix" arg to make challenge six easier
def main(): p = 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff g = 2 # Alice and Bob generate private keys a, b = random.randint(0, p), random.randint(0, p) # Alice and Bob sends public messages A, B = modexp(g,a,p), modexp(g,b,p) print(f"These are public info! \np: \t\t\t{hex(p)} \ng: {g}\nAlice public key: \t{hex(A)}\nBob public key: \t{hex(B)}") # Now, generate shared secret S by computing # S == A^b == B^a S = modexp(A,b,p) bytes_S = hex(S)[2:].encode() assert S == modexp(B,a,p), "Shared secret miscomputed" # 1a) Preparing to send Bob the message iv_a = get_random_int(128) sha_S = sha1(bytes_S,len(bytes_S)*8) print(f"shared secret is: {S}") shared_S = sha_S[2:][:32] alice_msg = "This is the password. Pass it on!".encode().hex() alice_encrypt = cbc_encrypt(alice_msg, shared_S, iv_a) + iv_a print(f"Here is my (alice's) encrypted text: \t\t{alice_encrypt}") print("\n~~~~~SENDING MESSAGE~~~~~~ PLS NO INTERCEPT ~~~~~") print("~~~~~BUT EVEN IF YOU DO THIS IS UNHAXABLE~~~~~~~~\n") # 1b) Bob receives the message # Confirming that Bob received the message from Alice correctly iv_b = alice_encrypt[-32:] alice_ciphertext = alice_encrypt[:-32] bob_decrypt = cbc_decrypt(alice_ciphertext, shared_S, iv_b) padding = int(bob_decrypt[-1], 16)*2 bob_decrypt = bob_decrypt[:-padding] assert bob_decrypt == alice_msg iv_b = get_random_int(128) bob_encrypt = cbc_encrypt(bob_decrypt, shared_S, iv_b) + iv_b print(f"Thanks! Here is my (bob's) encrypted text: \t{bob_encrypt}") # 2) Bob sending message back to Alice iv_b = bob_encrypt[-32:] bob_ciphertext = bob_encrypt[:-32] alice_decrypt = cbc_decrypt(bob_ciphertext, shared_S, iv_b) padding = int(alice_decrypt[-1], 16)*2 alice_decrypt = alice_decrypt[:-padding] assert alice_decrypt == alice_msg """ PHASE 2 """ print("~~~~~~~~~~~~~~~~~~~~~~~~~~") print(" PHASE 2 ") print("~~~~~~~~~~~~~~~~~~~~~~~~~~") # if A == B == p, keys are just 0 since p^k mod p == 0 A, B = modexp(g,a,p), modexp(g,b,p) M_A, M_B = p, p S = modexp(M_A,b,p) bytes_S = hex(S)[2:].encode() print(f"shared secret is: {S}") assert S == modexp(M_B,a,p) sha_S = sha1(bytes_S,len(bytes_S)*8) print(f"shared secret is: {S}") shared_S = sha_S[2:][:32] """
from set2.chall_four import generic_encrypt_ecb, padding_oracle from set2.chall_three import get_random_int, detect_ecb import base64, random from set2.chall_one import pkcs7_pad from set1.chall_seven import aes_ecb_encrypt_with_key key = get_random_int(128) def generic_encrypt_ecb_wrapper(rand_bits, attacker_bits, target, block_size): return generic_encrypt_ecb(rand_bits + attacker_bits + target, key, block_size) rand_prefix = 0 while 1: rand_bit_size = random.randint(1, 128) if rand_bit_size % 8 == 0: rand_prefix = get_random_int(rand_bit_size) break # in chall 4 we blanketly had multiple blocks: here, we should do it systematically to figure out length of random prefix prefix_len = 0 target = "attack at dawnBBBBBBBBBBBBBBBBB".encode().hex() my_string = '' for i in range(32, 48): my_string = ("A" * i).encode().hex() #my_string = "YELLOW_SUBMARINE".encode().hex() ciphertext = generic_encrypt_ecb_wrapper(rand_prefix, my_string, target, 16)