Skip to content

Write modules in Python3.9

jm33-m0 edited this page Mar 16, 2022 · 2 revisions

Python3.9 environment

Python3.9 environment is provided by vaccine.

You can delete binaries in modules/vaccine if you don't need them, to reduce the size of utils.tar.bz2.

The files needed by python3.9 are:

libs.tar.xz
python3.9.tar.xz
python3

If vaccine is not installed on your target, try use vaccine, and run to make sure it's installed correctly.

In the shell pane, try open python (not python3), and import sys, sys.path, check if python works.

You can also use the py_info module to check python environment, use py_info to get started.

All built-in packages are working fine, site-packages include:

Package                Version
---------------------- ---------
appdirs                1.4.4
beautifulsoup4         4.10.0
bs4                    0.0.1
CacheControl           0.12.10
certifi                2021.10.8
charset-normalizer     2.0.12
colorama               0.4.4
contextlib2            21.6.0
distlib                0.3.3
html5lib               1.1
idna                   3.3
lockfile               0.12.2
mysql-connector-python 8.0.28
packaging              20.9
pep517                 0.12.0
pip                    22.0.4
progress               1.6
protobuf               3.19.4
requests               2.27.1
retrying               1.3.3
six                    1.16.0
soupsieve              2.3.1
toml                   0.10.2
urllib3                1.26.8
webencodings           0.5.1

Write modules

Dependencies

Take a look at dockerscan.

Your modules are very likely to be like dockerscan, which requires external python packages, or even C libraries (not covered, I suggest avoid that)

As noted, emp3r0r's python3.9 environment comes with all built-in libraries and necessary third party packages, you are recommended not to use any third party libraries unless necessary.

If you really need to install more dependencies, try something like python -m pip install -t ./libs, that way all packages will be installed in ./libs, so you can just change sys.path for python to load them.

For example:

libs = f"{os.getcwd()}/libs"

parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(1, parent_dir)
sys.path.insert(1, libs)

import pwn # or whatever packages you have installed

emp3r0r's python version is 3.9.7, therefore I suggest doing pip install with the exact same version of python, to avoid compatibility issues. If you don't know how to run a different version of python on your system, check pyenv.

Compress your dependencies with tar --exclude="*.pyc" --exclude="__pycache__" -cJvpf libs.tar.xz libs, libs.tar.xz will be automatically unarchived when loading your module. Note that you have to use the exact file names as shown in the tar command.

User options

Your module might need some runtime variables, for example an RCE exploit needs a target option. To add options to your module, write config.json like this:

{
    "name": "Spring_Cloud_Gateway_RCE",
    "exec": "CVE-2022-22947.py",
    "platform": "Linux",
    "interactive": false,
    "author": "Axx8",
    "date": "2022-03-03",
    "comment": "CVE-2022-22947, see https://github.com/Axx8/CVE-2022-22947_Rce_Exp",
    "options": {
        "TARGET_URL": ["http://11.11.11.11:8080", "Target URL"],
        "CMD_EXEC": ["whoami", "Command to execute on target server"]
    }
}

If your modules is interactive, like ipython, set interactive to true

When using your module, do something like set CMD_EXEC whoami to configure your runtime variables.

How to receive those variables in your module/script?

if __name__ == '__main__':
    url = os.environ['TARGET_URL']
    cmd = os.environ['CMD_EXEC']
    exec(url, cmd)

The executable file

Your module needs to have an executable (python script) file. For example, like shown above, CVE-2022-22947.py

Your executable is run by a wrapper shell script start.sh:

TARGET_URL='http://127.0.0.1' CMD_EXEC='id -u' ./CVE-2022-22947.py

Here's a problem, you might have ported a python application that parses commandline arguments, how do you pass the required arguments to it using environment variables?

A possible solution is shown in dockerscan module:

#!/usr/bin/env python
# This shebang is needed!
# Our python interpreter will be the 1st in $PATH

import os
import sys

# run without args
# pass args via $ARGS environment variable
if len(sys.argv) == 1:
    args = os.environ["ARGS"]
    # re-run with args
    cmd = f"{sys.argv[0]} {args}"
    os.system(cmd)
    sys.exit(0)

# run with args
print(f"Actual work with args: {sys.argv}")