Skip to content

Commit 717120b

Browse files
committed
Add #get_hidden_inputs for Metasploit::Framework::LoginScanner::HTTP
1 parent c9bf8f3 commit 717120b

File tree

2 files changed

+74
-0
lines changed
  • lib/metasploit/framework/login_scanner
  • spec/lib/metasploit/framework/login_scanner

2 files changed

+74
-0
lines changed

lib/metasploit/framework/login_scanner/http.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'rex/proto/http'
22
require 'metasploit/framework/login_scanner/base'
33
require 'metasploit/framework/login_scanner/rex_socket'
4+
require 'nokogiri'
45

56
module Metasploit
67
module Framework
@@ -241,6 +242,32 @@ def send_request(opts)
241242
end
242243

243244

245+
# Returns a collection of found hidden inputs
246+
#
247+
# @param res [Rex::Proto::Http::Response] A response object that contains a body
248+
# @return [Array<Hash>] An array, each element represents a form that contains a hash of found hidden inputs
249+
# * 'name' [String] The hidden input's original name. The value is the hidden input's original value.
250+
# @example
251+
# res = send_request('uri'=>'/')
252+
# inputs = get_hidden_inputs(res)
253+
# session_id = inputs[0]['sessionid'] # The first form's 'sessionid' hidden input
254+
def get_hidden_inputs(res)
255+
forms = []
256+
noko = Nokogiri::HTML(res.body)
257+
noko.search("form").each_entry do |form|
258+
found_inputs = {}
259+
form.search("input").each_entry do |input|
260+
input_name = input.attributes['name'] ? input.attributes['name'].value : ''
261+
input_value = input.attributes['value'] ? input.attributes['value'].value : ''
262+
found_inputs[input_name] = input_value unless input_name.empty?
263+
end
264+
forms << found_inputs unless found_inputs.empty?
265+
end
266+
267+
forms
268+
end
269+
270+
244271
# Attempt a single login with a single credential against the target.
245272
#
246273
# @param credential [Credential] The credential object to attempt to

spec/lib/metasploit/framework/login_scanner/http_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,51 @@
3030
end
3131
end
3232

33+
describe '#get_hidden_inputs' do
34+
let(:response) do
35+
res = Rex::Proto::Http::Response.new(200, 'OK')
36+
res.body = %Q|
37+
<html>
38+
<head>
39+
<body>
40+
<form action="test.php">
41+
<input name="input_1" type="hidden" value="some_value_1" />
42+
</form>
43+
<form>
44+
<input name="input_1" type="hidden" value="some_value_1" />
45+
<INPUT name="input_2" type="hidden" value="" />
46+
</form>
47+
</body>
48+
</head>
49+
</htm>
50+
|
51+
res
52+
end
53+
54+
55+
context 'when an HTML page contains two forms containing hidden inputs' do
56+
it 'returns an array' do
57+
expect(subject.get_hidden_inputs(response)).to be_kind_of(Array)
58+
end
59+
60+
it 'returns hashes in the array' do
61+
subject.get_hidden_inputs(response).each do |form|
62+
expect(form).to be_kind_of(Hash)
63+
end
64+
end
65+
66+
it 'returns \'some_value_1\' in the input_1 hidden input from the first element' do
67+
expect(subject.get_hidden_inputs(response)[0]['input_1']).to eq('some_value_1')
68+
end
69+
70+
it 'returns two hidden inputs in the second element' do
71+
expect(subject.get_hidden_inputs(response)[1].length).to eq(2)
72+
end
73+
74+
it 'returns an empty string for the input_2 hidden input from the second element' do
75+
expect(subject.get_hidden_inputs(response)[1]['input_2']).to be_empty
76+
end
77+
end
78+
end
79+
3380
end

0 commit comments

Comments
 (0)