Skip to main content

Maco - Malware config extractor framework

Maco is a framework for malware config extractors.

It aims to solve two problems:

  • Define a standardize ontology (or model) for extractor output. This greatly helps for databasing extracted values.
  • Provide a standard way of identifying which parsers to run and how to execute them.

Maco components

  • model.py
    • A data model for the common output of an extractor
  • extractor.py
    • Base class for extractors to implement
  • collector.py
    • Utilities for loading and running extractors
  • cli.py
    • A CLI tool maco to assist with running your extractors locally
  • base_test.py
    • Assist with writing unit tests for your extractors

Note: If you're interested in using only the model in your project, you can pip install maco-model which is a smaller package containing only the model definition

Project Integrations 🛠️

This framework is actively being used by:

Project Description License
A malware analysis platform that uses the MACO model to export malware configuration extractions into a parseable, machine-friendly format License
configextractor-py A tool designed to run extractors from multiple frameworks and uses the MACO model for output harmonization License
A robust, multiprocessing-capable, multi-family RAT config parser/extractor that is compatible with MACO License
A parser/extractor repository containing MACO extractors that's authored by the CAPE community but is integrated in CAPE deployments.
Note: These MACO extractors wrap and parse the original CAPE extractors.
License
A parser/extractor repository containing MACO extractors that's authored by the SEKOIA community. License
A malware knowledge base designed for malware archiving, analytics and clustering that supports MACO extractors License

Model Example

See the model definition for all the supported fields. You can use the model independently of the rest of the framework. This is still useful for compatibility between systems!

from maco import model
# 'family' is the only required property on the model
output = model.ExtractorModel(family="wanabee")
output.version = "2019"  # variant first found in 2019
output.category.extend([model.CategoryEnum.cryptominer, model.CategoryEnum.clickfraud])
output.http.append(model.ExtractorModel.Http(protocol="https",
                                             uri="https://bad-domain.com/c2_payload",
                                             usage="c2"))
output.tcp.append(model.ExtractorModel.Connection(server_ip="127.0.0.1",
                                           usage="ransom"))
output.campaign_id.append("859186-3224-9284")
output.inject_exe.append("explorer.exe")
output.binaries.append(
    output.Binary(
        data=b"sam I am",
        datatype=output.Binary.TypeEnum.config,
        encryption=output.Binary.Encryption(
            algorithm="rot26",
            mode="block",
        ),
    )
)
# data about the malware that doesn't fit the model
output.other["author_lunch"] = "green eggs and ham"
output.other["author_lunch_time"] = "3pm"
print(output.model_dump(exclude_defaults=True))

# Generated model
{
    'family': 'wanabee',
    'version': '2019',
    'category': ['cryptominer', 'clickfraud'],
    'campaign_id': ['859186-3224-9284'],
    'inject_exe': ['explorer.exe'],
    'other': {'author_lunch': 'green eggs and ham', 'author_lunch_time': '3pm'},
    'http': [{'uri': 'https://bad-domain.com/c2_payload', 'usage': 'c2', 'protocol': 'https'}],
    'tcp': [{'server_ip': '127.0.0.1', 'usage': 'ransom'}],
    'binaries': [{
        'datatype': 'config', 'data': b'sam I am',
        'encryption': {'algorithm': 'rot26', 'mode': 'block'}
    }]
}

And you can create model instances from dictionaries:

from maco import model
output = {
    "family": "wanabee2",
    "version": "2022",
    "ssh": [
        {
            "username": "wanna",
            "password": "bee2",
            "hostname": "10.1.10.100",
        }
    ],
}
print(model.ExtractorModel(**output))

# Generated model
family='wanabee2' version='2022' category=[] attack=[] capability_enabled=[]
capability_disabled=[] campaign_id=[] identifier=[] decoded_strings=[]
password=[] mutex=[] pipe=[] sleep_delay=None inject_exe=[] other={}
binaries=[] ftp=[] smtp=[] http=[]
ssh=[SSH(username='wanna', password='bee2', hostname='10.1.10.100', port=None, usage=None)]
proxy=[] dns=[] tcp=[] udp=[] encryption=[] service=[] cryptocurrency=[]
paths=[] registry=[]

Extractor Example

The following extractor will trigger on any file with more than 50 ELF sections, and set some properties in the model.

Your extractors will do a better job of finding useful information than this one!

class Elfy(extractor.Extractor):
    """Check basic elf property."""

    family = "elfy"
    author = "blue"
    last_modified = "2022-06-14"
    yara_rule = """
        import "elf"

        rule Elfy
        {
            condition:
                elf.number_of_sections > 50
        }
        """

    def run(
        self, stream: BytesIO, matches: List[yara.Match]
    ) -> Optional[model.ExtractorModel]:
        # return config model formatted results
        ret = model.ExtractorModel(family=self.family)
        # the list for campaign_id already exists and is empty, so we just add an item
        ret.campaign_id.append(str(len(stream.read())))
        return ret

Writing Extractors

There are several examples that use Maco in the 'demo_extractors' folder.

Some things to keep in mind:

  • The Yara rule names must be prefixed with the extractor class name.
    • e.g. Class 'MyScript' has Yara rules named 'MyScriptDetect1' and 'MyScriptDetect2', not 'Detect1'
  • You can load other scripts contained within the same folder via a Python relative import
    • See complex.py for details
  • You can standardise your usage of the 'other' dict
    • This is optional, see limit_other.py for details
    • Consider instead making a PR with the properties you are frequently using

