Created
July 16, 2025 18:27
-
-
Save Reelix/d47762822b65f5a4518dcd1fd0c80aef to your computer and use it in GitHub Desktop.
RoundCube Session Password Decryptor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Thanks Gemini! | |
import re | |
import base64 | |
# The 'cryptography' library is required to run this code. | |
# You can install it in your local Python environment with: | |
# pip install cryptography | |
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes | |
from cryptography.hazmat.backends import default_backend | |
def unpad_pkcs7(data): | |
"""Removes PKCS#7 padding from a byte string.""" | |
if not data: | |
return data | |
padding_len = data[-1] | |
if padding_len > len(data): | |
return data | |
return data[:-padding_len] | |
def decrypt_roundcube_session_password(session_data, des_key): | |
""" | |
Decrypts the user password stored in a RoundCube session using 3DES. | |
Args: | |
session_data: The serialized PHP session string. | |
des_key: The value of $config['des_key'] from RoundCube's config. | |
Returns: | |
The decrypted plaintext password, or an error message. | |
""" | |
# 1. Extract the encrypted password from the session string | |
match = re.search(r'password\|s:32:"([^"]+)"', session_data) | |
if not match: | |
return "Error: Encrypted password not found in session data." | |
encrypted_password_b64 = match.group(1) | |
try: | |
# 2. Base64 decode the data | |
encrypted_data = base64.b64decode(encrypted_password_b64) | |
# 3. The first 8 bytes are the IV, the rest is the ciphertext, as per RoundCube's method | |
iv = encrypted_data[:8] | |
ciphertext = encrypted_data[8:] | |
# 4. Set up the 3DES CBC cipher. The key must be 24 bytes. | |
cipher = Cipher( | |
algorithms.TripleDES(des_key.encode('utf-8')), | |
mode=modes.CBC(iv), | |
backend=default_backend() | |
) | |
decryptor = cipher.decryptor() | |
# 5. Decrypt and remove PKCS#7 padding | |
decrypted_padded = decryptor.update(ciphertext) + decryptor.finalize() | |
plaintext = unpad_pkcs7(decrypted_padded) | |
return plaintext.decode('utf-8') | |
except ImportError: | |
return "Error: The 'cryptography' library is not installed. Please run 'pip install cryptography'." | |
except Exception as e: | |
return f"An error occurred during decryption: {e}" | |
def main(): | |
""" | |
Main function to run the decryption process. | |
""" | |
# session_data_string: The serialized PHP session string. (From sessions in Database) | |
session_data_string = r'language|s:5:"en_US";imap_namespace|a:4:{s:8:....."maxuid";i:3;}}list_mod_seq|s:2:"10";' | |
# des_key: The value of $config['des_key'] from RoundCube's config. | |
des_key = 'rcconfig-Pass123' | |
username_match = re.search(r'username\|s:\d+:"([^"]+)"', session_data_string) | |
username = username_match.group(1) if username_match else "Unknown" | |
decrypted_password = decrypt_roundcube_session_password(session_data_string, des_key) | |
print("--- RoundCube Session Password Decryptor ---") | |
print(f"Username: {username}") | |
print(f"Decrypted Password: {decrypted_password}") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment