Land #5110, teach Http::Response to extract hidden form inputs

This commit is contained in:
Brent Cook 2015-04-24 13:30:57 -05:00
commit 27f6adcd81
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
2 changed files with 94 additions and 0 deletions

View File

@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'uri'
require 'rex/proto/http'
require 'nokogiri'
module Rex
module Proto
@ -82,6 +83,34 @@ class Response < Packet
return cookies.strip
end
# Returns a collection of found hidden inputs
#
# @return [Array<Hash>] An array, each element represents a form that contains a hash of found hidden inputs
# * 'name' [String] The hidden input's original name. The value is the hidden input's original value.
# @example
# res = send_request_cgi('uri'=>'/')
# inputs = res.get_hidden_inputs
# session_id = inputs[0]['sessionid'] # The first form's 'sessionid' hidden input
def get_hidden_inputs
forms = []
noko = Nokogiri::HTML(self.body)
noko.search("form").each_entry do |form|
found_inputs = {}
form.search("input").each_entry do |input|
input_type = input.attributes['type'] ? input.attributes['type'].value : ''
next if input_type !~ /hidden/i
input_name = input.attributes['name'] ? input.attributes['name'].value : ''
input_value = input.attributes['value'] ? input.attributes['value'].value : ''
found_inputs[input_name] = input_value unless input_name.empty?
end
forms << found_inputs unless found_inputs.empty?
end
forms
end
#
# Updates the various parts of the HTTP response command string.
#

View File

@ -141,6 +141,71 @@ describe Rex::Proto::Http::Response do
cookies.split(';').map(&:strip)
end
describe '#get_hidden_inputs' do
let(:response) do
res = Rex::Proto::Http::Response.new(200, 'OK')
res.body = %Q|
<html>
<head>
<body>
<form action="test.php">
<input name="input_1" type="hidden" value="some_value_1" />
</form>
<form>
<input name="input_0" type="text" value="Not a hidden input" />
<input name="input_1" type="hidden" value="some_value_1" />
<INPUT name="input_2" type="hidden" value="" />
</form>
</body>
</head>
</htm>
|
res
end
subject do
cli = Rex::Proto::Http::Client.new('127.0.0.1')
cli.connect
req = cli.request_cgi({'uri'=>'/'})
res = cli.send_recv(req)
res
end
before(:each) do
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:request_cgi).with(any_args)
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv).with(any_args).and_return(response)
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:set_config).with(any_args)
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:close)
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect)
end
context 'when an HTML page contains two forms containing hidden inputs' do
it 'returns an array' do
expect(subject.get_hidden_inputs).to be_kind_of(Array)
end
it 'returns hashes in the array' do
subject.get_hidden_inputs.each do |form|
expect(form).to be_kind_of(Hash)
end
end
it 'returns \'some_value_1\' in the input_1 hidden input from the first element' do
expect(subject.get_hidden_inputs[0]['input_1']).to eq('some_value_1')
end
it 'returns two hidden inputs in the second element' do
expect(subject.get_hidden_inputs[1].length).to eq(2)
end
it 'returns an empty string for the input_2 hidden input from the second element' do
expect(subject.get_hidden_inputs[1]['input_2']).to be_empty
end
end
end
context "#get_cookies" do
it 'returns empty string for no Set-Cookies' do