Link Search Menu Expand Document

The Metasploit Framework provides different mixins you can use to develop a browser exploit, mainly they are Msf::Exploit::Remote::HttpServer, Msf::Exploit::Remote::HttpServer::HTML and Msf::Exploit::Remote::BrowserExploitServer. This writeup covers the HttpServer mixin.

The HttpServer mixin is kind of the mother of all HTTP server mixins (like BrowserExploitServer and HttpServer::HTML). To use it, your module is required to have a “on_request_uri” method, which is a callback triggered when the HTTP server receives a HTTP request from the browser. An example of setting up “on_request_uri”:

#
# Listens for a HTTP request.
# cli is the socket object, and request is a Rex::Proto::Http::Request object
#
def on_request_uri(cli, request)
	print_status("Client requests URI: #{request.uri}")
end

The “on_request_uri” method is also where you can create the HTTP response. Here’s a couple of choices you can use to do that:

  • send_not_found(cli) - Sends a 404 to the client. Make sure to pass the cli (socket) object.
  • send_redirect(cli, location=’/’, body=’’, headers={}) - Redirects the client to a new location.
  • send_response(cli, body, headers={}) - Sends a response to the client. This method is probably what you’ll be using most of the time.

If you’ve seen some of our exploit modules, you will also see them using Exploit::Remote::HttpServer::HTML instead of Exploit::Remote::HttpServer. Usage is mostly the same, the difference is the Exploit::Remote::HttpServer::HTML mixin gives you access to some Javascript functions like Base64, heap spraying, OS detection, etc.

Here’s an example of sending a HTTP response:

#
# Sends a "Hello, world!" to the client
#
def on_request_uri(cli, request)
	html = "Hello, world!"
	send_response(cli, html)
end

Also note that in order to handle a HTTP request, it must contain the base URIPATH, which by default is random. This means if you want to handle multiple URIs (possible if you need to handle a redirect or a link), you also need to make sure they have the base URIPATH. To retrieve the base URIPATH, you can use the “get_resource” method, here’s an example:

def serve_page_1(cli)
	html = "This is page 1"
	send_response(cli, html)
end

def serve_page_2(cli)
	html = "This is page 2"
	send_response(cli, html)
end

def serve_default_page(cli)
	html = %Q|
	<html>
	<a href="#{get_resource.chomp('/')}/page_1.html">Go to page 1</a><br>
	<a href="#{get_resource.chomp('/')}/page_2.html">Go to page 2</a>
	</html>
	|

	send_response(cli, html)
end

def on_request_uri(cli, request)
	case request.uri
	when /page_1\.html$/
		serve_page_1(cli)
	when /page_2\.html$/
		serve_page_2(cli)
	else
		serve_default_page(cli)
	end
end

Of course, when you write a Metasploit browser exploit there’s a lot more you need to think about. For example, your module probably needs to do browser detection, because it wouldn’t make any sense to allow Chrome to receive an IE exploit, would it? You probably also need to build a payload that’s specific to the target, which means your module needs to know what target it’s hitting, and you have to build a method to customize the exploit accordingly, etc. The HttpServer and HttpServer::HTML mixin provides all kinds of methods to allow you to accomplish all these. Make sure to check out the API documentation (you can either do this by running msf/documentation/gendocs.sh, or just run “yard” in the msf directory), or checkout existing code examples (especially the recent ones).

To get things started, you can always use the following template to start developing your browser exploit:

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::Remote::HttpServer

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'HttpServer mixin example',
        'Description' => %q{
          Here's an example of using the HttpServer mixin
        },
        'License' => MSF_LICENSE,
        'Author' => [ 'sinn3r' ],
        'References' => [
          [ 'URL', 'http://metasploit.com' ]
        ],
        'Platform' => 'win',
        'Targets' => [
          [ 'Generic', {} ],
        ],
        'DisclosureDate' => '2013-04-01',
        'DefaultTarget' => 0
      )
    )
  end

  def on_request_uri(cli, _request)
    html = 'hello'
    send_response(cli, html)
  end

end

If you want to take a closer look at what the mixin can do, see: https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/http/server.rb