Linux based user-land rootkit (part 1)
Introduction
I was recently attempting a HackTheBox machine, and the machine included a quite interesting problem. There was a simple user-land rootkit running on the machine which hooked the ls command in a way that hides a file. A partial solution was to "remove" the rootkit in order to see a hidden file.
I found this quite interresting so i wanted to attempt to create a simple shared library that was to be loaded prior to the ls command's own libraries. My custom library would hook the readdir() function and make it ignore if a file included "secret" in it's name.
Simple file hider module
This is a simple file hider test for a linux based user-land rootkit. It uses dlsym() to create a handle for the original readdir() function which is the normal ls command uses to read dirent stuctures.
The dirent structures represent the next directory entry in the dirp stream, and dirp is a pointer to a DIR structure which is an open directory stream.
If the value returned by the original readdir() function contains a substring of in this case "secret" it will skip the file/directory thereby hiding it from user view while running ls in a folder.
Compiling
To compile the module run the following command
gcc -fPIC -shared -o hide.so src/main.c -ldl
The compiler flags do as follows:
-
-fPIC Is Position-Independant Code which tells the compiler to generate code that can be relocated at runtime without modifications. This is a requirement for building shared libraries.
-
-shared Tells the compiler to produce a shared library file instead of an executable (.so)
-
-o Just specifies the output file name.
-
-ldl Links the dynamic linking library libdl which is used for dlsym() in this case
Loading the library
In order to load the custom library along side ls so that it uses this library instead of it's own readdir() we'll have to utilize LD_PRELOAD. This makes sure that our custom library with the modified readdir() is loaded before any other library when running ls in the terminal.