VAITP Dataset

← Back to the dataset

CVE-2025-46833

Weak RSA encryption in P73_SimplePythonEncryption.py allows brute-force decryption.

  • CVSS 4.6
  • CWE-326
  • Cryptographic
  • Remote

Programs/P73_SimplePythonEncryption.py illustrates a simple Python encryption example using the RSA Algorithm. In versions prior to commit 6ce60b1, an attacker may be able to decrypt the data using brute force attacks and because of this the whole application can be impacted. This issue has been patched in commit 6ce60b1. A workaround involves increasing the key size, for RSA or DSA this is at least 2048 bits, for ECC this is at least 256 bits.

CVSS base score
4.6
Published
2025-05-08
OWASP
A03:2021 Cryptographic Failures
Orthogonal defect classification
Algorithm
Code defect classification
Incorrect Algorithm
Category
Cryptographic
Subcategory
Weak encryption algorithm
Accessibility scope
Remote
Impact
Data Theft
Affected component
Python
Fixed by upgrading
Yes

Solution

Upgrade to version after commit 6ce60b1 or increase key size (RSA/DSA >= 2048 bits, ECC >= 256 bits).

Vulnerable code sample

import rsa

# Generate keys (insecurely small key size)
(pubkey, privkey) = rsa.newkeys(512) # Vulnerable key size

message = 'This is a secret message!'

# Encryption
encrypted_message = rsa.encrypt(message.encode('utf-8'), pubkey)

print(f"Encrypted message: {encrypted_message}")

# Simulate decryption (vulnerable to brute-force)
# In a real attack, a malicious actor would attempt to brute-force
# the private key due to the small key size.  This simulation
# simply demonstrates the successful decryption *if* the attacker
# manages to crack the key.  Actual brute-forcing code is not provided
# as it would be irresponsible and unethical.

decrypted_message = rsa.decrypt(encrypted_message, privkey).decode('utf-8')

print(f"Decrypted message: {decrypted_message}")

Patched code sample

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii

def generate_key_pair(key_size=2048):
    """
    Generates an RSA key pair.  The key size is now a parameter 
    and defaults to 2048 bits, a recommended minimum.
    """
    key = RSA.generate(key_size)  # Increased key size
    public_key = key.publickey().export_key()
    private_key = key.export_key()
    return public_key, private_key


def encrypt_message(public_key, message):
    """Encrypts a message using the provided public key."""
    key = RSA.import_key(public_key)
    cipher = PKCS1_OAEP.new(key)
    ciphertext = cipher.encrypt(message.encode('utf-8'))
    return binascii.hexlify(ciphertext).decode('utf-8')


def decrypt_message(private_key, ciphertext):
    """Decrypts a ciphertext using the provided private key."""
    key = RSA.import_key(private_key)
    cipher = PKCS1_OAEP.new(key)
    ciphertext = binascii.unhexlify(ciphertext)
    try:
        plaintext = cipher.decrypt(ciphertext)
        return plaintext.decode('utf-8')
    except ValueError:
        return "Decryption failed: Incorrect key or tampered ciphertext"


if __name__ == '__main__':
    # Example Usage
    public_key, private_key = generate_key_pair()

    message = "This is a secret message."
    encrypted_message = encrypt_message(public_key, message)
    decrypted_message = decrypt_message(private_key, encrypted_message)

    print("Original message:", message)
    print("Encrypted message:", encrypted_message)
    print("Decrypted message:", decrypted_message)

Payload

# This is a placeholder and NOT an actual exploit.
# Brute-forcing RSA keys is computationally infeasible with sufficiently large keys.
# This example assumes an extremely weak, short key length used by the vulnerable application.
# DO NOT USE THIS IN A REAL-WORLD SCENARIO. IT IS PURELY ILLUSTRATIVE.

# This would require access to the ciphertext and knowledge of the weak key generation.
# In reality, you'd likely need to analyze the P73_SimplePythonEncryption.py code
# to understand how keys are generated and used.

# Assuming a very short key length (e.g., 8 bits), the following demonstrates a *conceptual* approach.
# The actual code would be much more complex and would likely involve a precomputed rainbow table
# or other optimization techniques to make brute-forcing feasible, even for a short key.

# This example is only to show how to attempt a RSA decryption with a given key.

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii

def try_key(private_key_pem, ciphertext):
    try:
        key = RSA.import_key(private_key_pem)
        cipher = PKCS1_OAEP.new(key)
        plaintext = cipher.decrypt(binascii.unhexlify(ciphertext))
        return plaintext.decode('utf-8')  # Assuming UTF-8 encoding
    except Exception as e:
        # Key doesn't work
        return None

# Example ciphertext (assuming it's hex-encoded) - REPLACE with actual ciphertext
ciphertext = "1a2b3c4d5e6f7081"

# Example private key PEM string (replace with actual key or brute-force possibilities)
# Note: Real RSA keys are much longer and more complex. This is a tiny example.
private_key_pem = """-----BEGIN RSA PRIVATE KEY-----
MEgCQQDL9qR49y53J2uY4wIDAQABAkEAwJgR1y0hL1H5/LzV0QIE75j3u/j
y6i864wI7k0gCIQCPV6e04H4a7y/QJkHwIhAJNl86Y61M0J4gQ2rQICIQCD
x5tE37X+7t7/E/c10QIhAJ7p8L+U78s9o1hE4QIhAKF9p29S30K5/oW6vQ==
-----END RSA PRIVATE KEY-----"""

plaintext = try_key(private_key_pem, ciphertext)

if plaintext:
    print("Decrypted:", plaintext)
else:
    print("Decryption failed with this key.")

# In a real attack, you would loop through many possible keys to brute-force the decryption.

Cite this entry

@misc{vaitp:cve202546833,
  title        = {{Weak RSA encryption in P73_SimplePythonEncryption.py allows brute-force decryption.
}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2025},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2025-46833},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-46833/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::