Aqua Nautilus researchers have identified a security issue that arises from the interaction between Ubuntu’s command-not-found
package and the snap package repository. While command-not-found
serves as a convenient tool for suggesting installations for uninstalled commands, it can be inadvertently manipulated by attackers through the snap repository, leading to deceptive recommendations of malicious packages.
Additionally, our research indicates that as many as 26% of commands associated with APT (Advanced Package Tool) packages are vulnerable to impersonation by malicious actors. This issue could pave the way for supply chain attacks affecting Linux users and Windows running WSL. This blog delves into the operational details of command-not-found
, the risks associated with installing compromised snap packages, and the various attack vectors that could be exploited.
The command-not-found package
The command-not-found
package, is installed by default on Ubuntu, it provides an invaluable service to Linux users: it suggests packages to install when they attempt to execute a command in Bash or Zsh that isn’t available on their system. This is achieved through the implementation of the command_not_found_handle
function, which Bash calls whenever it encounters an unrecognized command.
The package offers suggestions for both APT and snap packages. For instance, if a user tries to run ifconfig
and it’s not installed, the package will recommend installing net-tools
via apt:
Similarly, when users attempt to run the code
command, which is associated with Visual Studio Code, they will receive a recommendation to install the code
package via snap.
If a command corresponds to both a snap and an apt package, the command-not-found
package will suggest both options, as in the case of the mojo
command:
Understanding the ‘command-not-found’ suggestion algorithm
The command-not-found
package is equipped with an internal database that associates commands with popular APT packages, it’s important to note that the command name may differ from the package name (like the example of the ifconfig
command with the net-tools
package above). This database is only updated when the command-not-found
package itself is upgraded.
In contrast, for snap packages, the package relies on the snap advise-snap
command. This functionality, provided by snap, references its own regularly updated database sourced from the Snap Store.
How does the system decide which package to recommend? To understand this, we can delve into the code snippet below from the command-not-found
package.
The process begins with the command-not-found
package utilizing the get_packages
function to identify corresponding APT packages and the get_snaps
function to retrieve matching snap packages. Subsequently, it assesses several conditions to provide the most accurate suggestion possible. If no exact matches are found within both snap and APT repositories, it attempts to recommend similar commands, accounting for potential typos. In cases where exact matches exist, the suggestion hinges on the number of results, this is because there may be multiple snap or APT packages associated with the same command.
With our understanding of the suggestion mechanism employed by the command-not-found
package, which relies on the APT and snap repositories, an important question arises: How feasible is it for an attacker to manipulate this system to have their malicious package recommended by the command-not-found
package?
While APT packages operate on the host operating system without any restrictions, not just anyone can contribute a package to the official APT repositories. The developers must undergo an acceptance process before they are allowed to upload a package.
For these reasons and given that the command-not-found
package’s APT database isn’t updated regularly, our focus shifts to the potential for attackers to publish malicious packages in the snap repository.
Restrictions of snap packages
Now that we’ve established our interest in examining snap packages, it’s crucial to explore the restrictions the snap team has put upon publishers and their packages.
First, we need to understand the confinement level. There are 2 major levels of snap confinement:
- Strict confinement, which is used by most of the snap packages. Strictly confined snaps run in a sandboxed environment, they cannot access files, network, processes, or any other system resources (more details can be found here)
- Classic, which runs on the host’s machine just like an APT package without any restrictions.
This raises an immediate question: why wouldn’t a malicious actor just choose to distribute a classic snap? The safeguard here is the requirement for manual review by the snap team for snaps requesting certain privileges, such as classic confinement. However, not all applications require the complete set of permissions that classic confinement provides while still needing access to specific local system resources. To address this requirement, the interface mechanism was developed.
Snap interfaces
Snap interfaces serve as controlled gateways for strictly confined snap packages, enabling them to interact with external resources that are typically off-limits in a sandboxed environment. There are numerous interfaces (a comprehensive list is available here), each one of them effectively creates controlled “cracks” in the sandbox walls. Through these openings, snaps can engage with the host’s resources or the environments of other running snaps.
In the image above, we can observe a partial list of the available snap interfaces. Some interfaces grant snaps substantial privileges, allowing them to access and manipulate sensitive system resources, including account management and sound recording. Others provide more benign capabilities, such as ‘audio-playback,’ which simply permits a snap to play audio.
These interfaces can be categorized based on their auto-connect property. This property determines which interfaces can be attached to a snap package automatically (marked as yes), and which require manual approval by the snap team, just like classic confinement, before they can be published in the store.
The dangers of malicious strict snap packages
Our investigation concentrates on the most probable tactics an attacker might employ using malicious snap packages. With this in mind, we’re particularly interested in the capabilities of a snap package that does not trigger any manual review. Specifically, we aim to uncover what an attacker could potentially achieve with a strictly confined snap package, one that leverages only interfaces set to auto-connect without requiring manual approval.
The desktop interfaces
Although most of the permissive interfaces require manual review, the desktop interfaces can be connected automatically. These interfaces allow applications that have a Graphical User Interface (GUI) to connect to the display server and show windows on the host system.
In Linux, the display server is a program responsible for managing the graphical output and input on the system, enabling the Graphical User Interface (GUI). Applications communicate with the display server using specific display server protocols. Two examples of such protocols are X11 and Wayland. X11 has been a longstanding display server protocol, while Wayland is a newer protocol aimed at providing a more modern and secure windowing system to replace X11.
The main issue here is that the sandbox confinements strength depends on the capabilities of the display server. Consequently, outdated display servers like the X Window System, which uses the X11 protocol, lack real security separation between windows of different applications. This allows snaps that connect to the X11 interface to eavesdrop on other windows and potentially capture keystrokes from the host machine.
This issue is known to Canonical and Matthew Garrett wrote a blog about it in 2016, emphasizing the security gaps that snap confinement has on X11.
He released an open-source tool that demonstrates this flaw. I compiled this PoC with a few alterations and ran it on Ubuntu 22:
We can observe in the video above, how executing a snap called friendlyteddy
, that is strictly confined, can steal the credentials of a user typing them on the host.
While the snap team declare they want to path a transition from the insecure X server to safer display server protocols like Wayland, X server is still commonly used by distributions today. While Wayland is the default protocol in ubuntu 22, the X server still comes installed by default and there are many articles and posts on how to switch in Ubuntu to use the X server instead of Wayland – https://linuxconfig.org/how-to-use-x-instead-of-wayland-on-ubuntu-22-04.
Kernel vulnerabilities
Even if you avoid using the insecure X11 protocol, there are still risks associated with installing malicious snap packages. The host and all other active snap packages share the same kernel. This means that if there’s a vulnerability within the kernel that a snap package can exploit, it could breach the sandboxing and allow full control over the host system. Numerous vulnerabilities are discovered in the Linux kernel annually. In 2023 alone, there were 282 reported vulnerabilities (according to stack.watch). While each vulnerability varies in severity and not all can be exploited through a snap container, the potential threat remains significant.
Furthermore, snaps have an auto-update feature that automatically updates the version of the installed snap to the newest available. While this is good for patching vulnerabilities in the snap package itself, there are also security implications. This feature could be utilized by malicious actors to deploy exploits targeting new vulnerabilities. For instance, an attacker might impersonate a trusted package. Upon the discovery of a critical Linux kernel vulnerability, they could push a malicious update to the snap repository. As a result, the auto-update mechanism would automatically distribute the rogue version to all users, exploiting the kernel vulnerability before the users have had a chance to apply any security patches.
Command-Not-Found impersonation of packages
With a foundational understanding of snap packages and the risks associated with installing a malicious one, we circle back to our primary concern: the command-not-found
package. Our objective now is to investigate how an attacker could potentially exploit the command-not-found
system to deceive users into installing his malicious package.
Snap package commands aliases
Snap’s documentation specifies that to prevent conflicts from different snaps exposing the same application names, the snap’s commands format is <snap name>.<application name>
. When the snap name is identical to the application name, the command simplifies to just <snap name>
.
Take, for instance, a scenario where the snap is named code
and the application is vscode
, the command executed would be code.vscode
. Conversely, if the application name also happens to be code
, aligning with the snap name, the command simplifies from code.code
to just code
.
Should a developer wish for their snap to execute a command that deviates from the <snap name>.<application name>
format and is not simply <snap name>
, they must request an alias. Such a request initiates a manual review process in which the requested alias is voted on to ensure it aligns with the application.
However, since the registered name is merely an alias rather than the official snap name, the actual snap name remains up for grabs. This means that an attacker could potentially register the corresponding snap name, thereby impersonating the command.
Let’s look at an example.
In the image above, we observe that upon entering the command tarquingui
, the ‘command-not-found’ package recommends installing the snap tarquin
. The command tarquingui
doesn’t match the snap name exactly, which indicates that tarquingui
is an alias for the tarquin
snap (the alias request details can be found here). However, as previously noted, since an alias does not equate to a snap name reservation, this leaves room for an attacker to register the tarquingui
snap name and publish their own snap package under it.
Below is the output of the command, after we published a snap with the name tarquingui
:
An attacker could systematically review all command aliases through the Snap Store API to identify any alias whose snap name is still available. Upon finding one, they could register a new snap under that name, creating an opportunity to deceive users into installing a malicious package.
It is important to note that the documentation states that an alias is not necessarily unique, and there could be potential conflicts.
APT packages commands
We’ve already examined how snap packages could be impersonated, but the possibility of impersonating APT packages presents another concern. As previously mentioned, the command-not-found
utility relies on a local database located at /var/lib/command-not-found/commands.db
, which links commands to their corresponding APT packages, guiding users to make accurate installations.
We wanted to examine how many commands listed in this local database could be exploited by an attacker by registering them as snap package names. This would potentially lead to the command-not-found
utility suggesting a malicious snap package alongside the legitimate APT package.
Upon querying the Snap Store for each command to check for available snap package names, the findings were startling. We discovered that 26% of the APT package commands were available, presenting a substantial security risk, as they could be registered under an attacker’s account.
For example, one of these packages is the jupyter-notebook
package:
The maintainers of the jupyter-notebook
APT package had not claimed the corresponding snap name. This oversight left a window of opportunity for an attacker to claim it and upload a malicious snap named jupyter-notebook
. Below is the output following our registration of the jupyter-notebook
snap name and the upload of a dummy “malicious” package:
We can observe that the command-not-found utility suggests the snap package first, even before the original APT package. This behavior could potentially mislead users into installing the snap package.
The real danger lies in the scale of this issue. While a single malicious snap package posing as a legitimate APT or snap package is troubling, the prospect of an attacker systematically exploiting 26% of the APT package commands, including those with aliases in the snap store, could have devastating consequences.
Typosquatting attacks
Beyond matching the exact name of a widely used command, attackers can also leverage typosquatting tactics. This involves taking advantage of common typographical errors made by users.
For instance, consider what could occur if a user accidentally types ifconfigg
instead of ifconfig
:
In the example shown above, the command-not-found package helpfully corrects the user, suggesting the net-tools
package for the mistyped ifconfig
command. However, the situation becomes more problematic when an attacker capitalizes on these common mistakes by registering a snap with the typo, such as ifconfigg
.
As demonstrated before, the command-not-found
utility typically corrects the user by suggesting the correct net-tools
package for the mistyped ifconfig
command. However, should an attacker register a snap with the name ifconfigg
, the command-not-found
would mistakenly match it to this incorrect command and recommend the malicious snap (as demonstrated in the image above), bypassing the suggestion for net-tools
altogether.
Summary and mitigation
The risk of attackers exploiting the command-not-found
utility to recommend their own malicious snap packages is a pressing concern. The true peril lies in the potential scope of this issue, with attackers capable of mimicking thousands of commands from widely-used packages. Past instances of malicious packages appearing in the Snap Store highlight this issue (see references: Snapcraft Forum, The Next Web).
It remains uncertain how extensively these capabilities have been exploited, underscoring the urgency for heightened vigilance and proactive defense strategies.
To safeguard against such threats, users and package maintainers should adopt several preventative measures:
- Users should verify the source of a package before installation, checking the maintainers’ credibility and the recommended platform (whether snap or APT).
- Snap developers with an alias should promptly register the corresponding name if it aligns with their application to prevent misuse.
- Developers of APT packages are encouraged to register the associated snap name for their commands, preemptively securing them from potential impersonation by attackers.
- Aqua customers can block the execution of
APT
andsnap
in containerized workloads. The runtime solutions can detect malicious behavior stemming from exploitation of this issue.