Tech News
← Back to articles

A free and open-source rootkit for Linux

read original related products more articles

A free and open-source rootkit for Linux [LWN subscriber-only content]

Welcome to LWN.net The following subscription-only content has been made available to you by an LWN subscriber. Thousands of subscribers depend on LWN for the best news from the Linux and free software communities. If you enjoy this article, please consider subscribing to LWN. Thank you for visiting LWN.net!

While there are several rootkits that target Linux, they have so far not fully embraced the open-source ethos typical of Linux software. Luckily, Matheus Alves has been working to remedy this lack by creating an open-source rootkit called Singularity for Linux systems. Users who feel their computers are too secure can install the Singularity kernel module in order to allow remote code execution, disable security features, and hide files and processes from normal administrative tools. Despite its many features, Singularity is not currently known to be in use in the wild — instead, it provides security researchers with a testbed to investigate new detection and evasion techniques.

Alves is quite emphatic about the research nature of Singularity, saying that its main purpose is to help drive security research forward by demonstrating what is currently possible. He calls for anyone using the software to " be a researcher, not a criminal ", and to test it only on systems where they have explicit permission to test. If one did wish to use Singularity for nefarious purposes, however, the code is MIT licensed and freely available — using it in that way would only be a crime, not an instance of copyright infringement.

Getting its hooks into the kernel

The whole problem of how to obtain root permissions on a system and go about installing a kernel module is out of scope for Singularity; its focus is on how to maintain an undetected presence in the kernel once things have already been compromised. In order to do this, Singularity goes to a lot of trouble to present the illusion that the system hasn't been modified at all. It uses the kernel's existing Ftrace mechanism to hook into the functions that handle many system calls and change their responses to hide any sign of its presence.

Using Ftrace offers several advantages to the rootkit; most importantly, it means that the rootkit doesn't need to change the CPU trap-handling vector for system calls, which was one of the ways that some rootkits have been identified historically. It also avoids having to patch the kernel's functions directly — kernel functions already have hooks for Ftrace, so the rootkit doesn't need to perform its own ad-hoc modifications to the kernel's machine code, which might be detected. The Ftrace mechanism can be disabled at run time, of course — so Singularity helpfully enables it automatically and blocks any attempts to turn it off.

Singularity is concerned with hiding four classes of things: its own presence, the existence of attacker-controlled processes, network communication with those processes, and the files that those processes use. Hiding its own presence is actually fairly straightforward: when the kernel module is loaded, it resets the kernel's taint marker and removes itself from the list of active kernel modules. This also means that Singularity cannot be unloaded, since it doesn't appear in the normal interfaces that are used for unloading kernel modules. It also blocks the loading of subsequent kernel modules (although they will appear to load — they'll just silently fail). Consequently, Alves recommends experimenting with Singularity in a virtual machine.

Hiding processes

Hiding processes, on the other hand, is more complicated. The mechanism that Singularity uses starts by identifying and remembering which processes are supposed to be hidden. Singularity uses a single 32-entry array of process IDs to track attacker-controlled processes; this is because a more sophisticated data structure would introduce more opportunities for the rootkit to be caught, either by adding additional memory allocations that could be noticed, or by introducing delays whenever one of its hooked functions needs to check the list of hidden process IDs.

... continue reading