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 root
account:
On the Wazuh manager
1. Create a new policy file at /var/ossec/etc/shared/default/dirtypipe_check.yml
:
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 default
group:
<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 root
:
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 /home/unpriv/Downloads/
directory.
After switching back to the unpriv
account, we run the following command from the directory containing the compiled exploit code:
./exploit-1
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/passwd
in our case) into the pipe. - Writes data into the pipe. In our case, a new password for the
root
account. - 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.
Auditd rules
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
/etc/audit/rules.d/audit.rules
file:
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/passwd
file. To do this, run the command below to add the rule to the/etc/audit/rules.d/audit.rules
file:
echo "-w /etc/passwd -p w -k audit-wazuh-w" >> /etc/audit/rules.d/audit.rules
The -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
/var/ossec/etc/ossec.conf
file:
<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
Wazuh detection
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
Detection results
When the exploit is run again, we see the following events on the Wazuh dashboard:
- Rule
5501
detects when the root shell is opened. Note that we did not have to create this rule because it is an in-built Wazuh rule. - Rule
700100
is the rule we created to monitor the system calls made by the exploit. - Rule
80781
detects when the exploit changes the/etc/passwd
file. 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/etc/passwd
file.
Conclusion
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.