def main(): # Server sends base, prime and k data = requests.get('http://127.0.0.1:5000/').json() prime, base, k = data['prime'], data['base'], data['k'] # Client and server exchange public keys, but the server sends 0 as its public #key. email = b'*****@*****.**'.decode() #Test a few bad public keys which are all 0 mod prime. These allow us to #login without knowing the password for bad_public_key in [0, prime, prime**2, 4 * prime]: server_response = requests.post('http://127.0.0.1:5000/', data={ 'email': email, 'dhA': bad_public_key }).json() #We only need the salt, not the secret key. Convert to bytes to calculate #our bogus hmac salt = bso.int_to_bytes(server_response['salt']) # Hmac is calculated by the client and sent to the server. K = sha256(bso.int_to_bytes(0)).digest() bogus_hmac = bso.bytes_to_hex( hmac(K, salt, lambda val: sha256(val).digest(), 64, 32)) print( requests.post('http://127.0.0.1:5000/', data={ 'HMAC': bogus_hmac }).text)
def main(): message = b'A test message' message_int = int(bso.bytes_to_hex(message), 16) ciphertexts = [] public_keys = [] #Encrypt the same message 3 times with 3 different public keys. Keep track # of the ciphertext and public key. It is not necessary to use 3, just need to # use the value of e in rsa. while len(ciphertexts) < 3: server = rsa.RSAServer(e=3) client = rsa.RSAClient() e, n = server.send_public_key() client.recv_public_key(e, n) ciphertext = client.encrypt(message_int) ciphertexts.append(ciphertext) public_keys.append(n) #Now decrypt without using the secret key discovered_message_int = rsa_attacks.hastad_attack(3, ciphertexts, public_keys) discovered_message = bso.hex_to_bytes(hex(discovered_message_int)[2:]) assert discovered_message == message
def bad_verify_message(self, message, signature): """Verifies a signature by decrypting and checking the signature (in hex) starts with '0001ff' and contains the correct ans1 for sha16 and hash of the message Agrs: message (bytes): message which has been signed signature (int): supposed signratur for the message Returns: bool: True if the signature passes the verification raises: Exception('Signiture is invalid'): if the signature does not pass validation """ message_hash = sha256(message).hexdigest() signature = rsa.RSAClient.encrypt(self, signature) signature = bso.bytes_to_hex(signature.to_bytes(128, 'big')) invalid_signature = Exception('Signiture is invalid') if signature[:6] != '0001ff': raise invalid_signature if not signature.find('ff00' + message_hash): raise invalid_signature return True
def verify_hmac(self, recv_hmac, filename='Challenge38_hash_storage.txt'): """ Simulates final SRP verification but instead of doing the verification, stores recv_hmac and necessary values for cracking. Args: recv_hmac (bytes): hmac computed bytes he client Returns: string, int: 'OK', 200 """ #Create a dict with all of the data for storage data = {} data['HMAC'] = bso.bytes_to_hex(recv_hmac) data['base'] = self.base data['u'] = self.u data['client_public_key'] = self.client_public_key data['salt'] = self.salt data['secret_key'] = self.secret_key with open(filename, 'w') as file: json.dump(data, file) return 'OK', 200
def calculate_hmac(self): """Calculates the hmac and returns it. If the password is correct, it it should match the hmac calculated byt the server. returns: string: hmac encoded as a hex string depending on password, salt and server and client keys """ return bso.bytes_to_hex(SRPClient.calculate_hmac(self))
def main(): """ Input and outputs in hex as given by the challenge""" hex_in_1 = '1c0111001f010100061a024b53535009181c' hex_in_2 = '686974207468652062756c6c277320657965' hex_out = '746865206b696420646f6e277420706c6179' """Convert hex to bytes for XOR""" bytes_in_1 = bso.hex_to_bytes(hex_in_1) bytes_in_2 = bso.hex_to_bytes(hex_in_2) XOR = bso.FixedXOR(bytes_in_1, bytes_in_2) """Don't miss out on the 90's rap reference""" print(XOR) """Check results""" assert bso.bytes_to_hex(XOR) == hex_out
def main(): alice = rsa.RSAServer() bob = rsa.RSAClient() e, n = alice.send_public_key() bob.recv_public_key(e, n) bob_msg = secrets.randbelow(2**1024) ciphertext = bob.encrypt(bob_msg) assert alice.decrypt(ciphertext) == bob_msg plaintext = b'A random message' plaintext_int = int(bso.bytes_to_hex(plaintext), 16) decrypted_message = alice.decrypt(bob.encrypt(plaintext_int)) decrypted_message = hex(decrypted_message) decrypted_message = bso.hex_to_bytes(decrypted_message[2:]) assert decrypted_message == plaintext
def main(): oracle = RSAOracle() client = rsa.RSAClient() client.recv_public_key(*oracle.send_public_key()) message = b'A secret message' #Client encrypts the message message_int = int(bso.bytes_to_hex(message), 16) ciphertext = client.encrypt(message_int) #Client sends ciphertext which gets decrypted assert message == bso.hex_to_bytes(hex(oracle.decrypt(ciphertext))[2:]) #Attacker intercepts the ciphertext and tries to get the plaintext from #the oracle. This fails because the oracle only decrypts each plaintext once try: successfully_decrypted = message == bso.hex_to_bytes( hex(oracle.decrypt(ciphertext))[2:]) except: successfully_decrypted = False assert successfully_decrypted == False #instead the attacker can get the decryption of an alternate ciphertext and # convert it to the original message. This attack uses the fat that exponentiation # is a homomorphism e, n = oracle.send_public_key() #S can be any value S = 2 altered_ciphertext = nt.modexp(S, e, n) * ciphertext % n altered_message = oracle.decrypt(altered_ciphertext) #altered message = S * message new_message = altered_message * nt.invmod(S, n) % n assert message == bso.hex_to_bytes(hex(new_message)[2:])
def main(): server = RSAParityOracle() client = rsa.RSAClient() e, mod = server.send_public_key() client.recv_public_key(e, mod) plaintext = 'VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ==' plaintext = base64.b64decode(plaintext) integer_plaintext = int(bso.bytes_to_hex(plaintext), 16) ciphertext = client.encrypt(integer_plaintext) cracked_plaintext = rsa_attacks.parity_oracle_attack( ciphertext, e, mod, lambda val: server.is_even(val)) assert bso.hex_to_bytes( hex(cracked_plaintext)[2:] ) == b"That's why I found you don't play around with the Funky Cold Medind"
def pad_and_encrypt(self, plaintext): plaintext = self.pad(plaintext) plaintext = int(bso.bytes_to_hex(plaintext), 16) return self.encrypt(plaintext)