Requirements

Python 3.8+.

Install this package with pip install maco.

All required Python packages are in the requirements.txt.

For tests to pass libmono must be installed The recommended way to do that on linux is to run the command sudo apt install mono-devel mono-complete -y

CLI Usage

> maco --help
usage: maco [-h] [-v] [--pretty] [--base64] [--logfile LOGFILE] [--include INCLUDE] [--exclude EXCLUDE] [-f] [--create_venv] extractors samples

Run extractors over samples.

positional arguments:
  extractors         path to extractors
  samples            path to samples

optional arguments:
  -h, --help         show this help message and exit
  -v, --verbose      print debug logging. -v extractor info, -vv extractor debug, -vvv cli debug
  --pretty           pretty print json output
  --base64           Include base64 encoded binary data in output (can be large, consider printing to file rather than console)
  --logfile LOGFILE  file to log output
  --include INCLUDE  comma separated extractors to run
  --exclude EXCLUDE  comma separated extractors to not run
  -f, --force        ignore yara rules and execute all extractors
  --create_venv      Creates venvs for every requirements.txt found (only applies when extractor path is a directory)

CLI output example

The CLI is helpful for using your extractors in a standalone system, such as in a reverse engineering environment.

> maco demo_extractors/ /usr/lib --include Complex
extractors loaded: ['Complex']

complex by blue 2022-06-14 TLP:WHITE
This script has multiple yara rules and coverage of the data model.

path: /usr/lib/udev/hwdb.bin
run Complex extractor from rules ['ComplexAlt']
{"family": "complex", "version": "5", "decoded_strings": ["Paradise"],
"binaries": [{"datatype": "payload", "size": 9, "hex_sample": "736F6D652064617461", "sha256": "1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee",
"encryption": {"algorithm": "something"}}],
"http": [{"protocol": "https", "hostname": "blarg5.com", "path": "/malz/9956330", "usage": "c2"}],
"encryption": [{"algorithm": "sha256"}]}

path: /usr/lib/udev/hwdb.d/20-OUI.hwdb
run Complex extractor from rules ['ComplexAlt']
{"family": "complex", "version": "5", "decoded_strings": ["Paradise"],
"binaries": [{"datatype": "payload", "size": 9, "hex_sample": "736F6D652064617461", "sha256": "1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee",
"encryption": {"algorithm": "something"}}],
"http": [{"protocol": "https", "hostname": "blarg5.com", "path": "/malz/1986908", "usage": "c2"}],
"encryption": [{"algorithm": "sha256"}]}

path: /usr/lib/udev/hwdb.d/20-usb-vendor-model.hwdb
run Complex extractor from rules ['ComplexAlt']
{"family": "complex", "version": "5", "decoded_strings": ["Paradise"],
"binaries": [{"datatype": "payload", "size": 9, "hex_sample": "736F6D652064617461", "sha256": "1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee",
"encryption": {"algorithm": "something"}}],
"http": [{"protocol": "https", "hostname": "blarg5.com", "path": "/malz/1257481", "usage": "c2"}],
"encryption": [{"algorithm": "sha256"}]}


15884 analysed, 3 hits, 3 extracted

The demo extractors are designed to trigger when run over the 'demo_extractors' folder.

e.g. maco demo_extractors demo_extractors

Contributions

Please use ruff to format and lint PRs. This may be the cause of PR test failures.

Ruff will attempt to fix most issues, but some may require manual resolution.

pip install ruff
ruff format
ruff check --fix

Metadata

Release files for maco 1.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maco 1.3.3
File Size Uploaded
maco-1.3.3.tar.gz 129.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maco 1.3.3
File Interpreter ABI Platform
maco-1.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 248.5 kB

Release files / maco-1.3.3.tar.gz

Download URL maco-1.3.3.tar.gz
Size 129.9 kB
Tags Source
SHA-256 checksum
How to use checksums
2c5c426a1eaf8c83b21904b584faf40894dbfc318eb4abd3ac5110f40dec434d
BLAKE2b-256 checksum
How to use checksums
8cc33d7db53cf97860fdaaef7bdc11d5bb48489ce4832b0e1be5759c8b0decb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release files / maco-1.3.3-py3-none-any.whl

Download URL maco-1.3.3-py3-none-any.whl
Size 118.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b66c3ba59e64001ce6d3aac707b9c5a1ca772b7c9ead8a0fae718efde6d8639c
BLAKE2b-256 checksum
How to use checksums
6bfc5aa063e3bead43c32ae664d027898ea98874dba1f83722db8fb89a728cac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release history Release notifications | RSS feed

This release

1.3.3 This release

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.26

2 release files

1.2.24

2 release files

1.2.23

2 release files

1.2.20

2 release files

1.2.16

2 release files

1.2.15

2 release files

1.2.14

2 release files

1.2.11

2 release files

1.2.10

2 release files

1.2.9

2 release files

1.2.8

2 release files

1.2.7

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.11

2 release files

1.1.10

2 release files

1.1.9

2 release files

1.1.8

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.15

2 release files

1.0.14

2 release files

1.0.10

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page