def encrypt(plain_text: bytes, key: bytes, skip_first_round: bool = False) -> bytes: # Check key parameter length key_length = len(key) if (key_length != KEY_LENGTH): log.warning( "Key does not have the correct length: {} != {}".format( KEY_LENGTH, key_length)) exit() else: log.success("Key have the correct length: {} == {}".format( KEY_LENGTH, key_length)) # Check plain text parameter length plain_length = len(plain_text) if (plain_length % CHUNK_LENGTH != 0): log.warning( "Text to encrypt does not have the correct length: {} % {} != 0" .format(plain_length, CHUNK_LENGTH)) exit() else: log.success( "Text to encrypt has the correct length: {} % {} == 0".format( plain_length, CHUNK_LENGTH)) log.info("Text to encrypt is: {}".format( Converter.bytes_to_hex(plain_text))) # Get keys used for encryption keys = BC4Worker._generate_keys(key, plain_length // CHUNK_LENGTH, skip_first_round) # Split text in chunks and encrypt encrypted_text: bytes = bytes() for i in range(0, plain_length, CHUNK_LENGTH): # Get parts that will be XORed plain_part = plain_text[i:i + CHUNK_LENGTH] key_part = keys[i:i + CHUNK_LENGTH] # Encrypt with XOR ciphertext_part = Converter.bytes_to_int( plain_part) ^ Converter.bytes_to_int(key_part) encrypted_text += Converter.int_to_bytes(ciphertext_part) # Log if VERBOSE: log.info("The #{} encryption is {} (meaning {} ^ {})".format( i // CHUNK_LENGTH, Converter.int_to_hex(ciphertext_part), Converter.bytes_to_hex(plain_part), Converter.bytes_to_hex(key_part))) # Log if VERBOSE: log.info("Ciphertext is: {}".format( Converter.bytes_to_hex(encrypted_text))) # Encode encrypted text and return return encrypted_text
def _generate_keys(key: bytes, number_of_generated_keys: int, skip_first_round: bool = False) -> bytes: # Split the key into two ints, left and right left = Converter.bytes_to_int(key[:(KEY_LENGTH // 2)]) right = Converter.bytes_to_int(key[(KEY_LENGTH // 2):]) # Log if VERBOSE: log.info( "Keys will be generated for key {}, with left {} and right {}". format(Converter.bytes_to_hex(key), Converter.bytes_to_hex(key[:(KEY_LENGTH // 2)]), Converter.bytes_to_hex(key[(KEY_LENGTH // 2):]))) # Generate keys keys = bytes() for i in range(0, number_of_generated_keys): # Generate next right and left parts if (not (skip_first_round and i == 0)): left = (5 * left + 11) % MODULO right = (7 * right + 19) % MODULO # XOR parts new_key_part = Converter.int_to_bytes(left ^ right) keys += new_key_part # Log if VERBOSE: log.info( "Sub-key generated in the #{} iteration is {} (meaning {} ^ {})" .format(i, Converter.bytes_to_hex(new_key_part), Converter.int_to_hex(left), Converter.int_to_hex(right))) # Log if VERBOSE: log.info("Keys generated is: {}".format( Converter.bytes_to_hex(keys))) # Return return keys
#!/usr/bin/env python3 # Import libraries from gmpy2 import mpz, invert, powmod, to_binary from pwn import log # Import handcrafted modules from utl_converters import Converter # Define used constants, where P and Q are obtained with factordb.com N = mpz( 70736025239265239976315088690174594021646654881626421461009089480870633400973 ) E = mpz(3) C = mpz( 28822365203577929536184039125870638440692316100772583657817939349051546473185 ) P = mpz(238324208831434331628131715304428889871) Q = mpz(296805874594538235115008173244022912163) # Decrypt ciphertext phi = mpz((P - 1) * (Q - 1)) d = invert(E, phi) m = powmod(C, d, N) # Print decrypted message log.success("The decrypted message is: {}".format( Converter.bytes_to_string(to_binary(m))[::-1]))
from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from pwn import log # Import handcrafted modules from utl_converters import Converter # Define used constants PATH_TO_IMAGES = "Additional Files/amc/" USED_MODES = [(AES.MODE_ECB, "ecb"), (AES.MODE_CBC, "cbc")] BMP_EXTENSION = ".bmp" # Get a random key and IV iv = get_random_bytes(16) key = get_random_bytes(16) log.info("IV is: {}".format(Converter.bytes_to_hex(iv))) log.info("Key is: {}".format(Converter.bytes_to_hex(key))) # Read file to encrypt file = open(PATH_TO_IMAGES + "original.bmp", "rb") content = file.read() file.close() # Get headers (14 bytes for BMP and 40 bytes for DIB) and remove them from content headers = content[0:54] content = content[54:] # Add PKCS#5 padding padding_length = AES.block_size - len(content) % AES.block_size content += padding_length * bytes([padding_length])
#!/usr/bin/env python3 # Import libraries from Crypto.Cipher import AES from Crypto.PublicKey import RSA from Crypto.Hash import SHA256 from gmpy2 import mpz, iroot, to_binary, bit_length from base64 import b64decode from pwn import log # Include handcrafted modules from utl_converters import Converter # Define constants BLOB = Converter.hex_to_bytes( "001893834df42280c7a3d695ed87d986a2dd87e5bf43c4b5dea50018172fff3690221206be2780bd99dc5a3c3a632d637595721d8e468c11326435bda16cd0e7fde4cc23" ) ALICE_PUBLIC_KEY = "MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAzjQuC7VtSzbFjU4FbEYxMTWBQJTFh8zkXdiYhdDv/iH2k5XeZtm+6Zozz4MOrNRlyhcuqBjHyGmLp/DXz6VNbHXQOSSFpnPXOM+W96xGFp/EJ4qhxLagcY7uFMfXS/tHIfKq1yxBPnmHnrDNGve2taGhQaAyeXKkIn2X665aZgwzgVDiVjviBQFPqVT6U5HROOf6YzLhhPtCYaoiYLs/gCLhJJfGu9POJuRVVPElEA0eQW7bxmXPSXQRRFbq4NIoFoYOV6YS+qzv1sbTn2ZhI+pvT2HpdEvwx2S9L/j0PLdhCBQ7xUPX2Bg//d87JDYT1hOJImptwSVo0ZDaafvZ7QIBAw==" BOB_PUBLIC_KEY = "MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAxXpbMNT1pMZaV/VwIDaOsWW7XKY7bksSPpJ0NpleJl9wBmXEVh1HnWYFd9fdBtlsQXsVxqxUNBYS6FdsHzgpG7Y0N7UZ4ISf3FKp12HmKxakfNM6Bj2rIYRPyFlCMZAvgmmKLNKgu8cm8cgKbSMemsgdOoO46Ft11Ywa801sVCCEpXJFT7PVNepTYMhQ+vU8Mr8r/YPxwrKLxdoXh8XJtj7FrmylHCWYvA91QIQpe4h4i1XdlBcDg01rnNplJVJoDOI7agXCT9XsA8zNGJ++iwoMT7Q+9xLOYVWw/rPjSBacpqH75DATpz7tMWw1bxPnXT1ShLTNnk41uB2qMZFfZQIBAw==" # Get known algorithm parameters from blob c1_length = Converter.bytes_to_int(BLOB[0:2]) c1 = BLOB[2:c1_length + 2] c2_length = Converter.bytes_to_int(BLOB[c1_length + 2:c1_length + 4]) c2 = BLOB[c1_length + 4:-16] encrypted_code = BLOB[-16:] # Log algorithm parameters log.info("C1, with length of {} bytes, is: {}".format( c1_length, Converter.bytes_to_hex(c1))) log.info("C2, with length of {} bytes, is: {}".format(
#!/usr/bin/env python3 # Import handcrafter modules from bc4_worker import BC4Worker from utl_converters import Converter from pwn import log # Defines constants used CIPHERTEXT = "eda1e0bce19bde665dd62d3c9a1c3001dc523a07fab5c8c15ff2c0eab482e3a37d6389dfa0b458cae535b841f24d8a2ae7361b1d16abd2031367c3bdfa7be21250361cc5d23c3803ee95b4342794fb749645e2" KNOWN_PLAINTEXT = "this will be" KNOWN_L = 0x8b76a64d SKIP_FIRST_ROUND = True # Bruteforce to get key ciphertext = Converter.hex_to_bytes(CIPHERTEXT) known_plaintext = Converter.string_to_bytes(KNOWN_PLAINTEXT) key = BC4Worker.brutefoce(ciphertext, known_plaintext, KNOWN_L) # Add one byte to ciphertext to respect the length constrains ciphertext += b'0' # Decrypt with the help of encrypt algorithm plaintext = BC4Worker.encrypt(ciphertext, key, SKIP_FIRST_ROUND) # Print log.success("Decrypted text is: {}".format(plaintext[:-1]))
def brutefoce(ciphertext: bytes, known_plaintext: bytes, start_with: int = 0): # get parts for bruteforce known_plaintext_length = len(known_plaintext) ciphertext_part = ciphertext[0:known_plaintext_length] # log parts if VERBOSE: log.info("Ciphertext used in bruteforce is: {}".format( Converter.bytes_to_hex(ciphertext_part))) log.info("Plaintext used in bruteforce is: {}".format( Converter.bytes_to_hex(known_plaintext))) # get the known XOR between R and L known_key_part = bytes() for i in range(0, known_plaintext_length, CHUNK_LENGTH): # Get parts that will be XORed ciphertext_subpart = ciphertext_part[i:i + CHUNK_LENGTH] known_plaintext_part = known_plaintext[i:i + CHUNK_LENGTH] # XOR new_key_part = Converter.int_to_bytes( Converter.bytes_to_int(ciphertext_subpart) ^ Converter.bytes_to_int(known_plaintext_part)) known_key_part += new_key_part # Log if VERBOSE: log.info( "New known part of key is: {} (meaning {} ^ {})".format( Converter.bytes_to_hex(new_key_part), Converter.bytes_to_hex(ciphertext_subpart), Converter.bytes_to_hex(known_plaintext_part))) # create progress bar progress_bar = tqdm(total=MODULO - start_with, ascii=True, position=0, leave=True) # bruteforce left part chunk_to_be_compared_with = known_key_part[CHUNK_LENGTH:] for left in range(start_with, MAX_NUMBER_TO_REACH): # get L right = Converter.bytes_to_int( known_key_part[0:CHUNK_LENGTH]) ^ left # compute new keys and compare to the known ones keys = BC4Worker._generate_keys( b"".join([ Converter.int_to_bytes(left), Converter.int_to_bytes(right) ]), known_plaintext_length // CHUNK_LENGTH - 1) if (keys == chunk_to_be_compared_with): log.success("Finded L and R are: ({}, {})".format(left, right)) return Converter.int_to_bytes(left) + Converter.int_to_bytes( right) # update progress bar progress_bar.update(n=1)