NIMBUSPWN: What You Need to Know Now
By: Ofri Ouzan, Security Researcher, Rezilion
The Microsoft 365 Defender Research Team has discovered several vulnerabilities in the `networkd-dispatcher` that are identified as CVE-2022-29799 and CVE-2022-29800 and dubbed as Nimbuspwn.
The vulnerabilities were identified by listening to messages on the System Bus while performing code reviews and dynamic analysis on services that run as root.
Exploiting both Nimbuspwn vulnerabilities, can be chained to gain root privileges on Linux systems, allowing attackers to deploy payloads, like a root backdoor, and perform other malicious actions via arbitrary root code execution.
Is a path traversal vulnerability as a result of a missing check in the `networkd-dispatcher` component implementation. The Path Traversal attack aims to access files and directories that are stored outside the web root folder. By manipulating variables that reference files with “dot-dot-slash (../)” sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files and directories stored on file systems including application source code or configuration and critical system files.
By using the Path Traversal attack, the attacker can access the malicious directory he created.
Is a TOCTOU (Time of Check – Time of Use) race condition vulnerability, caused by validation checks that the `networkd-dispatcher` performs in order to validate which scripts in the checked directory have root permissions. If a large amount of scripts need to be validated, the checks take time and meanwhile, the attacker can replace the subdirectory and cause malicious scripts with the same name to be executed instead.
In order to understand the flow, you need to be familiar with these two concepts:
D-Bus (short for Desktop Bus) is an Inter Process Communication channel mechanism that allows processes on the same endpoint to communicate by transmitting messages and responding to them.
A dispatcher daemon for `systemd-networkd` connection status changes.
The daemon listens for signals from `systemd-networkd` over dbus, and handles the signals according to the changed state.
There are subdirectories that represent the states which are placed under SCRIPT_DIR (`/usr/lib/networkd-dispatcher` by default) and contain scripts that should be executed in order to change the network state.
These are the following states:
carrier.d, degraded.d, dormant.d, no-carrier.d, off.d, routable.d
In order to exploit the vulnerability, the attacker creates a malicious directory which links to /sbin directory. Why /sbin? because it has a big amount of executable files with root permissions.
Then, the attacker copies all the file names with root permissions from the /sbin directory and creates malicious files with the same names in the malicious directory.
Meanwhile, the `networkd-dispatcher` daemon listens for signals from systemd-networkd over dbus.
When an appropriate signal arrives, the `_receive_signal` signal handler performs some basic checks on the object type being sent and determines its new state, which can be either OperationalState or AdministrativeState.
Another signal object is a path to the network interface that its state will be changed, which later on will be manipulated by the attacker.
Next, the “handle_state” method is invoked, which in turn invokes the `_handle_one_state` method for each one of those two states. This method checks that they are not empty and that there was indeed a state change.
If that is the case, it will update the new state and invoke the `_run_hooks_for_state` method, which takes the directory from SCRIPT_DIR (usually `/usr/lib/networkd-dispatcher`) and runs the scripts from the relevant new state directory.
The “_run_hooks_for_state” is responsible for:
- Discovering the script list. It does so by invoking the `get_script_list` method which in turn calls `scripts_in_path` which is intended to return all the executable files under “/etc/networkd-dispatcher/<state>.d” that are owned by the root user and the root group.
- Sorting the script list.
- Running each script with subprocess.Popen while using custom environment variables.
The attacker sends a signal with a path traversal (instead of the network interface object path), for example:
The attacker creates a link from poc.d to the /sbin directory so that the `_run_hooks_for_state` will perform its checks there.
When the `_run_hooks_for_state`sorting the files and because there are so many files in /sbin it takes time, the attacker replaces the `poc.d` link from /sbin to its malicious directory that contains all the scripts with the duplicate file names and wins the TOCTOU race.
When the `_run_hooks_for_state` will try to execute the scripts that change the state from the file names list he created, the files from the malicious directory will be executed instead.
This happens because
- The attacker created files with the same name in the malicious directory.
- The `_run_hooks_for_state` method already sorted the scripts by root permissions and it does not verify the files permissions again
As a result, those files will be executed with root permissions.
In order to check the networkd-dispatcher version, run the following command:
sudo apt-get policy `networkd-dispatcher`
Only Debian and Ubuntu based Linux machines are affected.
10 – 2.0-2
11 – 2.1-2
12 – 2.1-2
Sid – 2.1-2
18.04 – 1.7-0ubuntu3.4
20.04 – 2.1-2~ubuntu20.04.2
21.10 – 2.1-2ubuntu0.21.10.1
22.04 – 2.1-2ubuntu0.22.04.1
18.04 – 1.7-0ubuntu3.5
20.04 – 2.1-2~ubuntu20.04.3
21.10 – 2.1-2ubuntu0.21.10.2
22.04 – 2.1-2ubuntu0.22.04.2
Was not released yet
Upgrade the `networkd-dispatcher` version using the following command:
sudo apt-get update
Remove the networkd-dispatcher by using one of the following commands:
sudo apt-get remove networkd-dispatcher
sudo systemctl stop systemd-networkd.service
sudo systemctl disable systemd-networkd.service
We recommend you to be aware of the following:
- If you are running on an Ubuntu machine, make sure the networkd-dispatcher has the fixed version.
- If you are running on a Debian machine, make sure to mitigate the Nimbuspwn and update the networkd-dispatcher to the fixed version once it is released.