You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
stasinopoulos edited this page Sep 14, 2026
·
3 revisions
Commix supports a modular design, making it easy to extend its capabilities by adding custom Python modules. This is useful for penetration testers, researchers, and developers who want to cover a vulnerability class that the standard techniques do not reach, without touching the core engine.
Modules versus techniques
A technique is one of the ways commix proves and drives command execution through an injectable
parameter - classic, dynamic code evaluation, time-based, file-based, tempfile-based. Techniques are
selected with --technique/--skip-technique and are tested against every injection point commix
finds.
A module is a self-contained check for a vulnerability class that does not fit that model,
usually because the injection point is not a parameter at all. It gets its own switch, runs instead
of the normal detection flow, and never goes through --technique. The bundled --shellshock
module is the reference implementation: it injects through HTTP headers, not parameters.
Out-of-band is deliberately not one of the --technique letters for this reason - it is the
--oob switch, so that it can serve the modules too. A module can therefore offer OAST detection
and command execution of its own; shellshock.py does exactly that.
Creating a new module
Assume we want to add a module named new_module, driven by a --new-module switch.
Step 1: Create the module package
Each module is its own package under src/core/modules/:
The __init__.py may be empty. Placing a bare .py file directly in src/core/modules/ is not
enough - the loader imports a module path, so the package must exist.
Step 2: Define the handler
The entry point is a handler function, not main(). Its signature is fixed:
defnew_module_handler(url, http_request_method, filename):
# url : the target URL currently being tested# http_request_method : the HTTP method in use (e.g. 'GET', 'POST')# filename : the session/output file, passed to the shared checks helpers
...
The handler is responsible for the whole lifecycle of its check: detection, reporting the injection
point, and post-exploitation. When it is done it should end the run the same way the core engine
does, rather than returning into the normal detection flow.
Step 3: Register the module
Open src/core/modules/modules_handler.py and add an entry to the MODULES registry. The key is
the CLI switch name, and the value is the import path paired with the handler's name:
load_modules() walks this registry and runs the first module whose switch is set, so no import or
call has to be hand-written into the loader.
Step 4: Add the CLI switch
Open src/core/parse/cmdline.py and add the switch to the modules option group. The dest must match
the MODULES key exactly - that is how the loader tells whether the module was requested:
A module should reuse the shared core building blocks instead of reimplementing them. Rolling your
own request or output-recovery logic means losing session resume, tamper scripts, WAF handling and
the --os-shell modes for free. The pieces most modules need:
Most of these are reached through a single callback your module provides - a
execute_cmd(cmd) -> output function that runs one command on the target and returns its output.
Once that exists, the shared helpers handle enumeration, file access and the shell modes without
the module knowing how any of them work.
Summary
To add a new module to commix:
Create src/core/modules/<name>/ with an __init__.py and <name>.py.
Define <name>_handler(url, http_request_method, filename) as the entry point.
Register it in the MODULES dict in src/core/modules/modules_handler.py.
Add a matching switch to the modules group in src/core/parse/cmdline.py, with dest equal to the
registry key.
Reuse the shared helpers rather than reimplementing requests, file access or the shell modes.
Read shellshock.py
as the worked reference - it covers header-based injection, session resume, OAST detection and
command execution, file access and post-exploitation in the shape described above.
Example use cases for custom modules
Vulnerability classes injecting through something other than a parameter (headers, cookies, protocol fields)
Target-specific fingerprinting before the standard techniques run
CVE-specific checks with their own payload set
Integration with external tools or platforms
Automated post-exploitation routines
By leveraging this extensibility, users can adapt commix to fit specialized workflows or research
requirements.
Contents
User's manual
Usage - Exhaustive breakdown of all options and switches together with examples