-
-
Notifications
You must be signed in to change notification settings - Fork 263
Introduction to writing payloads
Exploit modules support (and require) the use of payloads to function. A payload, in WPXF, is simply the arbitrary PHP code that we intend to run on the target system via the vulnerability that the module exploits.
The naming scheme for payloads is the same as the Module Naming Scheme, except they always appear in the Wpxf::Payloads
namespace.
The below example illustrates how to register an option and use it when generating the payload.
module Wpxf::Payloads
class YourPayload < Wpxf::Payload
include Wpxf
include Wpxf::Options
def initialize
super
register_options([
StringOption.new(
name: 'greeting',
desc: 'A greeting to display',
required: true,
default: 'Hello, world!',
)
])
end
def greeting
escape_single_quotes(datastore['greeting'])
end
def raw
"echo '#{greeting}';"
end
end
end
When this payload is generated in WPXF, assuming encoding is disabled, the final PHP script would look like this (assuming the user didn't change the greeting option):
<?php echo 'Hello, world!'; ?>
In most (if not all) of the existing payloads, the majority of variable names are generated randomly at runtime in order to make fingerprinting the payload more difficult. A helper method, generate_vars
exists to aid in doing this, by accepting an array of keys and generating a random and unique variable name for each one and returning them in a hash.
If you want to contribute a payload to the project, it's encouraged you use this technique. An example can be seen below of how to do this:
module Wpxf::Payloads
class YourPayload < Wpxf::Payload
include Wpxf
include Wpxf::Options
def initialize
super
register_options([
StringOption.new(
name: 'greeting',
desc: 'A greeting to display',
required: true,
default: 'Hello, world!',
)
])
end
def greeting
escape_single_quotes(datastore['greeting'])
end
def raw
vars = generate_vars([:greeting])
<<-END_OF_PHP_CODE
$#{vars[:greeting]} = '#{greeting}'
echo $#{vars[:greeting]};"
END_OF_PHP_CODE
end
end
end
In some cases, it may be a good idea to run checks when the user loads the payload to make sure that there are no conflicts or to simply provide information to the user about the payload. An example of this can be found in the bind_php payload:
def check(mod)
if mod.get_option('proxy')
mod.emit_warning 'The proxy option for this module is only used for '\
'HTTP connections and will NOT be used for the TCP '\
'connection that the payload establishes'
end
end
As the TCP connection that is made via the payload does not go through the proxy set in the proxy option, we raise a warning to the user if there is a proxy option present in the module that the payload has been loaded into.
In some scenarios, some preparation will be required to be taken before we execute the payload; such as starting a TCP server in the reverse_tcp payload.
To implement pre-exploit actions, override the prepare
method in your payload and return true
if the preparation was successful. This will be executed prior to Module#run
being invoked.
By the same token, there may be resources associated with the payload that need to be cleaned up once we have finished running the module. To achieve this, override the post_exploit
method and again return true
if the cleanup was successful.