Skip to content

AustralianCyberSecurityCentre/azul-plugin-python

Repository files navigation

Azul Plugin Python Decompiler

Python bytecode decompiler for Azul 3.

Decompiles python code up to Python version 3.9

Development Installation

To install azul-plugin-python for development run the command (from the root directory of this project):

pip install -e .

Usage

Usage on local files:

azul-plugin-python malware.file

Example Output:

----- PythonDecompiler results -----
OK

Output features:
  python_compile_time: 2018-02-25 23:07:10
                  tag: python_bytecode
       python_version: 2.7

Feature key:
  python_compile_time:  Python bytecode compile time
  python_version:  Python version compiled for
  tag:  Any informational label about the sample

Generated child entities (1):
  {'action': 'decompiled'} <binary: 9c4ac3ea5bf4598938b60d079b241152976dde7463f864228baa3940c9556d7b>
    content: 9053 bytes

Automated usage in system:

azul-plugin-python --server http://azul-dispatcher.localnet/

Issues

  • Attempts are made to normalise the uncompyle6 output to prevent output hash mismatches but they may change on minor updates. This will break tests.

Why wrap uncompyle6

The two main advantages that python_decompiler provides over using uncompyle6 are

  • It allows in memory handling of decompilation, with no need to read or write temporary files
  • It is easier to call from other scripts

Example

python_decompiler samples/NetflixChecker.pyc

Yields:

Decompiling samples/NetflixChecker.pyc
Magic number recognised - Python 3.7.0
version: 3.7
magic: 3394
filename: NetflixChecker.py
15009 bytes written to NetflixChecker.py (2cd1471c3db139374f06ffdf35af0c35)

Partial decompilation

In cases where uncomplye6 may not be able to completely decompile some Python bytecode files. In those cases python_decompiler will return as much of the original source as uncompyle6 could decompile.

Decompiling samples/nanobomber.pyc
Magic number recognised - Python 3.8.0rc1+
Decompiling...
magic: 3344
version: 3.8
filename: nanobomber.py
15036 bytes written to nanobomber.py (c61a4738b79a5de5f6685257b10ba85b)
error_type: Decompile

nanobomber.pyc could not be completely decompiled, examining the tail of the output file (nanobomber.py) shows comments uncompyle6 has appended comments to the source it was able to decompile:

# NOTE: have internal decompilation grammar errors.
# Use -t option to show full context.
# not in loop:
#       break (2)
#      0.  L. 340      3492  POP_EXCEPT
#      1.          3494_3496  BREAK_LOOP         3508  'to 3508'

# file /tmp/tmpcdnm37ry.pyc
# Deparsing hit an internal grammar-rule bug

PyInstaller

Extracts Python bytecode and libraries from PyInstaller executables. Python bytecode may be decompilable with existing Python decompilers (uncompyle6 or decompyle3).

Currently configured to process:

  • Win32 EXE
  • ELF
  • Mach-O

Example Output:

----- AzulPluginUnbox-pyinstaller results -----
COMPLETED

events (3)

event for binary:12a04feb4e388ad3a3e16ce8f1798dd4927af2828c2a1ae1fcbd8acf77e4e4af:None
  {}
  output features:
                     box_count: 2
                  box_filepath: PYZ-00.pyz
                                unknown_unicode_filename.pyc
                      box_type: pyinstaller
    pyinstaller_build_platform: Windows
                python_library: __future__
                                _compat_pickle
                                _compression
                                _py_abc
                                _pydatetime
                                _pydecimal
                                _strptime
                                _threading_local
                                argparse
                                ast
                                base64
                                bisect
                                bz2
                                calendar
                                code
                                codeop
                                contextlib
                                contextvars
                                copy
                                csv
                                ctypes
                                dataclasses
                                datetime
                                decimal
                                dis
                                email
                                fnmatch
                                fractions
                                getopt
                                gettext
                                gzip
                                hashlib
                                hmac
                                http
                                importlib
                                inspect
                                ipaddress
                                json
                                logging
                                lzma
                                mimetypes
                                numbers
                                opcode
                                pathlib
                                pickle
                                pprint
                                py_compile
                                pyaes
                                queue
                                quopri
                                random
                                selectors
                                shutil
                                signal
                                socket
                                sqlite3
                                ssl
                                statistics
                                string
                                stringprep
                                subprocess
                                tarfile
                                tempfile
                                textwrap
                                threading
                                token
                                tokenize
                                tracemalloc
                                typing
                                urllib
                                urllib3
                                zipfile
                python_version: Python 3.12

event for binary:95d840c8a9e9b100e6bfbfabb33875c2fb66f4d3e6a80a014a36c47a9afad995:None
  {'action': 'unpacked'}
  child of binary:12a04feb4e388ad3a3e16ce8f1798dd4927af2828c2a1ae1fcbd8acf77e4e4af
  output data streams (1):
    1616841 bytes - EventData(hash='95d840c8a9e9b100e6bfbfabb33875c2fb66f4d3e6a80a014a36c47a9afad995', label='content')
  output features:
    filename: PYZ-00.pyz

event for binary:f4aa6bd7b64c46ace259fae65d1f24ea2f47f380f67b2394a53ed84defcdc6b4:None
  {'action': 'unpacked'}
  child of binary:12a04feb4e388ad3a3e16ce8f1798dd4927af2828c2a1ae1fcbd8acf77e4e4af
  output data streams (1):
    1470 bytes - EventData(hash='f4aa6bd7b64c46ace259fae65d1f24ea2f47f380f67b2394a53ed84defcdc6b4', label='content')
  output features:
    filename: unknown_unicode_filename.pyc

Feature key:
  box_count:  Number of items found in the box
  box_filepath:  This entity contains this filepath
  box_type:  The binary is of this box type
  filename:  The name of the file in its parent archive
  pyinstaller_build_platform:  Platform used to build PyInstaller archive
  python_library:  Python library package within this archive
  python_version:  Python version used to build archive

Python Package management

This python package is managed using a setup.py and pyproject.toml file.

Standardisation of installing and testing the python package is handled through tox. Tox commands include:

# Run all standard tox actions
tox
# Run linting only
tox -e style
# Run tests only
tox -e test

Dependency management

Dependencies are managed in the requirements.txt, requirements_test.txt and debian.txt file.

The requirements files are the python package dependencies for normal use and specific ones for tests (e.g pytest, black, flake8 are test only dependencies).

The debian.txt file manages the debian dependencies that need to be installed on development systems and docker images.

Sometimes the debian.txt file is insufficient and in this case the Dockerfile may need to be modified directly to install complex dependencies.

About

Python bytecode decompiler for Azul 3.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •