mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-29 18:07:27 +01:00
Use a keyed cookie. Moves AJAX call to a form post.
This commit is contained in:
parent
21cdaa4f39
commit
e8226f9d40
@ -7,4 +7,28 @@ function postInfo(path, data) {
|
|||||||
|
|
||||||
xmlHttp.open('POST', path, false);
|
xmlHttp.open('POST', path, false);
|
||||||
xmlHttp.send(data);
|
xmlHttp.send(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function postForm(path, data) {
|
||||||
|
var set = function(obj, attr, val) {
|
||||||
|
if (obj.setAttribute) { obj.setAttribute(attr, val); }
|
||||||
|
else { obj[attr] = val; }
|
||||||
|
}
|
||||||
|
|
||||||
|
var form = document.createElement('form');
|
||||||
|
set(form, 'method', 'POST');
|
||||||
|
set(form, 'action', path);
|
||||||
|
|
||||||
|
var input;
|
||||||
|
for (var i in data) {
|
||||||
|
input = document.createElement('input')
|
||||||
|
set(input, 'type', 'hidden');
|
||||||
|
set(input, 'name', i);
|
||||||
|
set(input, 'value', data[i]);
|
||||||
|
form.appendChild(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
form.style.display = 'none';
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
require 'erb'
|
require 'erb'
|
||||||
|
require 'cgi'
|
||||||
require 'rex/exploitation/js'
|
require 'rex/exploitation/js'
|
||||||
|
|
||||||
###
|
###
|
||||||
@ -16,6 +17,9 @@ module Msf
|
|||||||
include Msf::Exploit::Remote::HttpServer::HTML
|
include Msf::Exploit::Remote::HttpServer::HTML
|
||||||
include Msf::Exploit::RopDb
|
include Msf::Exploit::RopDb
|
||||||
|
|
||||||
|
# this must be static between runs, otherwise the older cookies will be ignored
|
||||||
|
DEFAULT_COOKIE_NAME = '__ua'
|
||||||
|
|
||||||
PROXY_REQUEST_HEADER_SET = Set.new(
|
PROXY_REQUEST_HEADER_SET = Set.new(
|
||||||
%w{
|
%w{
|
||||||
CLIENT_IP
|
CLIENT_IP
|
||||||
@ -72,10 +76,14 @@ module Msf
|
|||||||
[
|
[
|
||||||
OptBool.new('Retries', [false, "Allow the browser to retry the module", true])
|
OptBool.new('Retries', [false, "Allow the browser to retry the module", true])
|
||||||
], Exploit::Remote::BrowserExploitServer)
|
], Exploit::Remote::BrowserExploitServer)
|
||||||
|
|
||||||
|
register_advanced_options([
|
||||||
|
OptString.new('CookieName', [false, "The name of the tracking cookie", DEFAULT_COOKIE_NAME])
|
||||||
|
], Exploit::Remote::BrowserExploitServer)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Syncs a block of code
|
# Allows a block of code to access BES resources in a thread-safe fashion
|
||||||
#
|
#
|
||||||
# @param block [Proc] Block of code to sync
|
# @param block [Proc] Block of code to sync
|
||||||
#
|
#
|
||||||
@ -191,7 +199,7 @@ module Msf
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Returns the target profile based on the tag. Each profile has the following structure:
|
# Returns the target profile based on the tag. Each profile has the following structure:
|
||||||
# 'cookie' =>
|
# 'cookie_name' =>
|
||||||
# {
|
# {
|
||||||
# :os_name => 'Windows',
|
# :os_name => 'Windows',
|
||||||
# :os_flavor => 'something'
|
# :os_flavor => 'something'
|
||||||
@ -238,13 +246,13 @@ module Msf
|
|||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Initializes a profile
|
# Initializes a profile, if it did not previously exist
|
||||||
#
|
#
|
||||||
# @param tag [String] A unique string as a way to ID the profile
|
# @param tag [String] A unique string as a way to ID the profile
|
||||||
#
|
#
|
||||||
def init_profile(tag)
|
def init_profile(tag)
|
||||||
sync do
|
sync do
|
||||||
@target_profiles[tag] = {}
|
@target_profiles[tag] ||= {}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -257,14 +265,18 @@ module Msf
|
|||||||
# @param request [Rex::Proto::Http::Request] The HTTP request sent by the browser
|
# @param request [Rex::Proto::Http::Request] The HTTP request sent by the browser
|
||||||
#
|
#
|
||||||
def retrieve_tag(request)
|
def retrieve_tag(request)
|
||||||
tag = request.headers['Cookie'].to_s
|
cookie = CGI::Cookie.parse(request.headers['Cookie'].to_s)
|
||||||
|
tag = cookie.has_key?(cookie_name) && cookie[cookie_name].first
|
||||||
|
|
||||||
if tag.blank?
|
if tag.blank?
|
||||||
# Browser probably doesn't allow cookies, plan B :-/
|
# Browser probably doesn't allow cookies, plan B :-/
|
||||||
|
vprint_status("No cookie received, resorting to headers hash.")
|
||||||
ip = cli.peerhost
|
ip = cli.peerhost
|
||||||
os = request.headers['User-Agent']
|
os = request.headers['User-Agent']
|
||||||
tag = Rex::Text.md5("#{ip}#{os}")
|
tag = Rex::Text.md5("#{ip}#{os}")
|
||||||
end
|
else
|
||||||
|
vprint_status("Received cookie '#{tag}'.")
|
||||||
|
end
|
||||||
|
|
||||||
tag
|
tag
|
||||||
end
|
end
|
||||||
@ -278,22 +290,20 @@ module Msf
|
|||||||
#
|
#
|
||||||
def process_browser_info(source, cli, request)
|
def process_browser_info(source, cli, request)
|
||||||
tag = retrieve_tag(request)
|
tag = retrieve_tag(request)
|
||||||
|
|
||||||
# Browser doesn't allow cookies. Can't track that, use a different way to track.
|
|
||||||
init_profile(tag) if request.headers['Cookie'].blank?
|
|
||||||
target_info = get_profile(tag)
|
target_info = get_profile(tag)
|
||||||
|
init_profile(tag)
|
||||||
|
|
||||||
# Gathering target info from the detection stage
|
# Gathering target info from the detection stage
|
||||||
case source
|
case source
|
||||||
when :script
|
when :script
|
||||||
# Gathers target data from a POST request
|
# Gathers target data from a POST request
|
||||||
update_profile(target_info, :source, 'script')
|
update_profile(target_info, :source, 'script')
|
||||||
raw = Rex::Text.uri_decode(Rex::Text.decode_base64(request.body))
|
parsed_body = CGI::parse(request.body || '')
|
||||||
raw.split('&').each do |item|
|
|
||||||
k, v = item.scan(/(\w+)=(.*)/).flatten
|
|
||||||
update_profile(target_info, k.to_sym, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
# CGI::parse returns a single-value array for every value,
|
||||||
|
# let's just collaps that to the value itself
|
||||||
|
vprint_status("Received sniffed browser data over POST: \n#{parsed_body}.")
|
||||||
|
parsed_body.each { |k, v| update_profile(target_info, k.to_sym, v.first) }
|
||||||
when :headers
|
when :headers
|
||||||
# Gathers target data from headers
|
# Gathers target data from headers
|
||||||
# This may be less accurate, and most likely less info.
|
# This may be less accurate, and most likely less info.
|
||||||
@ -379,9 +389,7 @@ module Msf
|
|||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
var query = objToQuery(d);
|
postForm("<%=get_resource.chomp("/")%>/<%=@info_receiver_page%>/", d);
|
||||||
postInfo("<%=get_resource.chomp("/")%>/<%=@info_receiver_page%>/", query);
|
|
||||||
window.location = "<%=get_resource.chomp("/")%>/<%=@exploit_receiver_page%>/";
|
|
||||||
}
|
}
|
||||||
|).result(binding())
|
|).result(binding())
|
||||||
|
|
||||||
@ -399,6 +407,11 @@ module Msf
|
|||||||
|
|
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [String] name of the tracking cookie
|
||||||
|
def cookie_name
|
||||||
|
datastore['CookieName'] || DEFAULT_COOKIE_NAME
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Handles exploit stages.
|
# Handles exploit stages.
|
||||||
#
|
#
|
||||||
@ -421,14 +434,14 @@ module Msf
|
|||||||
ua = request.headers['User-Agent']
|
ua = request.headers['User-Agent']
|
||||||
init_profile(tag)
|
init_profile(tag)
|
||||||
html = get_detection_html(ua)
|
html = get_detection_html(ua)
|
||||||
send_response(cli, html, {'Set-Cookie' => tag})
|
send_response(cli, html, {'Set-Cookie' => "#{cookie_name}=#{tag}"})
|
||||||
|
|
||||||
when /#{@info_receiver_page}/
|
when /#{@info_receiver_page}/
|
||||||
#
|
#
|
||||||
# The detection code will hit this if Javascript is enabled
|
# The detection code will hit this if Javascript is enabled
|
||||||
#
|
#
|
||||||
process_browser_info(source=:script, cli, request)
|
process_browser_info(source=:script, cli, request)
|
||||||
send_response(cli, '')
|
send_redirect(cli, "#{get_resource.chomp("/")}/#{@exploit_receiver_page}")
|
||||||
|
|
||||||
when /#{@noscript_receiver_page}/
|
when /#{@noscript_receiver_page}/
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user