Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
#!/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]))
Пример #4
0
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])
Пример #5
0
#!/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(
Пример #6
0
#!/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]))
Пример #7
0
    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)