def decipher_block(iv, block): predict = ['\x00'] * 16 for i in xrange(15, -1, -1): for c in xrange(0, 256): predict[i] = chr(c) padding = (chr(16 - i) * (16 - i)).rjust(16, '\x00') new_iv = crypty.xor_hex_strings( crypty.xor_ascii_strings("".join(predict), crypty.h2a(iv)), crypty.a2h(padding)) if padding_oracle(block, new_iv): if i == 15: # Recheck for the correctness of found byte, whether its a genioun padding at the end or just random thing. flag = False for ch in xrange(0, 256): new_iv = crypty.xor_hex_strings( crypty.xor_ascii_strings( "".join(['\x00'] * 14) + chr(ch) + chr(c), crypty.h2a(iv)), crypty.a2h("\x00" * 14 + "\x02\x02")) if padding_oracle(block, new_iv): flag = True break if flag: break else: break return "".join(predict).encode("hex")
def findCollision(message, prefix): extra = (7 - len(prefix))%16 if extra == 0: extra = 16 for extraPadding in itertools.product([chr(c) for c in xrange(0x30, 0x7b)], repeat=extra): new_prefix = prefix + "".join(list(extraPadding)) print new_prefix prefixHash = h2a(hash(new_prefix)) mid_part = h2a(xor_ascii_strings(prefixHash, message[:16])) if not all(ord(c)>=32 and ord(c)<127 for c in mid_part): continue mal_message = h2a(pad_pkcs_7(a2h(new_prefix)) + h2a(xor_ascii_strings(prefixHash, message[:16])) + message[16:] return mal_message return "" def solver(): message = "alert('MZA who was that?');\n" h = hash(message) prefix = b"alert('Ayo, the Wu is back!'); //" collision = findCollision(message, prefix) print "[+] Found one." print a2h(collision) return if __name__=='__main__': solver()
def get_initial_size(): default_len = len(crypty.h2a(encryption_oracle(crypty.a2h('')))) for i in xrange(1, 17): plaintext = crypty.a2h('A' * i) length = len(crypty.h2a(encryption_oracle(plaintext))) if length is not default_len: return default_len - i return None
def get_block_size(): default_len = len(crypty.h2a(encryption_oracle(crypty.a2h('')))) for i in xrange(1, 40): plaintext = crypty.a2h('A' * i) length = len(crypty.h2a(encryption_oracle(plaintext))) if length is not default_len: return length - default_len return None
def solve(): try: print crypty.h2a(crypty.unpad_pkcs_7(crypty.a2h("ICE ICE BABY\x04\x04\x04\x04"))) except Exception as e: print e try: print crypty.h2a(crypty.unpad_pkcs_7(crypty.a2h("ICE ICE BABY\x05\x05\x05\x05"))) except Exception as e: print e
def encrypt(plaintext, key): """ Encrypts plaintext with key using AES-128-ECB Provide Padded plaintext to encrypt, aligned with blocksize = 16 :param plaintext: hex string :param key: hex string :return: hex string """ encrypter = AES.new(crypty.h2a(key), AES.MODE_ECB) return crypty.a2h(encrypter.encrypt(crypty.h2a(plaintext)))
def generateCollision(hashFn, iv, depth): hash, m1, m2 = findOneBlockCollision(hashFn, iv, (h2a(i2h(i)).ljust(8, '\x00') for i in range(0, 2**16))) collisions = [m1, m2] for i in xrange(5): hash, m1, m2 = findOneBlockCollision(hashFn, hash, (h2a(i2h(i)).ljust(8, '\x00') for i in range(0, 2**16))) collisions = [collisions[0] + m1, collisions[1] + m2] return
def check_key(hex_cipher, key, score_calculator): """ Checks if a particular key for xor cipher is correct or not. :param hex_cipher: hex string :param key: hex string :param score_type: either ascii or raw :return: tuple of probability score and key """ plaintext = crypty.xor_rep_hex_strings(hex_cipher, key) score = score_calculator(crypty.h2a(plaintext)) return (score, key, crypty.h2a(plaintext))
def decrypt(ciphertext, key): """ Decrypts ciphertext with key using AES-128-ECB Doesn't remove padding from decrypted string :param ciphertext: hex string :param key: hex string :return: hex string """ decrypter = AES.new(crypty.h2a(key), AES.MODE_ECB) plaintext = crypty.a2h(decrypter.decrypt(crypty.h2a(ciphertext))) return plaintext
def solve(): ciphertext = crypty.convert_b64_to_hex(get_ciphertext()) ## Test to check hamming distance assert crypty.hamming_distance(crypty.a2h("this is a test"), crypty.a2h("wokka wokka!!!")) == 37 key_size = xor_cipher.attacks.keysize_estimator(ciphertext, 2, 40)[0][1] print "Trying for key size: %d" % (key_size) key = xor_cipher.attacks.brute_force(ciphertext, key_len=key_size) print "Found Key : %d : %s" % (len(crypty.h2a(key)), crypty.h2a(key)) plaintext = xor_cipher.infra.decrypt(ciphertext, key) print "Plaintext : %s" % (crypty.h2a(plaintext))
def solver(): enc1, e1, n1 = RSA("A"*20) enc2, e2, n2 = RSA("A"*20) enc3, e3, n3 = RSA("A"*20) result = e_3_broadcast_attack((enc1, e1, n1), (enc2, e2, n2), (enc3, e3, n3)) assert h2a(format(result, "x")) == "A"*20 return
def decrypt_profile(ciphertext, key): plaintext = ecb_cipher.infra.decrypt(ciphertext, key) plaintext = crypty.h2a(crypty.unpad_pkcs_7(plaintext)) pairs = plaintext.split("&") profile = [] for p in pairs: profile.append([ x.encode("ascii") for x in p.split("=") ]) return profile
def MDFunction1(plaintext, IV, pad=True): hash = simplePadIVFn(IV) if pad: plaintext = simplePadMessageFn(plaintext) for block in get_blocks(a2h(plaintext), block_size=8): block = h2a(block) hash = simpleHashFn(block, hash) return hash
def hamming_distance_normalised(str1, str2): """ Calculates Hamming distance between two strings and returns the probability :param str1: hex string :param str2: hex string :return: 0<=p<=8 """ return crypty.hamming_distance(str1, str2) / float(len(crypty.h2a(str1)))
def solve(): ciphertexts = get_ciphertexts() min_len = min([len(c) for c in ciphertexts]) ciphertexts = [c[:min_len] for c in ciphertexts] print "[+]Key Size : %d" % (min_len) key = xor_cipher.attacks.brute_force("".join(ciphertexts), key_len=min_len) print "[+]Found Key : %s" % (key) plaintext = xor_cipher.infra.decrypt("".join(ciphertexts), key) print "Partial Plaintext : %s" % (crypty.h2a(plaintext))
def verifySignature(message, signature, e, N): block = b'\x00' + h2a(i2h(encrypt(signature, e, N))) print a2h(block) r = re.compile(b'\x00\x01\xff+?\x00(.{40})', re.DOTALL) m = r.match(block) if not m: return False digest = m.group(1) return digest == getSHA1(message)
def solve(): fp = open("4.txt","r") result = [] lines = fp.readlines() for idx,line in enumerate(lines): line = line.strip() key = xor_cipher.attacks.brute_force(line, key_len=1) plaintext = crypty.h2a(xor_cipher.infra.decrypt(line, key)) if all(c in string.printable for c in plaintext): result.append(plaintext) print "Line : %d : Length : %d Plaintext : %s" %(idx,len(result[-1]),result[-1]) return result
def get_cipher_indexes(hex_cipher, idx, key_len): """ Returns a string of all char at index idx in all blocks :param hex_cipher: hex string :param idx: int :return: hex string """ raw_cipher = crypty.h2a(hex_cipher) result = "" for start in xrange(0, len(raw_cipher), key_len): block = raw_cipher[start:start + key_len] if idx >= len(block): break result += block[idx] return crypty.a2h(result)
def encrypt(plaintext, key, nounce): """ Encrypts plaintext using AES-128-CTR Block Cipher :param plaintext: Hex string :param key: Hex string :param nounce: int :return: Hex string """ plaintext = crypty.h2a(plaintext) nounce_little_endian = struct.pack("<q",nounce) keystream = [] for ctr in xrange(len(plaintext)/16 + 1): ctr_little_endian = struct.pack("<q",ctr) keystream.append(ecb_cipher.infra.encrypt(crypty.a2h(nounce_little_endian+ctr_little_endian), key)) keystream = "".join(keystream)[:len(plaintext)*2] return crypty.xor_hex_strings(keystream, crypty.a2h(plaintext))
def encrypt_manual(hex_string, key, iv): """ Manually AES-128-CBC Encrypts the input hex string using key, iv and AES-128-ECB :param hex_string: Hex string :param key: Hex string :param iv: Hex string :return: hex string """ assert len(iv) == len(key) blocks = crypty.get_blocks(hex_string, block_size=16) ciphertext = "" for block in blocks: if len(crypty.h2a(block)) % 16 is not 0: block = crypty.pad_pkcs_7(block, block_size=16) xor_block = crypty.xor_hex_strings(block, iv) iv = ecb_cipher.infra.encrypt(xor_block, key) ciphertext += iv return ciphertext
def solve(): ciphertext = crypty.convert_b64_to_hex(get_ciphertext()) key = crypty.a2h("YELLOW SUBMARINE") plaintext = crypty.h2a(aes_ecb.infra.decrypt(ciphertext, key)) print plaintext
def simplePadMessageFn(message_hex): return h2a(pad_pkcs_7(message_hex, block_size=8))
def solve(): ciphertext = crypty.convert_b64_to_hex(get_ciphertexts()) key = crypty.a2h("YELLOW SUBMARINE") iv = crypty.a2h("\x00" * 16) print crypty.h2a(aes_cbc.infra.decrypt_manual(ciphertext, key, iv))