2012-11-01 21:37:12 +02:00
# -*- coding: binary -*-
module Msf
###
#
# This module exposes methods that may be useful to exploits that deal with
2013-08-21 12:45:15 +02:00
# webservers.
2012-11-01 21:37:12 +02:00
#
###
module Exploit::Remote::Web
include Exploit :: Remote :: Tcp
include Exploit :: Remote :: HttpClient
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
# Default value for #web_payload_stub
WEB_PAYLOAD_STUB = '!payload!'
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
#
# Optional stub to be replaced with the exploit payload.
#
# Default stub is 'WEB_PAYLOAD_STUB'.
#
attr_accessor :web_payload_stub
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
# Creates an instance of a Telnet exploit module.
#
def initialize ( info = { } )
super
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
register_options ( [
2013-01-23 23:05:22 +02:00
OptString . new ( 'PATH' , [ true , 'The path to the vulnerable script.' , '/' ] ) ,
2012-11-01 21:37:12 +02:00
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 )
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
self . web_payload_stub = WEB_PAYLOAD_STUB
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def path
Rex :: Text . uri_encode ( substitute_web_payload_stub ( datastore [ 'PATH' ] ) )
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def get
substitute_in_hash ( parse_query ( datastore [ 'GET' ] ) )
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def post
substitute_in_hash ( parse_query ( datastore [ 'POST' ] ) )
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def cookies
substitute_web_payload_stub ( datastore [ 'COOKIES' ] , ',;' )
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def headers
substitute_in_hash ( parse_query ( datastore [ 'HEADERS' ] ) )
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def method
post . empty? ? 'GET' : 'POST'
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def check
path = datastore [ 'PATH' ]
print_status " Checking #{ path } "
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
response = send_request_raw ( 'uri' = > path )
return Exploit :: CheckCode :: Detected if response . code == 200
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
print_error " Server responded with #{ response . code } "
Exploit :: CheckCode :: Unknown
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
def exploit
print_status " Sending HTTP request for #{ path } "
2013-01-29 03:08:53 +02:00
res = perform_request
if res
2013-01-23 23:05:22 +02:00
print_status " The server responded with HTTP status code #{ res . code } . "
2013-01-25 05:41:28 -06:00
else
print_status 'The server did not respond to our request.'
2013-01-23 23:05:22 +02:00
end
2012-11-16 23:11:48 +02:00
handler
2013-01-25 05:41:28 -06:00
end
2013-08-30 16:28:33 -05:00
2013-01-23 23:05:22 +02:00
def tries
1
2012-11-16 23:11:48 +02:00
end
2013-08-30 16:28:33 -05:00
2013-01-23 23:05:22 +02:00
private
2013-08-30 16:28:33 -05:00
2012-11-16 23:11:48 +02:00
def perform_request
2012-11-21 23:28:26 +02:00
send_request_cgi ( {
2012-11-01 21:37:12 +02:00
'global' = > true ,
'uri' = > path ,
'method' = > method ,
'vars_get' = > get ,
'vars_post' = > post ,
'headers' = > headers ,
'cookie' = > cookies
2013-02-25 19:49:39 +02:00
} , 10 )
2012-11-01 21:37:12 +02:00
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
#
# Converts a URI query string into a key=>value hash.
#
def parse_query ( query , sep = '&' )
query = query . to_s
return { } if query . empty?
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
query . split ( sep ) . inject ( { } ) do | h , part |
k , v = part . split ( '=' , 2 )
h [ k . to_s ] = v . to_s
h
end
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
#
# With what to replace 'WEB_PAYLOAD_STUB'.
#
# By default returns 'payload.encoded', override as needed.
#
def stub_value
payload . encoded
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
#
# Substitutes 'web_payload_stub' with the exploit payload.
#
def substitute_web_payload_stub ( str , escape = '' )
value = stub_value
2021-11-22 14:11:03 -06:00
value = URI :: DEFAULT_PARSER . escape ( stub_value , escape ) if ! escape . empty?
2012-11-01 21:37:12 +02:00
str . to_s . gsub ( web_payload_stub , value )
end
2013-08-30 16:28:33 -05:00
2012-11-01 21:37:12 +02:00
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