A vulnerability in the Linux kernel, dubbed “Dirty Pipe”, allows unprivileged users to overwrite data in read-only files. This can allow users to gain access to root privileges on the vulnerable endpoints. This is possible because exploiting this vulnerability can allow unprivileged processes to inject code into root processes.
The vulnerability was discovered and explained by Max Kellerman. It affects Linux kernel versions 5.8 to 5.16. The fixed versions are 5.16.11, 5.15.25, and 5.10.102.
For this blog post, we used the following infrastructure:
- An installed Wazuh manager (4.3.6).
- An installed and enrolled Wazuh agent (4.3.6) on a vulnerable Ubuntu 20.04 endpoint. The kernel version is 5.13.0.
Scanning vulnerable Linux kernel versions
We create a Wazuh SCA (Security Configuration Assessment) policy to detect vulnerable Linux kernels. SCA policies are written in YAML format and are used to run checks for system hardening. They can also be used to detect vulnerable software on monitored endpoints. In order to create and apply the SCA policy, we take the following steps using the
On the Wazuh manager
1. Create a new policy file at
policy: id: "dirty_pipe_vulnerability_check" file: "dirty_pipe_check_vulnerability.yml" name: "Dirty Pipe vulnerability check" description: "This document provides prescriptive guidance for identifying Dirty Pipe vulnerability" references: - https://nvd.nist.gov/vuln/detail/CVE-2022-0847 requirements: title: "Check if kernel version can be extracted with uname command" description: "Requirements for running the SCA scan against Linux based endpoints." condition: all rules: - 'c:sh -c "uname -r" -> r:^\d.\d+' checks: - id: 10000 title: "Ensure Linux kernel version is below 5.8 or 5.16.11, 5.15.25, and 5.10.102." description: "The Linux kernel is vulnerable to Dirty Pipe (CVE-2022-0847) on versions 5.8 and above except 5.16.11, 5.15.25, and 5.10.102." remediation: "Update the Linux kernel to version 5.16.11, 5.15.25, and 5.10.102 or apply a patch." condition: any rules: - 'c:uname -r -> r:^1.|^2.|^3.|^4.|^5.0(.|-|$)|^5.1(.|-|$)|^5.2(.|-|$)|^5.3(.|-|$)|^5.4(.|-|$)|^5.5(.|-|$)|^5.6(.|-|$)|^5.7(.|-|$)|^5.10.102|^5.10.92|^5.15.25|^5.(([1-9][6-9])|([2-9][0-9])).(([1-9][1-9])|([2-9][0-9]))|^5.(([1-9][7-9])|([2-9][0-9]))'
This SCA policy will get shared with a group of agents, which are the ones that will run the checks. In our case, we are sharing the policy with the default group, hence the
default directory. A detailed description of how to create custom SCA policies can be found in our documentation.
2. Once the SCA policy file is created, the owner and group ownership are modified so that it can be used by Wazuh:
chown wazuh:wazuh /var/ossec/etc/shared/default/dirtypipe_check.yml
3. Next, we add the SCA block to the
/var/ossec/etc/shared/default/agent.conf file. This will enable the new policy on the Wazuh agents that belong to the
<agent_config os="linux"> <sca> <enabled>yes</enabled> <scan_on_start>yes</scan_on_start> <interval>24h</interval> <skip_nfs>yes</skip_nfs> <policies> <policy>/var/ossec/etc/shared/dirtypipe_check.yml</policy> </policies> </sca> </agent_config>
On the Linux/Unix endpoint
In order to enable the execution of commands in the SCA policies that are received from the Wazuh manager, we need to explicitly enable remote commands on the endpoints we want to scan. This is usually disabled by default for security reasons and this modification is not necessary when the SCA policies are local to the agent. To do this, we edit the configuration on the Wazuh agent
/var/ossec/etc/local_internal_options.conf file and include
"sca.remote_commands=1" by running the command below as
echo "sca.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
Restart the Wazuh agent to apply the changes:
systemctl restart wazuh-agent
After the agent is restarted and the SCA scan runs, we can see the SCA scan results for the vulnerable endpoint below:
Detecting exploitation attempts
In order to exploit the Dirty Pipe vulnerability, we use an exploit source code that can be downloaded from GitHub by running the following command:
git clone https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits.git
The code exploits the Dirty Pipe vulnerability to execute a payload that spawns a root shell. Firstly, we compile the source code using the instructions below:
- In order to compile the exploit successfully, GCC needs to be installed:
apt-get install gcc
After installing GCC, run the
compile.sh script as follows:
chmod +x compile.sh ./compile.sh
To test the exploit, we create an account
unpriv on the vulnerable Ubuntu 22.04 endpoint. When we run
groups unpriv on the terminal we get the output:
unpriv : unpriv
The output shows that the account is a member of its own group. To confirm that the account has no root privileges, we switch to the
unpriv account and run the command below:
sudo apt-get update
unpriv is not in the sudoers file. This incident will be reported.
The output confirms that the account is a regular user account and has no superuser privileges. We proceed to move the directory with the compiled exploits to a directory that the
unpriv account can access. In this case, we used the
After switching back to the
unpriv account, we run the following command from the directory containing the compiled exploit code:
We get a shell with the output below if the code runs successfully:
Backing up /etc/passwd to /tmp/passwd.bak ... Setting root password to "piped"... Password: Restoring /etc/passwd from /tmp/passwd.bak... Done! Popping shell... (run commands now) whoami root
When we run
whoami in the shell we get
root as the response proving we have root access to the machine.
Dirty Pipe Exploit behavior
In order to write detection rules, we need to understand what the exploit does. The exploit:
- Creates a pipe for unidirectional inter-process communication.
- Fills the pipe with arbitrary data.
- Drains the pipe to free all buffer instances.
- Splices data from the target file(
/etc/passwdin our case) into the pipe.
- Writes data into the pipe. In our case, a new password for the
- Opens a new root shell using the changed password.
- Restores the original password file.
In essence, an unprivileged attacker can use this exploit to gain root privileges and clear his tracks at the same time. This is because if the
/etc/passwd file is examined, it would appear unchanged. However, Auditd can be used to detect these changes.
The Linux audit framework provides an auditing system that reliably collects information about any event on a system. It can help you track actions performed on a system. Using Auditd, we can monitor the splice system calls made by the Dirty Pipe exploit and write rules to detect them. The steps to implement these rules are given below, and are performed using the
root account on the monitored endpoint:
- Install Auditd on the endpoint.
apt install auditd
- Create Auditd rules to monitor the splice functions used by the exploit. To do this, run the commands below as root to add the rules to the
echo "-a always,exit -F arch=b64 -S splice -F a0=0x3 -F a2=0x5 -F a3=0x0 -F key=dirtypipe" >> /etc/audit/rules.d/audit.rules echo "-a always,exit -F arch=b64 -S splice -F a0=0x6 -F a2=0x8 -F a3=0x0 -F key=dirtypipe" >> /etc/audit/rules.d/audit.rules echo "-a always,exit -F arch=b64 -S splice -F a0=0x7 -F a2=0x9 -F a3=0x0 -F key=dirtypipe" >> /etc/audit/rules.d/audit.rules
- Create Auditd rules to monitor write activities performed on the
/etc/passwdfile. To do this, run the command below to add the rule to the
echo "-w /etc/passwd -p w -k audit-wazuh-w" >> /etc/audit/rules.d/audit.rules
-k flag helps us take advantage of in-built Wazuh rules for Auditd.
- Reload the Auditd ruleset to apply the changes:
auditctl -R /etc/audit/rules.d/audit.rules auditctl -l
- Ensure the following block is added to the agent
<localfile> <log_format>audit</log_format> <location>/var/log/audit/audit.log</location> </localfile>
- Restart the Wazuh agent to apply the changes:
systemctl restart wazuh-agent
Now that we have the Auditd rules, we create the following rule on the Wazuh manager to alert us whenever the exploit signature is detected on the monitored endpoint. The rule is added to the
/var/ossec/etc/rules/local_rules.xml file on the Wazuh manager:
<group name="dirtypipe-auditd,"> <rule id="700100" level="12"> <if_sid>80700</if_sid> <field name="audit.key">dirtypipe</field> <description>Dirty Pipe exploit activity detected (CVE-2022-0847)</description> </rule> </group>
Restart the Wazuh manager to apply the changes:
systemctl restart wazuh-manager
When the exploit is run again, we see the following events on the Wazuh dashboard:
5501detects when the root shell is opened. Note that we did not have to create this rule because it is an in-built Wazuh rule.
700100is the rule we created to monitor the system calls made by the exploit.
80781detects when the exploit changes the
/etc/passwdfile. This is an in-built Wazuh rule for Auditd events that detects write access to specified files. In this case, the rule is triggered when the exploit accesses the
Wazuh is a SIEM/XDR solution that can be used to detect advanced attacks. In this blog post, we have shown how to use the SCA module of Wazuh to detect Dirty Pipe vulnerability. We have also shown how to use Wazuh to detect Dirty Pipe exploit attempts.