Move HttpServer::HTML into its own file

bug/bundler_fix
James Lee 2015-01-30 15:24:15 -06:00
parent 3572ce9a37
commit 062529ce3b
No known key found for this signature in database
GPG Key ID: 2D6094C7CEA0A321
3 changed files with 256 additions and 250 deletions

View File

@ -14,6 +14,8 @@ module Msf
#
###
module Exploit::Remote::HttpServer
require 'msf/core/exploit/http/server/html'
require 'msf/core/exploit/http/server/php_include'
include Msf::Exploit::Remote::TcpServer
include Msf::Auxiliary::Report
@ -699,255 +701,5 @@ module Exploit::Remote::HttpServer
# allow this module to be patched at initialization-time
Metasploit::Concern.run(self)
end
###
#
# This module provides methods for exploiting an HTTP client by acting
# as an HTTP server.
#
###
module Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::HttpServer
UTF_NONE = 'none'
UTF_7 = 'utf-7'
UTF_7_ALL = 'utf-7-all'
UTF_8 = 'utf-8'
UTF_16_LE = 'utf-16le'
UTF_16_BE = 'utf-16be'
UTF_16_BE_MARKER = 'utf-16be-marker'
UTF_32_LE = 'utf-32le'
UTF_32_BE = 'utf-32be'
protected
def initialize(info = {})
super
register_evasion_options(
[
# utf-8, utf-7 and utf-7-all are currently not supported by
# most browsers. as such, they are not added by default. The
# mixin supports encoding using them, however they are not
# listed in the Option.
OptEnum.new('HTML::unicode', [false, 'Enable HTTP obfuscation via unicode', UTF_NONE, [UTF_NONE, UTF_16_LE, UTF_16_BE, UTF_16_BE_MARKER, UTF_32_LE, UTF_32_BE]]),
OptEnum.new('HTML::base64', [false, 'Enable HTML obfuscation via an embeded base64 html object (IE not supported)', 'none', ['none', 'plain', 'single_pad', 'double_pad', 'random_space_injection']]),
OptInt.new('HTML::javascript::escape', [false, 'Enable HTML obfuscation via HTML escaping (number of iterations)', 0]),
], Exploit::Remote::HttpServer::HTML)
end
#
# Obfuscates symbols found within a javascript string.
#
# Returns an ObfuscateJS object
#
def obfuscate_js(javascript, opts)
js = Rex::Exploitation::ObfuscateJS.new(javascript, opts)
js.obfuscate
return js
end
#
# Encrypts a given javascript string using the provided key.
#
# Returns a string containing the encrypted string and a loader
#
def encrypt_js(javascript, key)
Rex::Exploitation::EncryptJS.encrypt(javascript, key)
end
#
# Returns the heaplib javascript, including any custom javascript supplied
# by the caller.
#
def heaplib(custom_js = '', opts = {})
Rex::Exploitation::HeapLib.new(custom_js, opts).to_s
end
#
# Returns the heaplib2 javascript
#
def js_heaplib2(custom_js = '', opts = {})
@cache_heaplib2 ||= Rex::Exploitation::Js::Memory.heaplib2(custom_js, opts={})
end
def js_base64
@cache_base64 ||= Rex::Exploitation::Js::Utils.base64
end
#
# Downloads data using ajax
#
# Supported arguments:
# method => Optional. HTTP Verb (eg. GET/POST)
# path => Relative path to the file. In IE, you can actually use an URI. But in Firefox, you
# must use a relative path, otherwise you will be blocked by the browser.
# data => Optional. Data to pass to the server
#
# Example of using the ajax_download() function:
# For IE, your web server has to return this header to download binary data:
# "text/plain; charset=x-user-defined"
# <script>
# #{js_ajax_download}
#
# ajax_download({path:"/test.bin"});
# </script>
#
def js_ajax_download
@cache_ajax_download ||= Rex::Exploitation::Js::Network.ajax_download
end
#
# Transfers data using a POST request
#
def js_ajax_post
@cache_ajax_post ||= Rex::Exploitation::Js::Network.ajax_post
end
#
# This function takes advantage of MSTIME's CTIMEAnimationBase::put_values function that's
# suitable for a no-spray technique. There should be an allocation that contains an array of
# pointers to strings that we control, and each string should reside in its own buffer.
# Please note newer IEs (such as IE9), no longer support SMIL, therefore this only works on
# Internet Explorer 8 or prior. Note that "mstime_malloc" also requires a rather specific
# writing style, so make sure you have the following before using:
# * You must have the following at the beginning of your HTML file:
# <!doctype html>
# <HTML XMLNS:t ="urn:schemas-microsoft-com:time">
# * You must have the following in <meta>:
# <meta>
# <?IMPORT namespace="t" implementation="#default#time2">
# </meta>
#
# The "mstime_malloc" JavaScript function supports the following arguments:
# shellcode => The shellcode to place.
# offset => Optional. The pointer index that points to the shellcode.
# heapBlockSize => Object size.
# objId => The ID to your ANIMATECOLOR element.
#
# Example of using "js_mstime_malloc":
# <script>
# #{js_mstime_malloc}
#
# shellcode = unescape("%u4141%u4141%u4141%u4141%u4141");
# offset = 3;
# s = 0x58;
# mstime_malloc({shellcode:shellcode,offset:offset,heapBlockSize:s,objId:oId});
# </script>
#
def js_mstime_malloc
@cache_mstime_malloc ||= Rex::Exploitation::Js::Memory.mstime_malloc
end
#
# This heap spray technique takes advantage of MSHTML's SetStringProperty (or SetProperty)
# function to trigger allocations by ntdll!RtlAllocateHeap. It is based on Corelan's
# publication on "DEPS Precise Heap Spray on Firefox and IE10". In IE, the shellcode
# should land at address 0x0c0d2020, as this is the most consistent location across
# various versions.
#
# The "sprayHeap" JavaScript function supports the following arguments:
# shellcode => The shellcode to spray in JavaScript. Note: Avoid null bytes.
# objId => Optional. The ID for a <div> HTML tag.
# offset => Optional. Number of bytes to align the shellcode, default: 0x00
# heapBlockSize => Optional. Allocation size, default: 0x80000
# maxAllocs => Optional. Number of allocation calls, default: 0x350
#
# Example of using the 'sprayHeap' function:
# <script>
# #{js_property_spray}
#
# var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444");
# sprayHeap({shellcode:s, heapBlockSize:0x80000});
# </script>
#
def js_property_spray
@cache_property_spray ||= Rex::Exploitation::Js::Memory.property_spray
end
def js_heap_spray
@cache_heap_spray ||= Rex::Exploitation::Js::Memory.heap_spray
end
def js_explib2
@explib2 ||= ::Rex::Exploitation::Js::Memory.explib2
end
def js_explib2_payload(payload="exec")
@explib2_payload ||= ::Rex::Exploitation::Js::Memory.explib2_payload(payload)
end
def js_os_detect
@cache_os_detect ||= ::Rex::Exploitation::Js::Detect.os
end
def js_ie_addons_detect
@cache_ie_addons_detect ||= ::Rex::Exploitation::Js::Detect.ie_addons
end
def js_misc_addons_detect
@cache_misc_addons_detect ||= ::Rex::Exploitation::Js::Detect.misc_addons
end
# Transmits a html response to the supplied client
#
# HTML evasions are implemented here.
def send_response_html(cli, body, headers = {})
body = body.to_s.unpack("C*").pack("C*")
if datastore['HTML::base64'] != 'none'
case datastore['HTML::base64']
when 'plain'
body = Rex::Text.encode_base64(body)
when 'single_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'double_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'random_space_injection'
body = Rex::Text.encode_base64(body)
new = ''
while (body.size > 0)
new << body.slice!(0, rand(3) + 1) + Rex::Text.rand_text(rand(5) + 1, '', " \n")
end
body = new
end
body = '<HTML><BODY><OBJECT ID="' + Rex::Text.rand_text_alpha(rand(10)+5) + '" ' +
'HEIGHT="100%" WIDTH="100%" TYPE="text/html" DATA="data:text/html;base64,' +
body + '">Could not render object</OBJECT></BODY></HTML>'
end
if datastore['HTML::javascript::escape'] > 0
datastore['HTML::javascript::escape'].times {
body = '<script>document.write(unescape("' + Rex::Text.to_hex(body, '%') + '"))</script>'
}
end
if [UTF_16_LE, UTF_16_BE, UTF_32_LE, UTF_32_BE, UTF_7, UTF_8].include?(datastore['HTML::unicode'])
headers['Content-Type'] = 'text/html; charset= ' + datastore['HTML::unicode']
body = Rex::Text.to_unicode(body, datastore['HTML::unicode'])
else
# special cases
case datastore['HTML::unicode']
when UTF_16_BE_MARKER
headers['Content-Type'] = 'text/html'
body = "\xFE\xFF" + Rex::Text.to_unicode(body, UTF_16_BE)
when UTF_7_ALL
headers['Content-Type'] = "text/html; charset=#{UTF_7}"
body = Rex::Text.to_unicode(body, UTF_7, 'all')
when UTF_NONE
# do nothing
else
raise RuntimeError, 'Invalid unicode. how did you get here?'
end
end
send_response(cli, body, headers)
end
end
end

View File

@ -0,0 +1,254 @@
module Msf
###
#
# This module provides methods for exploiting an HTTP client by acting
# as an HTTP server.
#
###
module Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::HttpServer
UTF_NONE = 'none'
UTF_7 = 'utf-7'
UTF_7_ALL = 'utf-7-all'
UTF_8 = 'utf-8'
UTF_16_LE = 'utf-16le'
UTF_16_BE = 'utf-16be'
UTF_16_BE_MARKER = 'utf-16be-marker'
UTF_32_LE = 'utf-32le'
UTF_32_BE = 'utf-32be'
protected
def initialize(info = {})
super
register_evasion_options(
[
# utf-8, utf-7 and utf-7-all are currently not supported by
# most browsers. as such, they are not added by default. The
# mixin supports encoding using them, however they are not
# listed in the Option.
OptEnum.new('HTML::unicode', [false, 'Enable HTTP obfuscation via unicode', UTF_NONE, [UTF_NONE, UTF_16_LE, UTF_16_BE, UTF_16_BE_MARKER, UTF_32_LE, UTF_32_BE]]),
OptEnum.new('HTML::base64', [false, 'Enable HTML obfuscation via an embeded base64 html object (IE not supported)', 'none', ['none', 'plain', 'single_pad', 'double_pad', 'random_space_injection']]),
OptInt.new('HTML::javascript::escape', [false, 'Enable HTML obfuscation via HTML escaping (number of iterations)', 0]),
], Exploit::Remote::HttpServer::HTML)
end
#
# Obfuscates symbols found within a javascript string.
#
# Returns an ObfuscateJS object
#
def obfuscate_js(javascript, opts)
js = Rex::Exploitation::ObfuscateJS.new(javascript, opts)
js.obfuscate
return js
end
#
# Encrypts a given javascript string using the provided key.
#
# Returns a string containing the encrypted string and a loader
#
def encrypt_js(javascript, key)
Rex::Exploitation::EncryptJS.encrypt(javascript, key)
end
#
# Returns the heaplib javascript, including any custom javascript supplied
# by the caller.
#
def heaplib(custom_js = '', opts = {})
Rex::Exploitation::HeapLib.new(custom_js, opts).to_s
end
#
# Returns the heaplib2 javascript
#
def js_heaplib2(custom_js = '', opts = {})
@cache_heaplib2 ||= Rex::Exploitation::Js::Memory.heaplib2(custom_js, opts={})
end
def js_base64
@cache_base64 ||= Rex::Exploitation::Js::Utils.base64
end
#
# Downloads data using ajax
#
# Supported arguments:
# method => Optional. HTTP Verb (eg. GET/POST)
# path => Relative path to the file. In IE, you can actually use an URI. But in Firefox, you
# must use a relative path, otherwise you will be blocked by the browser.
# data => Optional. Data to pass to the server
#
# Example of using the ajax_download() function:
# For IE, your web server has to return this header to download binary data:
# "text/plain; charset=x-user-defined"
# <script>
# #{js_ajax_download}
#
# ajax_download({path:"/test.bin"});
# </script>
#
def js_ajax_download
@cache_ajax_download ||= Rex::Exploitation::Js::Network.ajax_download
end
#
# Transfers data using a POST request
#
def js_ajax_post
@cache_ajax_post ||= Rex::Exploitation::Js::Network.ajax_post
end
#
# This function takes advantage of MSTIME's CTIMEAnimationBase::put_values function that's
# suitable for a no-spray technique. There should be an allocation that contains an array of
# pointers to strings that we control, and each string should reside in its own buffer.
# Please note newer IEs (such as IE9), no longer support SMIL, therefore this only works on
# Internet Explorer 8 or prior. Note that "mstime_malloc" also requires a rather specific
# writing style, so make sure you have the following before using:
# * You must have the following at the beginning of your HTML file:
# <!doctype html>
# <HTML XMLNS:t ="urn:schemas-microsoft-com:time">
# * You must have the following in <meta>:
# <meta>
# <?IMPORT namespace="t" implementation="#default#time2">
# </meta>
#
# The "mstime_malloc" JavaScript function supports the following arguments:
# shellcode => The shellcode to place.
# offset => Optional. The pointer index that points to the shellcode.
# heapBlockSize => Object size.
# objId => The ID to your ANIMATECOLOR element.
#
# Example of using "js_mstime_malloc":
# <script>
# #{js_mstime_malloc}
#
# shellcode = unescape("%u4141%u4141%u4141%u4141%u4141");
# offset = 3;
# s = 0x58;
# mstime_malloc({shellcode:shellcode,offset:offset,heapBlockSize:s,objId:oId});
# </script>
#
def js_mstime_malloc
@cache_mstime_malloc ||= Rex::Exploitation::Js::Memory.mstime_malloc
end
#
# This heap spray technique takes advantage of MSHTML's SetStringProperty (or SetProperty)
# function to trigger allocations by ntdll!RtlAllocateHeap. It is based on Corelan's
# publication on "DEPS Precise Heap Spray on Firefox and IE10". In IE, the shellcode
# should land at address 0x0c0d2020, as this is the most consistent location across
# various versions.
#
# The "sprayHeap" JavaScript function supports the following arguments:
# shellcode => The shellcode to spray in JavaScript. Note: Avoid null bytes.
# objId => Optional. The ID for a <div> HTML tag.
# offset => Optional. Number of bytes to align the shellcode, default: 0x00
# heapBlockSize => Optional. Allocation size, default: 0x80000
# maxAllocs => Optional. Number of allocation calls, default: 0x350
#
# Example of using the 'sprayHeap' function:
# <script>
# #{js_property_spray}
#
# var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444");
# sprayHeap({shellcode:s, heapBlockSize:0x80000});
# </script>
#
def js_property_spray
@cache_property_spray ||= Rex::Exploitation::Js::Memory.property_spray
end
def js_heap_spray
@cache_heap_spray ||= Rex::Exploitation::Js::Memory.heap_spray
end
def js_explib2
@explib2 ||= ::Rex::Exploitation::Js::Memory.explib2
end
def js_explib2_payload(payload="exec")
@explib2_payload ||= ::Rex::Exploitation::Js::Memory.explib2_payload(payload)
end
def js_os_detect
@cache_os_detect ||= ::Rex::Exploitation::Js::Detect.os
end
def js_ie_addons_detect
@cache_ie_addons_detect ||= ::Rex::Exploitation::Js::Detect.ie_addons
end
def js_misc_addons_detect
@cache_misc_addons_detect ||= ::Rex::Exploitation::Js::Detect.misc_addons
end
# Transmits a html response to the supplied client
#
# HTML evasions are implemented here.
def send_response_html(cli, body, headers = {})
body = body.to_s.unpack("C*").pack("C*")
if datastore['HTML::base64'] != 'none'
case datastore['HTML::base64']
when 'plain'
body = Rex::Text.encode_base64(body)
when 'single_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'double_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'random_space_injection'
body = Rex::Text.encode_base64(body)
new = ''
while (body.size > 0)
new << body.slice!(0, rand(3) + 1) + Rex::Text.rand_text(rand(5) + 1, '', " \n")
end
body = new
end
body = '<HTML><BODY><OBJECT ID="' + Rex::Text.rand_text_alpha(rand(10)+5) + '" ' +
'HEIGHT="100%" WIDTH="100%" TYPE="text/html" DATA="data:text/html;base64,' +
body + '">Could not render object</OBJECT></BODY></HTML>'
end
if datastore['HTML::javascript::escape'] > 0
datastore['HTML::javascript::escape'].times {
body = '<script>document.write(unescape("' + Rex::Text.to_hex(body, '%') + '"))</script>'
}
end
if [UTF_16_LE, UTF_16_BE, UTF_32_LE, UTF_32_BE, UTF_7, UTF_8].include?(datastore['HTML::unicode'])
headers['Content-Type'] = 'text/html; charset= ' + datastore['HTML::unicode']
body = Rex::Text.to_unicode(body, datastore['HTML::unicode'])
else
# special cases
case datastore['HTML::unicode']
when UTF_16_BE_MARKER
headers['Content-Type'] = 'text/html'
body = "\xFE\xFF" + Rex::Text.to_unicode(body, UTF_16_BE)
when UTF_7_ALL
headers['Content-Type'] = "text/html; charset=#{UTF_7}"
body = Rex::Text.to_unicode(body, UTF_7, 'all')
when UTF_NONE
# do nothing
else
raise RuntimeError, 'Invalid unicode. how did you get here?'
end
end
send_response(cli, body, headers)
end
end
end