ExploitDF is a lightweight, Metasploit-like command-line framework focused on modular offensive tooling (auxiliary modules, scanners — and in future payloads & exploits). This README walks you through installation, basic use, creating new modules step‑by‑step, and debugging — as if I were holding your hand. 🤝
- Quickstart (5-minute setup)
- Issue: Modules Not Appearing in the show Command
- System Requirements & Compatibility
- Concepts & Architecture (what each class means)
- Commands Cheat-Sheet (quick reference — full list)
- Configuration & Options (exact table)
- Adding a New Module — hand‑holding guide
- Example: Build a Port Scanner (explain → code → run)
- Testing & Debugging (common errors & fixes)
- Contributing & Code Style
- Contact
Assumptions: You have Python 3.8+ installed and sudo
privileges (for system install). Use a virtual environment if you prefer.
Commands (copy-paste): a. for windows
# (optional) create virtualenv
py -m venv venv
# (optional) activate virtualenv
venv\Scripts\activate
# install requirements
pip install -r requirements.txt
# run as administrator
py setup.py
# manually set path to environment variable
(edit the system environment variable) -> Environment Variables -> (in System variables clicl 'New') -> add the path(C:/Program Files/ExploitDF)
# run the framework
exploitdf or py exploitDF.py
Note: You can use 'python' or 'python3' also instead of 'py' depends on your system.
b. for linux or macOS
# (optional) create virtualenv
python3 -m venv venv && source venv/bin/activate
# install requirements
pip install -r requirements.txt
# install (system or local)
sudo python3 setup.py # or: python3 setup.py install --user
# run the framework
exploitdf
Expected first-run output (example):
ExploitDF v1.0
Type `help` or `?` for a list of commands.
exploitdf >
Try a tiny smoke test:
exploitdf > show scanners
exploitdf > show auxiliary
You should see lists of installed modules. If you add a module later, run show scanners
again.
If a smoke test fails, or if you run the show command and don't see all of your auxiliary or scanner modules, it likely means some modules failed to load due to errors.
To find the exact problem, follow these steps:
# Enable Debug Mode
exploitdf > debug
# Reload All Modules
exploitdf > reload_all
# Check the Output :- missing package
pip install <package_name>
# Check the Output :- ModuleNotFoundError or SyntaxError
Please [open a new issue] on our GitHub page and include the following details:
1. The name of the module that failed to load.
2. The full error message from the terminal.
3. Your operating system (e.g., Windows 11, Kali Linux).
This version is a bit more formal and includes the Python version, which is also very helpful for users.
## System Requirements & Compatibility
ExploitDF is a cross-platform tool built with Python. It has been fully tested and is supported on the following platforms:
- Windows: Fully supported on Windows 10 and 11.
- Linux: Fully supported on Debian-based distributions (e.g., Kali Linux, Ubuntu).
- macOS: Fully supported on macOS.
A Python 3.8+ installation is required.
Before editing code, understand the pieces. I’ll explain each like we’re stacking building blocks.
What it is: The core behavior every module inherits — option parsing, printing helpers, socket creation, progress printing, threading helpers, and the run()
contract.
Why it exists: So every module doesn’t have to reimplement the same plumbing (options, verbose logging, progress updates).
Key responsibilities:
- Hold
info
,options
,advanced_options
,required_options
. - Provide
set_option()
,get_option()
,show_options()
. - Provide
create_socket()
helper with SSL support. - Provide
run()
interface (abstract) which checks required options before execution.
What it is: A specialization of BaseModule
for single-target or helper modules (e.g., banner grabbers, brute force helpers).
Defaults: Adds RHOSTS
, RPORT
, and flags RHOSTS
as required.
What it is: Further specialization for scanning use-cases: multi-target, thread-heavy workflows.
Adds / changes:
- Higher default
THREADS
. parse_targets()
to convertRHOSTS
strings into lists.scan_target(target)
method to override per scanner.run()
orchestrates parsing targets, threading, and progress updates.
ExploitDF is designed to be extensible — auxiliary modules and scanners are only the first module types. Because the project is open-source, contributors can add:
- Payloads: code that runs on a target after exploitation (requires handlers/listeners and careful sandboxing in tests).
- Exploits: modules that attempt to exploit specific vulnerabilities. These modules usually need extra safety checks, detailed
info
fields (CVE, disclosure date), and conservative defaults.
When adding payloads/exploits, follow the same structure (BaseModule
derivatives) and add clear info
metadata, safe defaults, and comprehensive required_options
checks.
All commands currently available in ExploitDF (copy this into your README or help output):
'?': 'Display help information',
'banner': 'Display the ExploitDF banner',
'cd': 'Change the current working directory',
'connect': 'Communicate with a host',
'debug': 'Toggle debug mode',
'exit': 'Exit the framework',
'features': 'Display the list of enabled features',
'get': 'Gets the value of a context-specific variable',
'getg': 'Gets the value of a global variable',
'grep': 'Grep the output of another command',
'help': 'Display help information',
'history': 'Show command history',
'load': 'Load a framework plugin',
'quit': 'Exit the framework',
'repeat': 'Repeat a list of commands',
'route': 'Route traffic through a session',
'save': 'Save the active datastores',
'sessions': 'Dump session listings and display information',
'set': 'Set a context-specific variable to a value',
'setg': 'Set a global variable to a value',
'sleep': 'Do nothing for the specified number of seconds',
'spool': 'Write console output into a file as well as the screen',
'threads': 'View and manipulate background threads',
'tips': 'Show a list of useful productivity tips',
'unload': 'Unload a framework plugin',
'update': 'Update the framework from the Git repository',
'unset': 'Unset one or more context-specific variables',
'unsetg': 'Unset one or more global variables',
'version': 'Show the framework and console library version numbers',
'clear': 'Clear the console screen',
'notes': 'Manage notes for hosts and modules',
'advanced': 'Display all advanced options',
'back': 'Move back from current context',
'clearm': 'Clear the module stack',
'favorite': 'Add a module to favorites',
'favorites': 'Print the list of favorite modules',
'info': 'Display information about one or more modules',
'listm': 'List all modules in the database',
'loadpath': 'Search for and load modules from a path',
'options': 'Display global options or for one or more modules',
'popm': 'Pop the latest module off of the module stack',
'previous': 'Set the previously loaded module as the current module',
'pushm': 'Push the active or list of modules onto the module stack',
'reload_all': 'Reload all modules from all defined module paths',
'search': 'Search for modules',
'show': 'Display modules of a given type, or all modules',
'use': 'Select a module by name',
'run': 'Launch the currently selected module',
'handler': 'Start a payload handler as a job',
'jobs': 'Display and manage jobs',
'kill': 'Kill a job',
'rename_job': 'Rename a job',
'dns': 'Manage the DNS resolver'
Note:
handler
is already present to support future payloads — when you add payload modules, they will typically require ahandler
to listen for incoming sessions.
This table explains commonly-used options that modules will have. Treat it as a handbook.
Name | Type | Default | Required? | Description | Example |
---|---|---|---|---|---|
RHOSTS | string | `` | yes (usually) | Comma-separated targets or ranges | 192.168.56.101,10.0.0.0/24 |
RPORT | int / range | 80 |
no | Target port or port range | 80 or 1-1024 |
THREADS | int | 1 or 10 for scanners |
no | Number of concurrent worker threads | 20 |
VERBOSE | bool | False |
no | Show verbose logs | true |
WORKSPACE | string | `` | no | Save results into workspace folder | testlab |
ShowProgress | bool | True |
no | Print progress updates | True |
ShowProgressPercent | int | 10 |
no | Percent interval for progress prints | 5 |
ConnectTimeout | int | 10 |
no | Socket timeout in seconds | 5 |
SSL | bool | False |
no | Wrap socket in SSL | True |
How to set options in the console:
exploitdf > use scanners/port_scanner
exploitdf scanners/port_scanner > set RHOSTS 192.168.56.101
exploitdf scanners/port_scanner > set RPORT 22,80,443
exploitdf scanners/port_scanner > set THREADS 10
exploitdf scanners/port_scanner > run
Programmatic usage (from Python): when writing modules you will use self.options
dict and self.get_option('NAME')
/ self.set_option()
.
I’ll walk you through every file and command so a total beginner can add a scanner or auxiliary module.
- AuxiliaryModule for single-target tasks (banner grabbing, exploits helpers, fuzzers)
- ScannerModule for tasks that scan multiple targets concurrently (port scan, vuln scan)
- Payloads/Exploit modules (future) — follow exploit best-practices: safe defaults, thorough
info
metadata (CVE, disclosure_date), and strong validation.
Path: modules/<type>/<my_module>.py
Example: modules/scanners/port_scanner.py
Template (copy & paste, then edit comments):
from basemodule import ScannerModule
class PortScanner(ScannerModule):
def __init__(self):
super().__init__()
self.info.update({
'name': 'Port Scanner',
'description': 'Simple TCP port scanner',
'author': 'Your Name',
'version': '1.0'
})
# Default options and defaults
self.options.update({
'RHOSTS': '',
'RPORT': '1-1024',
'THREADS': 20,
})
# Required options
self.required_options.add('RHOSTS')
def scan_target(self, target):
# This function runs per target — thread-safe
ports = [22, 80, 443] # replace with parsing of RPORT
for p in ports:
sock = self.create_socket(host=target, port=p)
if sock:
self.print_good(f"{target}:{p} is open")
sock.close()
else:
self.vprint(f"{target}:{p} closed or unreachable")
Notes:
- Keep each module small and single-responsibility.
- Use
self.vprint()
for verbose logs. - Protect shared resources. Avoid global mutable state; pass data structures or use locks.
Typically the framework loads modules from modules/
automatically on startup. If not:
- Add an import entry into
modules/__init__.py
or update the module index file. - Run
exploitdf
andshow scanners
to verify your module appears.
exploitdf > use scanners/port_scanner
exploitdf scanners/port_scanner > options
exploitdf scanners/port_scanner > set RHOSTS 127.0.0.1
exploitdf scanners/port_scanner > set THREADS 5
exploitdf scanners/port_scanner > run
Expect to see progress lines and open/closed results.
A port scanner checks if a TCP port on a remote host accepts connections. For each target:port
pair, we will try to open a TCP socket with configured timeout. If connect succeeds, port is open
; otherwise closed
or filtered.
We will use ScannerModule
so we get target parsing and threading for free. scan_target()
will be called for each host. Inside we parse RPORT
and test each port via create_socket(host, port)
.
# modules/scanners/simple_port_scanner.py
from basemodule import ScannerModule
class SimplePortScanner(ScannerModule):
def __init__(self):
super().__init__()
self.info.update({
'name': 'Simple Port Scanner',
'description': 'Threaded TCP port scanner (example)',
'author': 'Your Name',
'version': '1.0'
})
self.options.update({
'RHOSTS': '',
'RPORT': '22,80,443',
'THREADS': 10,
'ConnectTimeout': 3,
})
self.required_options.add('RHOSTS')
def parse_ports(self, ports_str):
# Accept comma separated and ranges like 1-1024
ports = set()
for part in str(ports_str).split(','):
part = part.strip()
if not part:
continue
if '-' in part:
start, end = part.split('-', 1)
ports.update(range(int(start), int(end)+1))
else:
ports.add(int(part))
return sorted(ports)
def scan_target(self, target):
ports = self.parse_ports(self.get_option('RPORT'))
for p in ports:
if not self.running:
break
sock = self.create_socket(host=target, port=p)
if sock:
self.print_good(f"{target}:{p} is open")
try:
sock.close()
except Exception:
pass
else:
self.vprint(f"{target}:{p} closed or unreachable")
exploitdf > use scanners/simple_port_scanner
exploitdf scanners/simple_port_scanner > set RHOSTS 192.168.56.101
exploitdf scanners/simple_port_scanner > set RPORT 22,80,443
exploitdf scanners/simple_port_scanner > set THREADS 10
exploitdf scanners/simple_port_scanner > run
Expected output (example):
[2025-09-22 14:05:21] [*] Scanning 1 targets...
[2025-09-22 14:05:21] [+] 192.168.56.101:22 is open
[2025-09-22 14:05:22] [*] Progress: 1/1 (100%) - Scanning 192.168.56.101
[2025-09-22 14:05:22] [+] Scan completed
-
Connection failed: [Errno 111] Connection refused
- Cause: target closed port or firewall. Fix: Verify target is running, check
RPORT
, increase timeout.
- Cause: target closed port or firewall. Fix: Verify target is running, check
-
Module not found
whenuse scanners/my_module
- Cause: file not in
modules/scanners/
or not imported. Fix: Ensure file saved with correct name and class. Restart framework or add import inmodules/__init__.py
.
- Cause: file not in
-
Missing required options: RHOSTS
- Cause: Forgot to set
RHOSTS
. Fix:set RHOSTS 127.0.0.1
- Cause: Forgot to set
-
PermissionError
duringsetup.py
- Fix: Run with
sudo
or install into--user
or use a virtualenv.
- Fix: Run with
- Run the module with
VERBOSE
enabled:set VERBOSE true
to getvprint()
messages. - Reproduce the module import from Python to debug syntax errors:
python3 -c "from modules.scanners.simple_port_scanner import SimplePortScanner; print('import ok')"
- Add
try/except
around networking code to log exceptions withself.print_error()
.
Add a tests/
folder with basic checks. Example using pytest (skeleton):
# tests/test_simple_port_scanner.py
from modules.scanners.simple_port_scanner import SimplePortScanner
def test_parse_ports():
m = SimplePortScanner()
assert m.parse_ports('22,80,100-102') == [22,80,100,101,102]
Run
pytest -q
- Use
flake8
orblack
for formatting. - Use meaningful
info['name']
,description
, andauthor
fields in modules. - Add unit tests for parsing functions and core logic.
- Submit PRs against
develop
branch, include test coverage for new features.
If you want help with this README or module templates, reach out to: