From time to time, you may come across a scenario where a system has misconfigured permissions in their Python library. Generally, directories that house Python modules have permissions set so that modifications can’t be made without elevated privileges. With that, there are a number of ways that users can create this vulnerability:
- The user creates their own Python module and forgets to restrict write access to it.
- The user decides to lessen restrictions within the Python library directory.
- The PATH variable for the Python library is configured to check the current directory first.
Regardless, in order to escalate privileges, we also need a way to execute a Python script with elevated privileges. This either means looking for a cronjob or scheduled task that executes Python scripts with either elevated privileges or leveraging other vulnerabilities, for example, through SUID files, to execute the script.
If we decide to explore this avenue as a potential method to escalate privileges, we first need to understand where Python looks within the file system to import its modules. We can leverage the “sys” module in Python to do this. You can read more about that here: https://docs.python.org/2/library/sys.html
Enumerating Python’s Path
From our terminal, we can run the following command to find the path:
python -c 'import sys; print(sys.path)'
Once we do this, we get something that looks like this:
This output shows a list of directories that Python looks in when importing modules. Python looks through this list in order. With this information, we have an idea of which directories we need to enumerate first. Once we find a directory we want to attack, we can start modifying both a target Python script or the library.
As proof of concept, I am going to demonstrate how you can leverage this misconfiguration from my own Kali host.
First, you need to identify a Python script that will be executed with elevated privileges. An example of this is a Python script that is run through a cronjob with elevated privileges. In our case, I have created a file called “hello.py” to simulate a script that is executed with elevated permissions.
This script does something very simple. Based on the code, we expect that the function of this script is to print the text, “hello world”. One thing to notice is that this script also appears to import a custom Python module called “evil”. Let’s find this in our Python library.
When we inspect this module, we can see that this module is written to print the text, “This is an evil script”.
Let’s assume that as an attacker, we only have read permissions to “hello.py”, but we have write permissions to our “evil” module. We know that we can’t do anything with “hello.py”, but what about the “evil” module?
One method we can use to leverage this misconfiguration is to modify the “evil” module to house a Python reverse shell. In this case, I used one from pentestmonkey ( http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet) and converted it from a one-liner to a script.
Now, all we have to do is wait until an elevated user executes the Python script, “hello.py”. When the elevated user executes the script, the “evil” module will also be imported which also executes the module. In our case, since we modified the content of the module with a reverse shell, we should have a root shell!
During the course of your enumeration, when you come across Python scripts that are executed with elevated permissions and misconfigured Python libraries, you can easily leverage that misconfiguration to obtain an elevated shell. When a Python script imports a module, the script also executes that module.