Example #1
0
def forge_via_length_extension(attacker_id: str, victim_id: str) -> bytes:
    victim = ClientV2(victim_id)
    server = ServerV2()

    # Intercept transaction from victim to some recipient "8".
    payload = victim.send({"8": 100})
    assert server.validate(payload)

    message, t = parse_payload_v2(payload)
    message = pkcs7(message)  # It's important to keep track of the padding.

    # CBC-MAC extension works because for some t = mac(m_1),
    # mac(m1 || m_2) = mac(t xor m_2).

    # We want to concatonate the original message with our own extension,
    # which will be a transaction to our ID for 1,000,000 spacebucks.
    # Conveniently that's the largest order of magnitude amount that we
    # can squeeze into the extension.

    # We need to keep the "from=..." field intact. It's 6 bytes long. The
    # below xor ensures that in the extension attack, the resulting message
    # will retain the original 6 bytes.
    mandatory_xor = fixed_xor(message[:6], t[:6])
    extension = mandatory_xor + b";" + attacker_id.encode() + b":1000000"

    # Extend and generate a new CBC-MAC.
    # Yeah, we call victim.cbc_mac here.
    m_prime = message + extension
    mac_prime = victim.cbc_mac(fixed_xor(t, extension))
    payload = m_prime + mac_prime

    assert server.validate(payload)
    return payload
Example #2
0
def oracle(userdata: bytes) -> bytes:
    key = RANDOM_KEY
    prefix = b"comment1=cooking%20MCs;userdata="
    postfix = b";comment2=%20like%20a%20pound%20of%20bacon"
    userdata = userdata.replace(b";", b"").replace(b"=", b"")
    plaintext = pkcs7(prefix + userdata + postfix)
    return encrypt_aes_cbc(key, iv=bytes(16), plaintext=plaintext)
Example #3
0
def oracle(plaintext: bytes) -> bytes:
    prefix = RANDOM_PREFIX
    with open("data/12.txt") as data_fd:
        unknown_string = b64decode(data_fd.read())
    plaintext = pkcs7(prefix + plaintext + unknown_string, 16)
    cypher = AES.new(RANDOM_KEY, AES.MODE_ECB)
    return cypher.encrypt(plaintext)
Example #4
0
def rewrite_cookie(email = "*****@*****.**"):
    bs = 16
    assert len(email) % bs == 13, "email must be 13 (mod 16) characters"
    admin_block = pkcs7(b'admin', bs).decode()
    d = int(len(email) / bs) * bs
    email = email[:-3] + admin_block + email[-3:]
    c = oracle(email)
    return c[:bs+d] + c[2*bs+d:3*bs+d] + c[bs+d:2*bs+d]
Example #5
0
def rewrite_cookie(email: str) -> bytes:
    bs = 16
    if len(email) % bs != 13:
        raise ValueError(f"email must be 13 (mod {bs}) characters")
    admin_block = pkcs7(b"admin", bs).decode()
    d = int(len(email) / bs) * bs
    email = email[:-3] + admin_block + email[-3:]
    c = oracle(email)
    return c[:bs + d] + c[2 * bs + d:3 * bs + d] + c[bs + d:2 * bs + d]
Example #6
0
def forge_hash(m: bytes, m_prime: bytes, key: bytes, iv: bytes) -> bytes:
    t = cbc_mac(key, iv, pkcs7(m))
    t_prime = cbc_mac(key, iv, m_prime)

    # We need to find m'' such that E_k(m'' xor t') = t
    # by solving D_k(t) xor t' = m''.

    m_prime_suffix = decrypt_aes_cbc(key, t_prime, t)
    return m_prime + m_prime_suffix
Example #7
0
def main() -> None:
    m = b"alert('MZA who was that?');\n"
    key = b"YELLOW SUBMARINE"
    iv = bytes(16)

    # No padding because it aligns with the blocksize.
    m_prime = b"alert('Ayo, the Wu is back!');//"
    forgery = forge_hash(m, m_prime, key, iv)

    assert cbc_mac(key, iv, pkcs7(m)) == cbc_mac(key, iv, forgery)
    print(forgery)
Example #8
0
def encryption_oracle(plaintext: bytes) -> bytes:
    plaintext = bytes(randrange(5, 11)) + plaintext + bytes(randrange(5, 11))
    plaintext = pkcs7(plaintext)

    key = get_random_bytes(16)

    if randrange(2) == 0:
        iv = get_random_bytes(16)
        return encrypt_aes_cbc(key, iv, plaintext)

    cypher = AES.new(key, AES.MODE_ECB)
    return cypher.encrypt(plaintext)
Example #9
0
def encryption_oracle(plaintext):
    plaintext = bytes(randrange(5, 11)) + plaintext + bytes(randrange(5, 11))
    plaintext = pkcs7(plaintext, 16)

    key = bytes(getrandbits(8) for i in range(16))

    if randrange(0,2) == 0:
        iv = bytes(getrandbits(8) for i in range(16))
        cyphertext = encrypt_aes_cbc(plaintext, key, iv)
        #print("CBC")
    else:
        cypher = AES.new(key, AES.MODE_ECB)
        cyphertext = cypher.encrypt(plaintext)
        #print("ECB")

    return cyphertext
Example #10
0
def oracle(plaintext: bytes) -> bytes:
    with open("data/12.txt", "r") as data_handle:
        unknown_string = b64decode(data_handle.read())
    plaintext = pkcs7(plaintext + unknown_string, 16)
    cypher = AES.new(RANDOM_KEY, AES.MODE_ECB)
    return cypher.encrypt(plaintext)
Example #11
0
 def send(self, to_id: str, amount: int) -> bytes:
     message = self.compose_message(self.id, to_id, amount)
     iv = get_random_bytes(BLOCKSIZE)
     return message + iv + cbc_mac(KEY, iv, pkcs7(message))
Example #12
0
 def send_message(self, message: bytes) -> None:
     iv = get_random_bytes(16)
     cyphertext = encrypt_aes_cbc(self._aes_key(), iv, pkcs7(message))
     self.peer.receive_message(cyphertext + iv)
Example #13
0
def oracle(userdata, k = RANDOM_KEY):
    prefix = b'comment1=cooking%20MCs;userdata='
    postfix = b';comment2=%20like%20a%20pound%20of%20bacon' 
    userdata = userdata.replace(";", "").replace("=", "")
    plaintext = pkcs7(prefix + bytes(userdata, "ascii") + postfix)
    return encrypt_aes_cbc(plaintext, k, iv = bytes(16))
Example #14
0
 def validate(payload: bytes) -> bool:
     message, iv, mac = parse_payload_v1(payload)
     return compare_digest(cbc_mac(KEY, iv, pkcs7(message)), mac)
Example #15
0
def oracle(userdata: bytes) -> bytes:
    prefix = b"comment1=cooking%20MCs;userdata="
    postfix = b";comment2=%20like%20a%20pound%20of%20bacon"
    userdata = userdata.replace(b";", b"").replace(b"=", b"")
    plaintext = pkcs7(prefix + userdata + postfix)
    return aes_ctr(plaintext, RANDOM_KEY)
Example #16
0
 def send(self, tx_list: dict[str, int]) -> bytes:
     """Return a payload for the server"""
     message = self._compose(tx_list)
     return message + self.cbc_mac(pkcs7(message))
Example #17
0
def oracle(email: str) -> bytes:
    profile = profile_for(email)
    cypher = AES.new(RANDOM_KEY, AES.MODE_ECB)
    return cypher.encrypt(pkcs7(bytes(profile, "ascii"), 16))
Example #18
0
def oracle(plaintext = b''):
    unknown_string = b64decode(open("data/12.txt", "r").read())
    plaintext = pkcs7(plaintext + unknown_string, 16)
    cypher = AES.new(RANDOM_KEY, AES.MODE_ECB)
    return cypher.encrypt(plaintext)
Example #19
0
def bad_cbc_encryption(plaintext: bytes) -> bytes:
    key = RANDOM_KEY
    return encrypt_aes_cbc(key, iv=key, plaintext=pkcs7(plaintext))
Example #20
0
def cbc_oracle(plaintext: bytes) -> int:
    """CBC-mode compression orcle"""
    key = get_random_bytes(BLOCKSIZE)
    iv = get_random_bytes(BLOCKSIZE)
    return len(
        encrypt_aes_cbc(key, iv, pkcs7(compress(format_request(plaintext)))))
Example #21
0
 def validate(payload: bytes) -> bool:
     """Unreasonably flexible payload validation"""
     message, mac = parse_payload_v2(payload)
     if len(message) % 16 != 0:
         message = pkcs7(message)
     return compare_digest(cbc_mac(KEY, bytes(16), message), mac)
Example #22
0
def oracle(email):
    profile = profile_for(email)
    cypher = AES.new(RANDOM_KEY, AES.MODE_ECB)
    return cypher.encrypt(pkcs7(bytes(profile, "ascii"), 16))
Example #23
0
def chose_plaintext():
    f = open("data/17.txt", "r").read().splitlines()
    return pkcs7(b64decode(f[randint(0, len(f) - 1)]))
Example #24
0
def pkcs7(plaintext: bytes, blocksize: int = 16) -> bytes:
    return m09.pkcs7(plaintext, blocksize)