Detecting Dirty Pipe vulnerability with Wazuh (CVE-2022-0847)

| by | Wazuh 4.3
Post icon

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:

  1. Creates a pipe for unidirectional inter-process communication.
  2. Fills the pipe with arbitrary data.
  3. Drains the pipe to free all buffer instances.
  4. Splices data from the target file(/etc/passwd in our case) into the pipe.
  5. Writes data into the pipe. In our case, a new password for the root account.
  6. Opens a new root shell using the changed password.
  7. 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:

  1. Install Auditd on the endpoint.
apt install auditd
  1. 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
  1. 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.

  1. Reload the Auditd ruleset to apply the changes:
auditctl -R /etc/audit/rules.d/audit.rules
auditctl -l
  1. 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>
  1. 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.

References

The Dirty Pipe Vulnerability