Generate a Metasploit payload using the RPC API (payload.generate). Saves the generated payload to a file on the server if successful. Args: payload_type: Type of payload (e.g., windows/meterpreter/reverse_tcp). format_type: Output format (raw, exe, python, etc.).
(
payload_type: str,
format_type: str,
options: Union[Dict[str, Any], str], # Required: e.g., {"LHOST": "1.2.3.4", "LPORT": 4444} or "LHOST=1.2.3.4,LPORT=4444"
encoder: Optional[str] = None,
iterations: int = 0,
bad_chars: str = "",
nop_sled_size: int = 0,
template_path: Optional[str] = None,
keep_template: bool = False,
force_encode: bool = False,
output_filename: Optional[str] = None,
)
| 828 | |
| 829 | @mcp.tool() |
| 830 | async def generate_payload( |
| 831 | payload_type: str, |
| 832 | format_type: str, |
| 833 | options: Union[Dict[str, Any], str], # Required: e.g., {"LHOST": "1.2.3.4", "LPORT": 4444} or "LHOST=1.2.3.4,LPORT=4444" |
| 834 | encoder: Optional[str] = None, |
| 835 | iterations: int = 0, |
| 836 | bad_chars: str = "", |
| 837 | nop_sled_size: int = 0, |
| 838 | template_path: Optional[str] = None, |
| 839 | keep_template: bool = False, |
| 840 | force_encode: bool = False, |
| 841 | output_filename: Optional[str] = None, |
| 842 | ) -> Dict[str, Any]: |
| 843 | """ |
| 844 | Generate a Metasploit payload using the RPC API (payload.generate). |
| 845 | Saves the generated payload to a file on the server if successful. |
| 846 | |
| 847 | Args: |
| 848 | payload_type: Type of payload (e.g., windows/meterpreter/reverse_tcp). |
| 849 | format_type: Output format (raw, exe, python, etc.). |
| 850 | options: Dictionary of required payload options (e.g., {"LHOST": "1.2.3.4", "LPORT": 4444}) |
| 851 | or string format "LHOST=1.2.3.4,LPORT=4444". Prefer dict format. |
| 852 | encoder: Optional encoder to use. |
| 853 | iterations: Optional number of encoding iterations. |
| 854 | bad_chars: Optional string of bad characters to avoid (e.g., '\\x00\\x0a\\x0d'). |
| 855 | nop_sled_size: Optional size of NOP sled. |
| 856 | template_path: Optional path to an executable template. |
| 857 | keep_template: Keep the template working (requires template_path). |
| 858 | force_encode: Force encoding even if not needed by bad chars. |
| 859 | output_filename: Optional desired filename (without path). If None, a default name is generated. |
| 860 | |
| 861 | Returns: |
| 862 | Dictionary containing status, message, payload size/info, and server-side save path. |
| 863 | """ |
| 864 | client = get_msf_client() |
| 865 | logger.info(f"Generating payload '{payload_type}' (Format: {format_type}) via RPC. Options: {options}") |
| 866 | |
| 867 | # Parse options gracefully |
| 868 | try: |
| 869 | parsed_options = _parse_options_gracefully(options) |
| 870 | except ValueError as e: |
| 871 | return {"status": "error", "message": f"Invalid options format: {e}"} |
| 872 | |
| 873 | if not parsed_options: |
| 874 | return {"status": "error", "message": "Payload 'options' dictionary (e.g., LHOST, LPORT) is required."} |
| 875 | |
| 876 | try: |
| 877 | # Get the payload module object |
| 878 | payload = await _get_module_object('payload', payload_type) |
| 879 | |
| 880 | # Set payload-specific required options (like LHOST/LPORT) |
| 881 | await _set_module_options(payload, parsed_options) |
| 882 | |
| 883 | # Set payload generation options in payload.runoptions |
| 884 | # as per the pymetasploit3 documentation |
| 885 | logger.info("Setting payload generation options in payload.runoptions...") |
| 886 | |
| 887 | # Define a function to update an individual runoption |