Path Hijacking and Library Hijacking are two basic privilege escalation techniques, which when combined with, for example, SUID privilege or sudo, can become dangerous from a security standpoint.
Table of Contents:
What is the PATH?
When we execute a command in a terminal or cmd, how does the shell know that the word we’ve written corresponds to a command with X function. What decides whether a command is detected or not?:

All of this is thanks to the PATH. The path is an environment variable which contains system paths. When we execute a command, the system searches for a file with the name of the command we’ve written, in each path of the PATH.
That is, for example, when we write pwd, the system will search for a file with the same name in the following directories in the following order:

The same would happen on Windows:

And it also applies to programming languages, for example, Python:

This would be the path for when we want to load a library.
The path is only used when relative paths are written:

In the first execution, the system used the path to find where the whoami binary was, however, in the second one it’s not necessary, because we already indicate where it is. So in the second way we can avoid attacks like path hijacking and library hijacking. For the development of any binary/script, it’s highly recommended to always use absolute paths, both for commands if we’re in a command language like bash or libraries if we’re in a programming language like Python for example.
Path Hijacking
To perform path hijacking I’ve created the following program in C:

As we can see, the program outputs the first 10 lines of the passwd file twice, the first one is done using the absolute path of head, and the second, in a relative way. At this point, we compile with gcc to create the binary:

Note: in this case I do it with a compiled binary to be able to use the SUID permission properly.
To see more clearly the danger of not using absolute paths, I’m going to assign SUID permission to it:

With this, if we execute the binary from the normal user we’ll do it as the root user due to the SUID permission:

With all this done, we’re going to carry out the Path Hijacking, if we do a strings on the binary we can identify that the command is being called in a relative way (this would be a possible way to identify it if we don’t have access to the original code):

strings prints readable character strings
This way we can realize it, although it’s not always the case that we can see it.
Additionally, we can notice that setuid is being used in the code, this means that the code will execute with the user of the UID we indicate (careful, even if we put 0, it won’t execute as root if it doesn’t have the SUID permission, you need so to speak a double check, that’s why in addition to setuid at 0, we give it the SUID permission. This double check wouldn’t apply if we were the root user, since we have total privileges, so with setuid it would be enough).
At this point, we’re going to change the PATH by adding the current path and the PATH variable itself, to avoid command problems:

At this point, since the command we want to impersonate is head, we create a file with the same name that contains the command we want to execute, in my case, bash -p:

With the path changed to look in the current path and a file that impersonates the legitimate head, if we now execute the binary:

We see how in the part of the code that executes head in a relative way, the command we’ve written is executed, this way we’ve executed a path hijacking (path hijack) and obtained a shell as root.
Library Hijacking
Understanding path hijacking, library hijacking is basically the same thing, just changing the practical aspect a bit. We’re going to use the following code in Python:

As we can see, the function of the script is to make a request to the blog and see its response code:

So, as seen in the code, the requests library is being called in a relative way:

We’re going to take advantage of this to execute a Library Hijacking. The first thing is to check the path that python3 follows, we can do this with the sys library:

If we notice, the first place where Python checks by default for the existence of the library is in '', this means the current path. So we’ll simply create a file called requests.py in the current path:

This way, if we execute the script:

We manage to execute the command we’ve specified, in this case, a shell.
Be careful, in this case, we don’t apply the SUID privilege to Python, since being a script, it interferes with the security layer of the SUID permission itself:

However, we could take advantage of it to become root if for example we have sudo privileges over the execution of the script.