Skip to content

How to send an HTTP request using Rex::Proto::Http::Client

wchen-r7 edited this page Oct 11, 2014 · 24 revisions

The Rex library (Ruby Extension Library) is the most fundamental piece of the Metasploit Framework architecture. Modules normally do not interact with Rex directly, instead they depend on the framework core and its mixins for better code sharing. If you are a Metasploit module developer, the lib/msf/core directory should be more than enough for most of your needs. If you are writing a module that speaks HTTP, then the Msf::Exploit::Remote::HttpClient mixin (which is found in lib/msf/core/exploit/http/client) is most likely the one you want.

However, in some scenarios, you actually can't use the HttpClient mixin. The most common is actually when writing a form-based login module using the LoginScanner API. If you find yourself in that situation, use Rex::Proto::Http::Client.

Initializing Rex::Proto::Http::Client

Making an HTTP request

Even though our main topic of this documentation is about Rex::Proto::Http::Client, it does not know how to make HTTP requests. Instead, Rex::Proto::Http::ClientRequest is actually the mother of all Metasploit's HTTP requests.

So how does Rex::Proto::Http::ClientRequest give birth to an HTTP request? Well, you see son, it all begins when Rex::Proto::Http::Client asks for one with either the #request_cgi or the #request_raw method. The difference is that if #request_cgi is used, the request is meant to be CGI compatible. If #request_raw is used, then the request is likely used to violate the HTTP specification. In most cases, you want #request_cgi.

Sending an HTTP request

Here are examples of how to actually speak to an HTTP server with either #request_cgi or #request_raw:

#request_cgi

cli = Rex::Proto::Http::Client.new(rhost),
cli.connect
req = cli.request_cgi({
	'uri'      =>'/test.php',
	'vars_get' => {
		'param1' => 'value',
		'param2' => 'value'
	},
	'vars_post' => {
		'username' => 'user',
		'password' => 'pass'
	}
})
res = cli.send_recv(req)
cli.close

#request_raw

cli = Rex::Proto::Http::Client.new(rhost),
cli.connect
req = cli.request_raw({'uri'=>'/'})
res = cli.send_recv(req)
cli.close

Configuring advanced options

URI Parsing

Full Example

Metasploit Wiki Pages


Clone this wiki locally