Exploiting Linux Capabilities – Part 6

Learn the basics of process injection and kernel modules. Build your own rootkits to exploit cap_sys_ptrace and cap_sys_module capabilities in the Linux kernel

Exploiting Linux Capabilities – Part 6

This is the last part of Exploiting Linux Capabilities sub-series from the main Linux Privilege Escalation series. In the previous posts, I have discussed with you the exploitation of capabilities related to files, networking and system administrations. If you haven't read those, I would recommend you to first read those parts and then come back here with a context of knowledge.

In this post, I will be covering three labs from attack defence on the Linux kernel module and process injection. Since this is not a post on process injection or rootkits, I will just touch the surface of the ocean

So let's begin...


In this lab, a python interpreter has cap_sys_ptrace capability in the effective and permitted set

Getting capable files recursively from the root directory

When a process is running with cap_sys_ptrace capability in its effective set, it can open the process and write data into its memory. This means you can inject the running process with your malicious bind shell shellcode and then later connect to it. You will get the shell with the current uid of the process. With this capability, if a process is running with the root user, you can directly escalate to the root user and get a privileged shell

From the man page of capabilities

I found that the nginx parent process is running with the root user. I have copied and executed the exploit code from hacktricks gitbook – https://book.hacktricks.xyz/linux-unix/privilege-escalation/linux-capabilities#example-with-binary-1

This code will inject a shellcode in the nginx process and open a bind shell on 5600

Injecting to nginx process

After injecting the shellcode, I can see port 5600 is open as explained earlier. Now I can connect to the port with netcat and execute commands as the root user

Connecting to bind shell and retrieve the flag


I have found that in this case, kmod binary has cap_sys_module capability in both effective and permitted sets

Getting capable files recursively from the root directory

The Linux kernel allows extending its functionality by allowing users to add or remove kernel modules. These are pluggable pieces of code, each performing some definite set of operations. For instance, when you add virtual box guest additions, it injects the kernel modules to allow seamless interaction with the host OS. So it is clear to have such privileges, you should be a root user. But if a process is running with cap_sys_module capability, it can perform such operations. And, if a process like a python or kmod is having this capability, you can directly escalate to the root user using the reverse shell.

Since how a kernel module works are not in the scope of this post, I managed to get the codes snippets from hacktricks gitbook – reverse-shell.c and Makefile.

The commands in Makefile must be indented with TAB characters, so I made the changes in the make file using tab instead of spaces

obj-m +=reverse-shell.o

-    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

-    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Fixed indentation bug in the Makefile

It's time to build the kernel object (aka module). To do this run make command

Getting capable files recursively from the root directory

After the build succeeded, I found that there is a file named reverse-shell.ko. This is the kernel object which I can inject into the module. Since this is a one-time reverse shell, I have started the ncat listener on a separate tab.

I have used the insmod tool to insert the kernel module that internally use the kmod command to perform the actual injection. Since kmod in this lab has cap_sys_module, it will run successfully

After injecting I got a reverse connection to another tab with the root user bash shell.

Got reverse connection after injecting the kernel object

All I needed to do now was to find the flag file in the system and read it

Read the flag


In this lab, the python interpreter has cap_sys_module in the effective and permitted set and the kmod module is installed in python

Getting capable files recursively from the root directory

If you see a python interpreter allowed to manage kernel modules and kmod is installed. You can use the modprobe utility to inject the kernel module.

Modprobe requests some pre-processing which I have ignored in the previous lab. You need to first create a modules directory and copy modules from the system into this directory

$ mkdir lib/modules -p
$ cp -a /lib/modules/$(uname -r)/ lib/modules/$(uname -r)
Copy system modules into a local directory lib/modules

I got the exploit code from the same link shared while discussing the previous lab and built the code kernel module after fixing the Makefile issue, again.

This time, I need to copy the compiled kernel module into the lib/modules/$(uname -r) directory. This is required for modprobe

Building and copying the kernel module in the lib/modules/$(uname -r)/ directory

Since this is a reverse shell, I need to start the listener in a different tab

ncat listener on port 4444

I used the depmod tool to update the kernel module list which eventually modprobe will read while finding and inserting the module

Inserting the kernel module

As soon as the module was injected, I got a reverse connection on the netcat server, I opened it in a different tab.

Got reverse connection from kernel module