Skip to content

Commit

Permalink
Merge pull request #5 from jlee-r7/dmaloney-r7-http/auth_methods
Browse files Browse the repository at this point in the history
Return a Request object
  • Loading branch information
dmaloney-r7 authored and dmaloney-r7 committed Feb 7, 2013
2 parents 888bb80 + a158893 commit e13f16c
Show file tree
Hide file tree
Showing 19 changed files with 773 additions and 91 deletions.
Binary file modified data/gui/msfgui.jar
Binary file not shown.
3 changes: 2 additions & 1 deletion external/source/gui/msfguijava/src/msfgui/RpcConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ protected RpcConnection doInBackground() throws Exception {
// Don't fork cause we'll check if it dies
String rpcType = "Basic";
java.util.List args = new java.util.ArrayList(java.util.Arrays.asList(new String[]{
"msfrpcd","-f","-P",defaultPass,"-t","Msg","-U",defaultUser,"-a","127.0.0.1"}));
"msfrpcd","-f","-P",defaultPass,"-t","Msg","-U",defaultUser,"-a","127.0.0.1",
"-p",Integer.toString(defaultPort)}));
if(!defaultSsl)
args.add("-S");
if(disableDb)
Expand Down
134 changes: 76 additions & 58 deletions lib/rex/proto/http/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,27 +151,44 @@ def set_config(opts = {})
#
# Create an arbitrary HTTP request
#
# @param opts [Hash]
# @option opts 'agent' [String] User-Agent header value
# @option opts 'basic_auth' [String] Basic-Auth header value
# @option opts 'connection' [String] Connection header value
# @option opts 'cookie' [String] Cookie header value
# @option opts 'data' [String] HTTP data (only useful with some methods, see rfc2616)
# @option opts 'encode' [Bool] URI encode the supplied URI, default: false
# @option opts 'headers' [Hash] HTTP headers, e.g. <code>{ "X-MyHeader" => "value" }</code>
# @option opts 'method' [String] HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
# @option opts 'proto' [String] protocol, default: HTTP
# @option opts 'query' [String] raw query string
# @option opts 'raw_headers' [Hash] HTTP headers
# @option opts 'uri' [String] the URI to request
# @option opts 'version' [String] version of the protocol, default: 1.1
# @option opts 'vhost' [String] Host header value
#
# @return [Request]
def request_raw(opts={})
c_enc = opts['encode'] || false
c_uri = opts['uri'] || '/'
c_ag = opts['agent'] || config['agent']
c_auth = opts['basic_auth'] || config['basic_auth'] || ''
c_body = opts['data'] || ''
c_conn = opts['connection']
c_cook = opts['cookie'] || config['cookie']
c_enc = opts['encode'] || false
c_head = opts['headers'] || config['headers'] || {}
c_host = opts['vhost'] || config['vhost'] || self.hostname
c_meth = opts['method'] || 'GET'
c_prot = opts['proto'] || 'HTTP'
c_vers = opts['version'] || config['version'] || '1.1'
c_qs = opts['query']
c_ag = opts['agent'] || config['agent']
c_cook = opts['cookie'] || config['cookie']
c_host = opts['vhost'] || config['vhost'] || self.hostname
c_head = opts['headers'] || config['headers'] || {}
c_rawh = opts['raw_headers']|| config['raw_headers'] || ''
c_conn = opts['connection']
c_auth = opts['basic_auth'] || config['basic_auth'] || ''
c_uri = opts['uri'] || '/'
c_vers = opts['version'] || config['version'] || '1.1'

# An agent parameter was specified, but so was a header, prefer the header
if c_ag and c_head.keys.map{|x| x.downcase }.include?('user-agent')
c_ag = nil
end

uri = set_uri(c_uri)

req = ''
Expand All @@ -191,7 +208,6 @@ def request_raw(opts={})
req << set_host_header(c_host)
req << set_agent_header(c_ag)


if (c_auth.length > 0)
req << set_basic_auth_header(c_auth)
end
Expand All @@ -201,53 +217,45 @@ def request_raw(opts={})
req << set_extra_headers(c_head)
req << set_raw_headers(c_rawh)
req << set_body(c_body)

{:string => req , :opts => opts}

request = Request.new
request.parse(req)
request.options = opts

request
end


#
# Create a CGI compatible request
#
# Options:
# - agent: User-Agent header value
# - basic_auth: Basic-Auth header value
# - connection: Connection header value
# - cookie: Cookie header value
# - ctype: Content-Type header value, default: +application/x-www-form-urlencoded+
# - data: HTTP data (only useful with some methods, see rfc2616)
# - encode: URI encode the supplied URI, default: false
# - encode_params: URI encode the GET or POST variables (names and values), default: true
# - headers: HTTP headers as a hash, e.g. <code>{ "X-MyHeader" => "value" }</code>
# - method: HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
# - proto: protocol, default: HTTP
# - query: raw query string
# - raw_headers: HTTP headers as a hash
# - uri: the URI to request
# - vars_get: GET variables as a hash to be translated into a query string
# - vars_post: POST variables as a hash to be translated into POST data
# - version: version of the protocol, default: 1.1
# - vhost: Host header value
# @param (see #request_raw)
# @option opts (see #request_raw)
# @option opts 'ctype' [String] Content-Type header value, default: +application/x-www-form-urlencoded+
# @option opts 'encode_params' [Bool] URI encode the GET or POST variables (names and values), default: true
# @option opts 'vars_get' [Hash] GET variables as a hash to be translated into a query string
# @option opts 'vars_post' [Hash] POST variables as a hash to be translated into POST data
#
# @return [Request]
def request_cgi(opts={})
c_ag = opts['agent'] || config['agent']
c_body = opts['data'] || ''
c_cgi = opts['uri'] || '/'
c_conn = opts['connection']
c_cook = opts['cookie'] || config['cookie']
c_enc = opts['encode'] || false
c_enc_p = (opts['encode_params'] == true or opts['encode_params'].nil? ? true : false)
c_cgi = opts['uri'] || '/'
c_body = opts['data'] || ''
c_head = opts['headers'] || config['headers'] || {}
c_host = opts['vhost'] || config['vhost']
c_meth = opts['method'] || 'GET'
c_path = opts['path_info']
c_prot = opts['proto'] || 'HTTP'
c_vers = opts['version'] || config['version'] || '1.1'
c_qs = opts['query'] || ''
c_varg = opts['vars_get'] || {}
c_varp = opts['vars_post'] || {}
c_head = opts['headers'] || config['headers'] || {}
c_rawh = opts['raw_headers'] || config['raw_headers'] || ''
c_type = opts['ctype'] || 'application/x-www-form-urlencoded'
c_ag = opts['agent'] || config['agent']
c_cook = opts['cookie'] || config['cookie']
c_host = opts['vhost'] || config['vhost']
c_conn = opts['connection']
c_path = opts['path_info']
c_varg = opts['vars_get'] || {}
c_varp = opts['vars_post'] || {}
c_vers = opts['version'] || config['version'] || '1.1'

uri = set_cgi(c_cgi)
qstr = c_qs
Expand All @@ -264,7 +272,7 @@ def request_cgi(opts={})

c_varg.each_pair do |var,val|
qstr << '&' if qstr.length > 0
qstr << (c_enc_p ? set_encode_uri(var) : var)
qstr << (c_enc_p ? set_encode_uri(var) : var)
qstr << '='
qstr << (c_enc_p ? set_encode_uri(val) : val)
end
Expand Down Expand Up @@ -315,12 +323,19 @@ def request_cgi(opts={})
req << set_raw_headers(c_rawh)
req << set_body(pstr)

{:string => req , :opts => opts}
request = Request.new
request.parse(req)
request.options = opts

request
end

#
# Connects to the remote server if possible.
#
# @param t [Fixnum] Timeout
# @see Rex::Socket::Tcp.create
# @return [Rex::Socket::Tcp]
def connect(t = -1)
# If we already have a connection and we aren't pipelining, close it.
if (self.conn)
Expand Down Expand Up @@ -360,28 +375,29 @@ def close

#
# Sends a request and gets a response back
# If the request is a 401, and we have creds, it will attempt to
# complete authentication and return the final response
#
# If the request is a 401, and we have creds, it will attempt to complete
# authentication and return the final response
#
def send_recv(req, t = -1, persist=false)
opts = req[:opts]
req = req[:string]
res = _send_recv(req,t,persist)
if res and res.code == 401 and res.headers['WWW-Authenticate'] and have_creds?
res = send_auth(res, opts, t, persist)
res = send_auth(res, req.options, t, persist)
end
res
end

#
# Transmit an HTTP request and receive the response
# If persist is set, then the request will attempt
# to reuse an existing connection.
#
# If persist is set, then the request will attempt to reuse an existing
# connection.
#
# Call this directly instead of {#send_recv} if you don't want automatic
# authentication handling.
#
# @return [Response]
def _send_recv(req, t = -1, persist=false)
if req.kind_of? Hash and req[:string]
req = req[:string]
end
@pipeline = persist
send_request(req, t)
res = read_response(t)
Expand All @@ -392,12 +408,14 @@ def _send_recv(req, t = -1, persist=false)
#
# Send an HTTP request to the server
#
# @param req [Request,#to_s] The request to send
# @param t (see #connect)
def send_request(req, t = -1)
connect(t)
conn.put(req.to_s)
end

# Validates that the client has creds
# Validates that the client has creds
def have_creds?
!(self.username.nil?) && self.username != ''
end
Expand All @@ -420,7 +438,7 @@ def send_auth(res, opts, t, persist)
else
opts['headers'] = { 'Authorization' => basic_auth_header(self.username,self.password)}
end

req = request_cgi(opts)
res = _send_recv(req,t,persist)
return res
Expand Down Expand Up @@ -628,7 +646,7 @@ def negotiate_auth(opts={})
opts['password'] ||= self.password.to_s

if opts['provider'] and opts['provider'].include? 'Negotiate'
provider = "Negotiate "
provider = "Negotiate "
else
provider = 'NTLM '
end
Expand Down
2 changes: 2 additions & 0 deletions lib/rex/proto/http/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def initialize(uri = '/', proto = DefaultProtocol)
end
end

attr_accessor :options

#
# Initializes an instance of an HTTP request with the supplied method, URI,
# and protocol.
Expand Down
4 changes: 2 additions & 2 deletions modules/auxiliary/admin/http/netgear_sph200d_traversal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def find_files(file,user,pass)
:category => "web",
:method => "GET"
})

loot = store_loot("lfi.data","text/plain",rhost, res.body,file)
vprint_good("#{rhost}:#{rport} - File #{file} downloaded to: #{loot}")
elsif res and res.code
Expand All @@ -89,7 +89,7 @@ def run_host(ip)
pass = datastore['PASSWORD']

vprint_status("#{rhost}:#{rport} - Trying to login with #{user} / #{pass}")

#test login
begin
res = send_request_cgi({
Expand Down
30 changes: 20 additions & 10 deletions modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ def initialize(info={})
This module attempts to identify Ruby on Rails instances vulnerable to
an arbitrary object instantiation flaw in the XML request processor.
},
'Author' => 'hdm',
'Author' => [
'hdm', #author
'jjarmoc' #improvements
],
'License' => MSF_LICENSE,
'References' =>
[
Expand All @@ -29,15 +32,16 @@ def initialize(info={})
))

register_options([
OptString.new('URIPATH', [true, "The URI to test", "/"])
OptString.new('URIPATH', [true, "The URI to test", "/"]),
OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST', 'PUT'] ]),
], self.class)
end

def send_probe(ptype, pdata)
odata = %Q^<?xml version="1.0" encoding="UTF-8"?>\n<probe type="#{ptype}"><![CDATA[\n#{pdata}\n]]></probe>^
res = send_request_cgi({
'uri' => datastore['URIPATH'] || "/",
'method' => 'POST',
'method' => datastore['HTTP_METHOD'],
'ctype' => 'application/xml',
'data' => odata
}, 25)
Expand All @@ -46,29 +50,35 @@ def send_probe(ptype, pdata)
def run_host(ip)

res1 = send_probe("string", "hello")
res2 = send_probe("yaml", "--- !ruby/object:Time {}\n")
res3 = send_probe("yaml", "--- !ruby/object:\x00")

unless res1
vprint_status("#{rhost}:#{rport} No reply to the initial XML request")
return
end

if res1.code.to_s =~ /^[5]/
vprint_status("#{rhost}:#{rport} The server replied with #{res1.code} for our initial XML request, double check URIPATH")
return
end

res2 = send_probe("yaml", "--- !ruby/object:Time {}\n")

unless res2
vprint_status("#{rhost}:#{rport} No reply to the initial YAML probe")
return
end

res3 = send_probe("yaml", "--- !ruby/object:\x00")

unless res3
vprint_status("#{rhost}:#{rport} No reply to the second YAML probe")
return
end

if res1.code.to_s =~ /^[45]/
vprint_status("#{rhost}:#{rport} The server replied with #{res1.code} for our initial XML request, double check URIPATH")
end
vprint_status("Probe response codes: #{res1.code} / #{res2.code} / #{res3.code}")


if res2.code.to_s =~ /^[23]/ and res3.code != res2.code and res3.code != 200
if (res2.code == res1.code) and (res3.code != res2.code) and (res3.code != 200)
print_good("#{rhost}:#{rport} is likely vulnerable due to a #{res3.code} reply for invalid YAML")
report_vuln({
:host => rhost,
Expand All @@ -79,7 +89,7 @@ def run_host(ip)
:refs => self.references
})
else
vprint_status("#{rhost}:#{rport} is not likely to be vulnerable or URIPATH must be set")
vprint_status("#{rhost}:#{rport} is not likely to be vulnerable or URIPATH & HTTP_METHOD must be set")
end
end

Expand Down
4 changes: 2 additions & 2 deletions modules/auxiliary/scanner/misc/dvr_config_disclosure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def initialize

end

def get_ppooe_credentials(conf)
def get_pppoe_credentials(conf)

user = ""
password = ""
Expand Down Expand Up @@ -208,7 +208,7 @@ def run_host(ip)
get_ftp_credentials(conf)
get_dvr_credentials(conf)
get_ddns_credentials(conf)
get_ppooe_credentials(conf)
get_pppoe_credentials(conf)

dvr_name = ""
if res.body =~ /DVR_NAME=(.*)/
Expand Down
Loading

0 comments on commit e13f16c

Please sign in to comment.