-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Writing External Metasploit Modules
For an introduction to the reasons and goals for external modules, see our 2017 HaXmas post on the subject.
Each time Metasploit wants an external module to do something (ex. describe itself or run with a certain configuration), it runs the module in a new process and talks to it over stdin/stdout.
To get the metadata from a module (which includes options), the call sequence looks a bit like:
+------------+
| Metasploit |
| | Describe yourself +-------------------+
| +-------------------> | some_module.py |
| | | |
| | | |
| | Some metadata | |
| | <-------------------+ |
| | | |
| | +-------------------+
| |
| |
+------------+
A module run might look like:
+------------+
| Metasploit | Do a thing with
| | these options +-------------------+
| +-------------------> | some_module.py |
| | | |
| | | |
| | A bit of status | |
| | <-------------------+ |
| | | |
| | Moar status | |
| | <-------------------+ |
| | | |
| | I found a thing | |
| | <-------------------+ |
| | | |
| | +-------------------+
| |
+------------+
When a module meant for a single host is run against a range of hosts, Metasploit will start a new process for each host. If the THREADS
datastore option is set and it is an auxiliary module, that many processes will be run at the same time.
External modules communicate with Metasploit over stdin/stdout. The methods a module must implement are describe
and run
; additional methods can be advertised in the capabilities
array, for now assumed to use a subset of the options used for run
. Metasploit implements message
and will implement report
in the near future. The specs for each method are written below using JSON-schema. Work still needs to be done enumerating valid types and codes for the messages.
Request
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"required": ["params", "method", "jsonrpc", "id"],
"properties": {
"jsonrpc": {"enum": ["2.0"]},
"id": {"type": "string"},
"method": {"enum": ["describe"]},
"params": {"type": "object"}
}
}
Response
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"required": ["jsonrpc", "result", "id"],
"properties": {
"jsonrpc": {"enum": ["2.0"]},
"id": {"type": "string"},
"result": {
"type": "object",
"required": ["name", "description", "authors", "type", "options", "capabilities"],
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"authors": {"type": "array", "items": {"type": "string"}},
"date": {"type": "string"},
"references": {
"type": "array",
"items": {
"type": "object",
"required": ["type", "ref"],
"properties": {
"type": {"type": "string"},
"ref": {"type": "string"}
}
}
},
"type": {"enum": ["remote_exploit.cmd_stager.wget"]},
"privileged": {"type": "boolean"},
"targets": {
"type": "array",
"items": {
"type": "object",
"required": ["platform", "arch"],
"properties": {
"platform": {"type": "string"},
"arch": {"type": "string"}
}
}
},
"options": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^=]*$": {
"type": "object",
"required": ["type", "description", "required", "default"],
"properties": {
"required": {"type": "boolean"},
"default": {"type": ["null", "string", "number", "boolean", "object", "array"]},
"description": {"type": "string"},
"type": {"type": "string"}
}
}
}
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
Request
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"required": ["params", "method", "jsonrpc", "id"],
"properties": {
"jsonrpc": {"enum": ["2.0"]},
"id": {"type": "string"},
"method": {"enum": ["run"]},
"params": {
"type": "object"
"additionalProperties": false,
"patternProperties": {
"^[^=]*$": {
"type": "object",
"required": ["type", "description", "required", "default"],
"properties": {
"required": {"type": "boolean"},
"default": {"type": ["null", "string", "number", "boolean", "object", "array"]},
"description": {"type": "string"},
"type": {"type": "string"}
}
}
}
}
}
}
Response
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"required": ["jsonrpc", "id"],
"properties": {
"jsonrpc": {"enum": ["2.0"]},
"id": {"type": "string"},
"result": {
"type": "object",
"required": ["message"]
"properties": {
"message": {"type": "string"},
"return": {"type": "string"}
}
},
"error": {
"type": "object",
"required": ["message", "code"],
"properties": {
"message": {"type": "string"},
"code": {"type": "number"},
"data": {"type": "object"}
}
}
}
}
Notification - no response
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"required": ["params", "method", "jsonrpc"],
"properties": {
"jsonrpc": {"enum": ["2.0"]},
"method": {"enum": ["message"]},
"params": {
"type": "object",
"required": ["level", "message"],
"properties": {
"level": {"enum": ["error", "good", "warning", "info", "debug"]},
"message": {"type": "string"}
}
}
}
}
- Home Welcome to Metasploit!
- Using Metasploit A collection of useful links for penetration testers.
-
Setting Up a Metasploit Development Environment From
apt-get install
togit push
. - CONTRIBUTING.md What should your contributions look like?
- Landing Pull Requests Working with other people's contributions.
- Using Git All about Git and GitHub.
- Contributing to Metasploit Be a part of our open source community.
- Meterpreter All about the Meterpreter payload.