def func1(rand_key, rand_iv, userdata): plainbuf = generate_str(userdata) plainbuf_padded = challenge9.pkcs7_pad(16, plainbuf) encbuf = challenge10.encrypt_aes_128_cbc(rand_key, rand_iv, plainbuf_padded) return encbuf
def aes_cbc_encrypt(k, pt, iv): """ Encrypts a message using AES in CBC mode. Pads as necessary using PKCS#7. @param k [str]: ASCII key @param pt [str]: ASCII PT string @param iv [str]: Initialization vector @returns [str]: ASCII CT string """ def ecb_encrypt(k, pt): """ Encrypts a message using AES in ECB mode (assume the input is padded to the block size). """ cipher = Cipher(algorithms.AES(k), modes.ECB(), backend=default_backend()) encryptor = cipher.encryptor() return encryptor.update(pt) + encryptor.finalize() padded_pt = pkcs7_pad(pt, len(k)) pt_list = [ padded_pt[i:i + len(k)] for i in range(0, len(padded_pt), len(k)) ] ct_list = [iv] for i in range(len(pt_list)): ct_list.append(ecb_encrypt(k, xorstr(ct_list[-1], pt_list[i]))) return ''.join(ct_list[1:]) # Remove the IV
def encryption_oracle(random_prefix, attacker_controlled, target_bytes, random_key): plainbuf = random_prefix + attacker_controlled + target_bytes padded_plainbuf = challenge9.pkcs7_pad(16, plainbuf) encbuf = challenge7.encrypt_aes_128_ecb(random_key, padded_plainbuf) return encbuf
def f(x): if type(x) == str: x = bytearray(x, 'utf-8') unknown_str_b64 = "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK" unknown_str = b64_to_bytes(unknown_str_b64) new_pt = pkcs7_pad(x + unknown_str, BLK_SZ) return encrypt_aes_ecb(new_pt, KEY)
def __profile_encrypt(self, username): """ :return: encrypted profile to send out to client """ prof_str = self.__profile_for(username.decode()) profile = challenge9.pkcs7_pad(prof_str.encode("utf-8"), 16) ctext = self.__cipher.encrypt(profile) return ctext
def aes_encryption_oracle(text, key): # Given in the challenge secret_string = base64.b64decode( b'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg' b'aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq' b'dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg' b'YnkK') cipher = AES.new(key, AES.MODE_ECB) return cipher.encrypt(pkcs7_pad(text + secret_string, 16))
def aes_ecb_encrypt(k, pt): """ Encrypts a message using AES in ECB mode. Pads as necessary using PKCS#7. @param k [str]: key @param pt [str]: PT (ASCII string) @returns [str]: CT (ASCII string) """ padded_pt = pkcs7_pad(pt, len(k)) cipher = Cipher(algorithms.AES(k), modes.ECB(), backend=default_backend()) encryptor = cipher.encryptor() return encryptor.update(padded_pt) + encryptor.finalize()
def encrypt(self, plaintext): """ Create URL string, adding prefix, postfix comments :return: encrypted URL result. """ # prevent user from creating a ;admin=true; string plaintext.replace(b";", b"") plaintext.replace(b"=", b"") plaintext.replace(b"&", b"") text = self._prefix + plaintext + self._postfix #print(text) #print(pkcs7_pad(text, 16)) return self._cipher.encrypt(pkcs7_pad(text, 16))
def encrypt(): """ provide encrypted phrase to client via JSON """ token = random.choice(tokens) IV = os.urandom(16) global KEY KEY = os.urandom(16) cipher = AES.new(KEY, AES.MODE_CBC, IV) token = challenge9.pkcs7_pad(token, 16) ciphertext = cipher.encrypt(token) data, iv = base64.b64encode(ciphertext), base64.b64encode(IV) return json.dumps([{"token": data.decode()}, {"IV": iv.decode()}])
def encrypt(self, text): ciphertext = [] plaintext = [ text[i:i + self.__bsize] for i in range(0, len(text), self.__bsize) ] if len(plaintext[0]) != self.__bsize: plaintext[0] = pkcs7_pad(plaintext[0], self.__bsize) block = xor(plaintext[0], self.__IV) ciphertext.append(self.__cipher.encrypt(block)) for p in plaintext[1:]: if len(p) != self.__bsize: p = pkcs7_pad(p, self.__bsize) block = xor(p, ciphertext[-1]) ciphertext.append(self.__cipher.encrypt(block)) output = b"" for c in ciphertext: output += c return output
def encryption_oracle(input): prefix = bytes(urandom(randint(5, 10))) suffix = bytes(urandom(randint(5, 10))) to_encrypt = pkcs7_pad(prefix + input + suffix, 16) random_aes_key = urandom(16) if (choice([True, False])): cipher = AES.new(random_aes_key, AES.MODE_ECB) aes_mode = 'ECB' else: iv = urandom(16) cipher = AES.new(random_aes_key, AES.MODE_CBC, iv) aes_mode = 'CBC' ciphertext = cipher.encrypt(to_encrypt) return ciphertext, aes_mode
def f1(s): # quote out ; and = in s s = s.replace(';', '";"') s = s.replace('=', '"="') res = PREPEND + s + APPEND # pad res_padded = pkcs7_pad(res, BLK_SZ) # encrypt under random AES key k = gen_aes_key() iv = secrets.token_bytes(BLK_SZ) res_enc = aes_cbc_encrypt(res_padded, k, iv) return k, res_enc, iv
def attacker(): # generate input such that last block contains only user email = "A" * 13 victim = profile_for(email) assert len(profile_for(email[5:])) < len(victim) target_block = pkcs7_pad("admin", BLK_SZ) # spray email=\x00...|admin__pad__|.... email_spray = bytearray([0 for _ in range(10)]) + target_block evil = profile_for(email_spray.decode('utf-8')) evil_blk = evil[BLK_SZ:2 * BLK_SZ] # copy and paste victim = victim[:-BLK_SZ] victim += evil_blk return victim
def aes_cbc_encrypt(key, iv, stream): fail_msg = "stream should be a multiple of %d, size actually: %d" \ % (BLOCK_SIZE_IN_BYTES, len(stream)) assert len(stream) % BLOCK_SIZE_IN_BYTES == 0, fail_msg blocks = block_split(stream) result = [] for idx, pt_block in enumerate(blocks): last_block = iv if idx == 0 else result[-1] # pad block if its too small... # TODO: should only be needed on the last block if len(pt_block) < BLOCK_SIZE_IN_BYTES: pt_block = pkcs7_pad(pt_block, BLOCK_SIZE_IN_BYTES) ct_block = aes_ecb_encrypt(key, repeating_xor(last_block, pt_block)) result.append(ct_block) return bytes().join(result)
def encryption_oracle(plaintext): rand_key = get_rand_bytes(16) rand_size1 = random.randint(5, 10) rand_buf1 = get_rand_bytes(rand_size1) rand_size2 = random.randint(5, 10) rand_buf2 = get_rand_bytes(rand_size2) plainbuf = rand_buf1 + plaintext + rand_buf2 plainbuf_padded = challenge9.pkcs7_pad(16, plainbuf) if random.randrange(2): mode = "ecb" encbuf = challenge7.encrypt_aes_128_ecb(rand_key, plainbuf_padded) else: mode = "cbc" rand_iv = get_rand_bytes(16) encbuf = challenge10.encrypt_aes_128_cbc(rand_key, rand_iv, plainbuf_padded) return encbuf, mode
def _handle_client(self, conn): """ Give client encrypted data, which is in the form: length_of_message (little endian) || encrypted data. :param conn: socket object to talk to client """ print("[*] Got client: waiting for text to encrypt") text = self._get_response(conn) print("[*] Got plaintext, encrypting...") # AES(user_text || unknown text) text += self._unknown new_text = pkcs7_pad(text, 16) ctext = self._cipher.encrypt(new_text) clen = struct.pack("I", int(len(ctext))) conn.send(clen) conn.send(ctext) print("[*] Sent encrypted data, closing") conn.close()
def aes_cbc_encrypt(plaintext, key, iv): blocksize = 16 prev_block = iv ciphertext = b'' blocks = [ plaintext[i:i + blocksize] for i in range(0, len(plaintext), blocksize) ] # Mode is ECB, no cheating :) cipher = AES.new(key, AES.MODE_ECB) for block in blocks: if (len(block) < blocksize): block = pkcs7_pad(block, blocksize) combined_block = xor(block, prev_block) cipher_block = cipher.encrypt(combined_block) prev_block = cipher_block ciphertext += cipher_block return ciphertext
def aes_cbc_encrypt(pt, key, iv): # pad if needed pt_padded = pkcs7_pad(pt, BLK_SZ) pt_chunks = chunk(pt_padded, BLK_SZ) prev_blk = iv ct_blks = [] for pt_blk in pt_chunks: # xor with prev blk pt_xored = xor(prev_blk, pt_blk) # ECB encrypt ct_blk = encrypt_aes_ecb(pt_xored, key) ct_blks.append(ct_blk) # store as prev blk prev_blk = ct_blk ct_s = functools.reduce(lambda a, b: a + b, ct_blks) return ct_s
def encryption_oracle(x): if type(x) == str: x = bytearray(x, "utf-8") bytes_append_len = 5 + secrets.randbelow(6) bytes_prepend_len = 5 + secrets.randbelow(6) bytes_appended = bytearray(secrets.token_bytes(bytes_append_len)) bytes_prepended = bytearray(secrets.token_bytes(bytes_prepend_len)) pt = pkcs7_pad(bytes_prepended + x + bytes_appended, 16) encryption_scheme = secrets.randbelow(2) if (encryption_scheme == ECB_MODE): # do ECB ct = encrypt_aes_ecb(pt, gen_aes_key()) elif (encryption_scheme == CBC_MODE): # do CBC ct = aes_cbc_encrypt(pt, gen_aes_key(), secrets.token_bytes(BLK_SZ)) return ct, encryption_scheme
def func1(key): strings = [ "MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=", "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=", "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==", "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==", "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl", "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==", "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==", "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=", "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=", "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93" ] choice = base64.b64decode(random.choice(strings)) choice_padded = challenge9.pkcs7_pad(16, choice) iv = challenge11.get_rand_bytes(16) ciphertext = challenge10.encrypt_aes_128_cbc(key, iv, choice_padded) return choice, ciphertext, iv
def encryption_oracle(text): # random key key = os.urandom(16) # random encryption flip = random.randint(0, 1) if flip: IV = os.urandom(16) cipher = AES_CBC(key, IV) cbc = True else: cipher = AES.new(key, AES.MODE_ECB) cbc = False prefix = random.randint(5, 10) postfix = random.randint(5, 10) random_text = os.urandom(prefix + postfix) new_text = random_text[:prefix] + text + random_text[postfix:] end = len(new_text) % 16 pad = pkcs7_pad(new_text[-end:], 16) new_text = new_text[:-end] + pad return (cipher.encrypt(new_text), cbc)
def create_admin(pt, ct): """ Consider the CBC decryption algorithm: P_i = D_k(C_i) XOR C_i-1; C_0 = IV for all blocks i We wish to construct a modified CT C' that when decrypted gives us the desired string ';admin=true;'. So, if we were to find C' such that the ith block would contain P_i' = ';admin=true;\x04\x04\x04\x04', we need to find C'_i-1 = P_i' XOR D_k(C_i). Since P_i = D_k(C_i) XOR C_i-1 and we have both P and C (and hence P_i and C_i-1), we can rewrite D_k(C_i) = P_i XOR C_i-1. So, C'_i-1 = P_i' XOR P_i XOR C_i-1. Assume we know the blocksize is 16 bytes. """ blocksize = 16 idx = 2 # Rewrite the second block of the CT to produce a PT with a # scrambled second block and our target 3rd block. idx is i-1 block_text = pkcs7_pad(';admin=true;', blocksize) ct_blocks = [ct[i:i + blocksize] for i in range(0, len(ct), blocksize)] pt_blocks = [pt[i:i + blocksize] for i in range(0, len(pt), blocksize)] ct_new_block = xorstr(xorstr(block_text, pt_blocks[idx + 1]), ct_blocks[idx]) ct_blocks[idx] = ct_new_block return ''.join(ct_blocks)
def decrypt_profile(key, enc_profile): plain_profile = challenge7.decrypt_aes_128_ecb(key, enc_profile) unpadded_profile = challenge9.pkcs7_unpad(16, plain_profile) return unpadded_profile if __name__ == "__main__": random_key = challenge11.get_rand_bytes(16) enc_blocks = [] input1 = "A" * 13 enc_profile1 = encrypt_profile(random_key, profile_for(input1)) # first 2 encrypted blocks decrypt to: # email=AAAAAAAAAAAAA&uid=10&role= enc_blocks.append(enc_profile1[:32]) input2 = "A" * (16 - len("email=")) + challenge9.pkcs7_pad(16, "admin") enc_profile2 = encrypt_profile(random_key, profile_for(input2)) # second encrypted block decrypts to: # admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b enc_blocks.append(enc_profile2[16:32]) new_enc_profile = "".join(enc_blocks) plain_profile = decrypt_profile(random_key, new_enc_profile) print plain_profile profile_obj = kv_parse(plain_profile) print profile_obj
def profile_for(x): x = x.replace("&", "") x = x.replace("=", "") d = {'email': x, 'uid': 10, 'role': 'user'} return encrypt_aes_ecb(pkcs7_pad(obj_to_qs(d), BLK_SZ), KEY)
def encrypt_profile(key, profile): padded_profile = challenge9.pkcs7_pad(16, profile) enc_profile = challenge7.encrypt_aes_128_ecb(key, padded_profile) return enc_profile