# -*- coding: binary -*- module Msf ### # # This module exposes methods that may be useful to exploits that deal with # webservers. # ### module Exploit::Remote::Web include Exploit::Remote::Tcp include Exploit::Remote::HttpClient # Default value for #web_payload_stub WEB_PAYLOAD_STUB = '!payload!' # # Optional stub to be replaced with the exploit payload. # # Default stub is 'WEB_PAYLOAD_STUB'. # attr_accessor :web_payload_stub # Creates an instance of a Telnet exploit module. # def initialize( info = {} ) super register_options([ OptString.new( 'PATH', [ true, 'The path to the vulnerable script.', '/' ] ), OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), OptString.new( 'HEADERS', [ false, "Headers to be sent with the request. ('User-Agent=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), ], self.class ) self.web_payload_stub = WEB_PAYLOAD_STUB end def path Rex::Text.uri_encode( substitute_web_payload_stub( datastore['PATH'] ) ) end def get substitute_in_hash( parse_query( datastore['GET'] ) ) end def post substitute_in_hash( parse_query( datastore['POST'] ) ) end def cookies substitute_web_payload_stub( datastore['COOKIES'], ',;' ) end def headers substitute_in_hash( parse_query( datastore['HEADERS'] ) ) end def method post.empty? ? 'GET' : 'POST' end def check path = datastore['PATH'] print_status "Checking #{path}" response = send_request_raw( 'uri' => path ) return Exploit::CheckCode::Detected if response.code == 200 print_error "Server responded with #{response.code}" Exploit::CheckCode::Unknown end def exploit print_status "Sending HTTP request for #{path}" res = perform_request if res print_status "The server responded with HTTP status code #{res.code}." else print_status 'The server did not respond to our request.' end handler end def tries 1 end private def perform_request send_request_cgi({ 'global' => true, 'uri' => path, 'method' => method, 'vars_get' => get, 'vars_post' => post, 'headers' => headers, 'cookie' => cookies }, 10 ) end # # Converts a URI query string into a key=>value hash. # def parse_query( query, sep = '&' ) query = query.to_s return {} if query.empty? query.split( sep ).inject({}) do |h, part| k, v = part.split( '=', 2 ) h[k.to_s] = v.to_s h end end # # With what to replace 'WEB_PAYLOAD_STUB'. # # By default returns 'payload.encoded', override as needed. # def stub_value payload.encoded end # # Substitutes 'web_payload_stub' with the exploit payload. # def substitute_web_payload_stub( str, escape = '' ) value = stub_value value = URI.encode( stub_value, escape ) if !escape.empty? str.to_s.gsub( web_payload_stub, value ) end def substitute_in_hash( hash ) hash.inject({}) do |h, (k, v)| h[substitute_web_payload_stub( k )] = substitute_web_payload_stub( v ) h end end end end