Move HttpServer::HTML into its own file
parent
3572ce9a37
commit
062529ce3b
|
@ -14,6 +14,8 @@ module Msf
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
module Exploit::Remote::HttpServer
|
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::Exploit::Remote::TcpServer
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
|
@ -699,255 +701,5 @@ module Exploit::Remote::HttpServer
|
||||||
# allow this module to be patched at initialization-time
|
# allow this module to be patched at initialization-time
|
||||||
Metasploit::Concern.run(self)
|
Metasploit::Concern.run(self)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue