Skip to content

Commit

Permalink
Land #17795, Add documentation on debugging and running external pyth…
Browse files Browse the repository at this point in the history
…on modules
  • Loading branch information
dwelch-r7 authored Mar 21, 2023
2 parents 2f45c3b + 83cc0bf commit feaddc0
Showing 1 changed file with 94 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,99 @@ if __name__ == '__main__':
```
The example sends a get request to the given `rhost` and `targeturi`, then calls `logging.info()` on the result to have the output displayed in msfconsole.

### Debugging Python modules

If you want to run an external module as a standalone program from your metasploit-framework folder just specify the Python path to include
the Metasploit library support and run the module directly:

```
$ PYTHONPATH=./lib/msf/core/modules/external/python:$PYTHONPATH python3 ./modules/auxiliary/scanner/wproxy/att_open_proxy.py
```

The Python module will wait for stdin to receive JSON-RPC input. Entering the request to run the module:

```jsonl
{ "jsonrpc": "2.0", "id": "1337", "method": "run", "params": { "rhosts": ["127.0.0.1"], "rport": "49152" } }
```

You will see the JSON-RPC responses printed to stdout:

```jsonl
{"jsonrpc": "2.0", "method": "message", "params": {"level": "debug", "message": "127.0.0.1:49152 - Connected"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "debug", "message": "127.0.0.1:49152 - Received 5 bytes"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "127.0.0.1:49152 - Does not match"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "debug", "message": "127.0.0.1:49152 - Does not match with: bytearray(b'xxxxx')"}}
```

You can pipe the JSON-RPC request as well for automation purposes:

```
echo '{ "jsonrpc": "2.0", "id": "1337", "method": "run", "params": { "rhosts": ["127.0.0.1"], "rport": "49152" } }' | PYTHONPATH=./lib/msf/core/modules/external/python:$PYTHONPATH python3 ./modules/auxiliary/scanner/wproxy/att_open_proxy.py
```

The Python external modules can be run directly with command line options:

```
$ PYTHONPATH=./lib/msf/core/modules/external/python:$PYTHONPATH python3.9 ./modules/auxiliary/scanner/wproxy/att_open_proxy.py --help
usage: att_open_proxy.py [-h] --rhosts RHOSTS [--rport RPORT] [ACTION]
The Arris NVG589 and NVG599 routers configured with AT&T U-verse firmware 9.2.2h0d83 expose an un-authenticated proxy that allows connecting from WAN to LAN by MAC address.
positional arguments:
ACTION The action to take (['run'])
optional arguments:
-h, --help show this help message and exit
--rport RPORT The target port, (default: 49152)
required arguments:
--rhosts RHOSTS The target address
```

For example:

```
PYTHONPATH=./lib/msf/core/modules/external/python:$PYTHONPATH python3 ./modules/auxiliary/scanner/wproxy/att_open_proxy.py --rhosts 127.0.0.1 --rport 49152
```

For exploit modules, the payload is encoded encoded using Base64 and specified in a top level `payload_encoded` key, implemented [here](https://github.com/rapid7/metasploit-framework/blob/668735e4185968405c0073465f9aafbf62930538/lib/msf/core/modules/external/templates/remote_exploit.erb#L36-L39).
Below is an example of the ([now deleted](https://github.com/rapid7/metasploit-framework/pull/15217)) [ms17_010_eternalblue_win8.py](https://github.com/rapid7/metasploit-framework/blob/6dd298ebb76a1617e24da5e4c73e43a46b226a23/modules/exploits/windows/smb/ms17_010_eternalblue_win8.py) module running:

```
$ cat options.json
{
"jsonrpc": "2.0",
"id": "1337",
"method": "run",
"params": {
"VERBOSE": true,
"RHOST": "192.168.144.131",
"RPORT": "445",
"GroomAllocations": 13,
"ProcessName": "spoolsv.exe",
"SMBUser": "test",
"SMBPass": "123456",
"payload_encoded": "/EiD5PDozAAA...etc...==="
}
}
$ cat options.json | PYTHONPATH=./lib/msf/core/modules/external/python:$PYTHONPATH python3 modules/exploits/windows/smb/ms17_010_eternalblue_win8.py
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "shellcode size: 1221"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "numGroomConn: 13"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "Target OS: Windows 10 Pro 10240"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "got good NT Trans response"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "got good NT Trans response"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "SMB1 session setup allocate nonpaged pool success"}}
{"jsonrpc": "2.0", "method": "message", "params": {"level": "info", "message": "SMB1 session setup allocate nonpaged pool success"}}
```

To add breakpoints to your Python code, add the below code snippet. Note that the interactive breakpoints will only work when
running the external modules as standalone Python scripts, and won't work when running from msfconsole:

```python
import pdb; pdb.pry
```

## Coding with Style

All the Python code in Metasploit aims to be [PEP 8](https://www.python.org/dev/peps/pep-0008/) compliant. The biggest differences coming from Metasploit's Ruby style:
Expand Down Expand Up @@ -202,4 +295,4 @@ The external modules communicate with framework via JSON-RPC. If your Python mod

[Metasploit Python library](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/modules/external/python/)

[ERB Templates](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/modules/external/templates)
[ERB Templates](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/modules/external/templates)

0 comments on commit feaddc0

Please sign in to comment.