/formatic

automatic traversal of format() string injections

Primary LanguagePythonMIT LicenseMIT

formatic

🔑 automated traversal of Python format() string injections 🐍

pypi python version


Synopsis

formatic is a Python tool and library for automated traversal of Python format() string injections, leaking system information of a vulnerable service.

Installation

To install via pip:

pip install formatic

To install the latest version from source:

git clone https://github.com/welchbj/formatic
cd formatic
python setup.py

To install a development copy of the environment:

git clone https://github.com/welchbj/formatic
cd formatic
pip install -r dev-requirements.txt

Usage

formatic is usable against Python programs that are vulnerable to format() string injections. A targeted application must also return the result of the format string injection to the user, so that formatic can process it.

formatic comes with a builtin harness for injecting into any program that can be called from the command-line. All you have to do is specify the command as you would invoke it from the terminal, marking the injectable field with the @@ marker.

This repository contains a couple of applications that are vulnerable to format() string injections. To inject into a vulnerable local command-line program, try:

formatic -v -- python demo/vulnerable_cli_app.py --inject @@

To inject into a vulnerable local web server, first run the server with:

python demo/vulnerable_web_app.py 8888

And then run formatic against it:

formatic -v -- curl -g http://localhost:8888/inject/@@

License

formatic is intended for educational purposes and events such as CTFs only and should never be run on machines and/or networks without explicit prior consent. This code is released under the MIT license.

Known Issues

This tool is far from perfect and is currently in a proof-of-concept stage. You may experience the following shortcomings if you choose to use it:

  • No handling for Python 2 func_closure and Python 3 __closure__ function attributes; you will likely experience this when trying to decompile code involving super(SuperClass, self).__init__() calls
  • No decompilation of list comprehensions that are passed within a function's __code__.co_constants tuple
  • No recovery of values for complex (i.e., non str or int literals) class-level attributes
  • Functions decorated with @classmethod are not retrieved nor reported in decompiled source

Development

The following linting should be performed on any committed code:

# pep8 compliance
flake8 .

# type checking
mypy .

When it's time to cut a release:

# clean any old dist builds
rm -r dist/

# build source and wheel distributions
python setup.py bdist_wheel sdist

# run post-build checks
twine check dist/*

# upload to PyPI
twine upload dist/*

References

The following resources were a great help in getting this project up and running: