Skip to content

Commit 27f6adc

Browse files
author
Brent Cook
committed
Land rapid7#5110, teach Http::Response to extract hidden form inputs
2 parents 7167dc1 + f280e51 commit 27f6adc

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

lib/rex/proto/http/response.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: binary -*-
22
require 'uri'
33
require 'rex/proto/http'
4+
require 'nokogiri'
45

56
module Rex
67
module Proto
@@ -82,6 +83,34 @@ def get_cookies
8283
return cookies.strip
8384
end
8485

86+
87+
# Returns a collection of found hidden inputs
88+
#
89+
# @return [Array<Hash>] An array, each element represents a form that contains a hash of found hidden inputs
90+
# * 'name' [String] The hidden input's original name. The value is the hidden input's original value.
91+
# @example
92+
# res = send_request_cgi('uri'=>'/')
93+
# inputs = res.get_hidden_inputs
94+
# session_id = inputs[0]['sessionid'] # The first form's 'sessionid' hidden input
95+
def get_hidden_inputs
96+
forms = []
97+
noko = Nokogiri::HTML(self.body)
98+
noko.search("form").each_entry do |form|
99+
found_inputs = {}
100+
form.search("input").each_entry do |input|
101+
input_type = input.attributes['type'] ? input.attributes['type'].value : ''
102+
next if input_type !~ /hidden/i
103+
104+
input_name = input.attributes['name'] ? input.attributes['name'].value : ''
105+
input_value = input.attributes['value'] ? input.attributes['value'].value : ''
106+
found_inputs[input_name] = input_value unless input_name.empty?
107+
end
108+
forms << found_inputs unless found_inputs.empty?
109+
end
110+
111+
forms
112+
end
113+
85114
#
86115
# Updates the various parts of the HTTP response command string.
87116
#

spec/lib/rex/proto/http/response_spec.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,71 @@ def cookie_sanity_check(meth)
141141
cookies.split(';').map(&:strip)
142142
end
143143

144+
145+
describe '#get_hidden_inputs' do
146+
let(:response) do
147+
res = Rex::Proto::Http::Response.new(200, 'OK')
148+
res.body = %Q|
149+
<html>
150+
<head>
151+
<body>
152+
<form action="test.php">
153+
<input name="input_1" type="hidden" value="some_value_1" />
154+
</form>
155+
<form>
156+
<input name="input_0" type="text" value="Not a hidden input" />
157+
<input name="input_1" type="hidden" value="some_value_1" />
158+
<INPUT name="input_2" type="hidden" value="" />
159+
</form>
160+
</body>
161+
</head>
162+
</htm>
163+
|
164+
res
165+
end
166+
167+
subject do
168+
cli = Rex::Proto::Http::Client.new('127.0.0.1')
169+
cli.connect
170+
req = cli.request_cgi({'uri'=>'/'})
171+
res = cli.send_recv(req)
172+
res
173+
end
174+
175+
before(:each) do
176+
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:request_cgi).with(any_args)
177+
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv).with(any_args).and_return(response)
178+
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:set_config).with(any_args)
179+
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:close)
180+
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect)
181+
end
182+
183+
context 'when an HTML page contains two forms containing hidden inputs' do
184+
it 'returns an array' do
185+
expect(subject.get_hidden_inputs).to be_kind_of(Array)
186+
end
187+
188+
it 'returns hashes in the array' do
189+
subject.get_hidden_inputs.each do |form|
190+
expect(form).to be_kind_of(Hash)
191+
end
192+
end
193+
194+
it 'returns \'some_value_1\' in the input_1 hidden input from the first element' do
195+
expect(subject.get_hidden_inputs[0]['input_1']).to eq('some_value_1')
196+
end
197+
198+
it 'returns two hidden inputs in the second element' do
199+
expect(subject.get_hidden_inputs[1].length).to eq(2)
200+
end
201+
202+
it 'returns an empty string for the input_2 hidden input from the second element' do
203+
expect(subject.get_hidden_inputs[1]['input_2']).to be_empty
204+
end
205+
end
206+
end
207+
208+
144209
context "#get_cookies" do
145210

146211
it 'returns empty string for no Set-Cookies' do

0 commit comments

Comments
 (0)