Skip to content

Commit 9456506

Browse files
committed
Merge branch 'master' into feature/MSP-11124/msf-dbmanager-reorg
MSP-11124
2 parents 3bce8e4 + 0941b98 commit 9456506

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2019
-152
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
require 'metasploit/framework/login_scanner/http'
2+
3+
module Metasploit
4+
module Framework
5+
module LoginScanner
6+
7+
# Jenkins login scanner
8+
class Jenkins < HTTP
9+
10+
# Inherit LIKELY_PORTS,LIKELY_SERVICE_NAMES, and REALM_KEY from HTTP
11+
CAN_GET_SESSION = true
12+
DEFAULT_PORT = 8080
13+
PRIVATE_TYPES = [ :password ]
14+
15+
# (see Base#set_sane_defaults)
16+
def set_sane_defaults
17+
self.uri = "/j_acegi_security_check" if self.uri.nil?
18+
self.method = "POST" if self.method.nil?
19+
20+
super
21+
end
22+
23+
def attempt_login(credential)
24+
result_opts = {
25+
credential: credential,
26+
host: host,
27+
port: port,
28+
protocol: 'tcp'
29+
}
30+
if ssl
31+
result_opts[:service_name] = 'https'
32+
else
33+
result_opts[:service_name] = 'http'
34+
end
35+
begin
36+
cli = Rex::Proto::Http::Client.new(host, port, {}, ssl, ssl_version)
37+
cli.connect
38+
req = cli.request_cgi({
39+
'method'=>'POST',
40+
'uri'=>'/j_acegi_security_check',
41+
'vars_post'=> {
42+
'j_username' => credential.public,
43+
'j_password'=>credential.private
44+
}
45+
})
46+
res = cli.send_recv(req)
47+
if res && !res.headers['location'].include?('loginError')
48+
result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: res.headers)
49+
else
50+
result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: res)
51+
end
52+
rescue ::EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error
53+
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
54+
end
55+
Result.new(result_opts)
56+
end
57+
end
58+
end
59+
end
60+
end

lib/msf/base/serializer/readable_text.rb

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def self.dump_module(mod, indent = " ")
3131
when MODULE_AUX
3232
return dump_auxiliary_module(mod, indent)
3333
when MODULE_POST
34-
return dump_basic_module(mod, indent)
34+
return dump_post_module(mod, indent)
3535
else
3636
return dump_generic_module(mod, indent)
3737
end
@@ -84,14 +84,14 @@ def self.dump_exploit_target(mod, indent = '', h = nil)
8484
tbl.to_s + "\n"
8585
end
8686

87-
# Dumps an auxiliary's actions
87+
# Dumps a module's actions
8888
#
89-
# @param mod [Msf::Auxiliary] the auxiliary module.
89+
# @param mod [Msf::Module] the module.
9090
# @param indent [String] the indentation to use (only the length
9191
# matters)
9292
# @param h [String] the string to display as the table heading.
9393
# @return [String] the string form of the table.
94-
def self.dump_auxiliary_actions(mod, indent = '', h = nil)
94+
def self.dump_module_actions(mod, indent = '', h = nil)
9595
tbl = Rex::Ui::Text::Table.new(
9696
'Indent' => indent.length,
9797
'Header' => h,
@@ -108,6 +108,28 @@ def self.dump_auxiliary_actions(mod, indent = '', h = nil)
108108
tbl.to_s + "\n"
109109
end
110110

111+
# Dumps the module's selected action
112+
#
113+
# @param mod [Msf::Module] the module.
114+
# @param indent [String] the indentation to use (only the length
115+
# matters)
116+
# @param h [String] the string to display as the table heading.
117+
# @return [String] the string form of the table.
118+
def self.dump_module_action(mod, indent = '', h = nil)
119+
tbl = Rex::Ui::Text::Table.new(
120+
'Indent' => indent.length,
121+
'Header' => h,
122+
'Columns' =>
123+
[
124+
'Name',
125+
'Description',
126+
])
127+
128+
tbl << [ mod.action.name || 'All', mod.action.description || '' ]
129+
130+
tbl.to_s + "\n"
131+
end
132+
111133
# Dumps the table of payloads that are compatible with the supplied
112134
# exploit.
113135
#
@@ -146,6 +168,7 @@ def self.dump_exploit_module(mod, indent = '')
146168
output << " Privileged: " + (mod.privileged? ? "Yes" : "No") + "\n"
147169
output << " License: #{mod.license}\n"
148170
output << " Rank: #{mod.rank_to_s.capitalize}\n"
171+
output << " Disclosed: #{mod.disclosure_date}\n" if mod.disclosure_date
149172
output << "\n"
150173

151174
# Authors
@@ -201,6 +224,53 @@ def self.dump_auxiliary_module(mod, indent = '')
201224
output << " Module: #{mod.fullname}\n"
202225
output << " License: #{mod.license}\n"
203226
output << " Rank: #{mod.rank_to_s.capitalize}\n"
227+
output << " Disclosed: #{mod.disclosure_date}\n" if mod.disclosure_date
228+
output << "\n"
229+
230+
# Authors
231+
output << "Provided by:\n"
232+
mod.each_author { |author|
233+
output << indent + author.to_s + "\n"
234+
}
235+
output << "\n"
236+
237+
# Actions
238+
if mod.action
239+
output << "Available actions:\n"
240+
output << dump_module_actions(mod, indent)
241+
end
242+
243+
# Options
244+
if (mod.options.has_options?)
245+
output << "Basic options:\n"
246+
output << dump_options(mod, indent)
247+
output << "\n"
248+
end
249+
250+
# Description
251+
output << "Description:\n"
252+
output << word_wrap(Rex::Text.compress(mod.description))
253+
output << "\n"
254+
255+
# References
256+
output << dump_references(mod, indent)
257+
258+
return output
259+
end
260+
261+
# Dumps information about a post module.
262+
#
263+
# @param mod [Msf::Post] the post module.
264+
# @param indent [String] the indentation to use.
265+
# @return [String] the string form of the information.
266+
def self.dump_post_module(mod, indent = '')
267+
output = "\n"
268+
output << " Name: #{mod.name}\n"
269+
output << " Module: #{mod.fullname}\n"
270+
output << " Platform: #{mod.platform_to_s}\n"
271+
output << " Arch: #{mod.arch_to_s}\n"
272+
output << " Rank: #{mod.rank_to_s.capitalize}\n"
273+
output << " Disclosed: #{mod.disclosure_date}\n" if mod.disclosure_date
204274
output << "\n"
205275

206276
# Authors
@@ -210,6 +280,12 @@ def self.dump_auxiliary_module(mod, indent = '')
210280
}
211281
output << "\n"
212282

283+
# Actions
284+
if mod.action
285+
output << "Available actions:\n"
286+
output << dump_module_actions(mod, indent)
287+
end
288+
213289
# Options
214290
if (mod.options.has_options?)
215291
output << "Basic options:\n"

lib/msf/core/exploit/http/server.rb

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,16 @@ module Exploit::Remote::HttpServer::HTML
689689

690690
include Msf::Exploit::Remote::HttpServer
691691

692+
UTF_NONE = 'none'
693+
UTF_7 = 'utf-7'
694+
UTF_7_ALL = 'utf-7-all'
695+
UTF_8 = 'utf-8'
696+
UTF_16_LE = 'utf-16le'
697+
UTF_16_BE = 'utf-16be'
698+
UTF_16_BE_MARKER = 'utf-16be-marker'
699+
UTF_32_LE = 'utf-32le'
700+
UTF_32_BE = 'utf-32be'
701+
692702
protected
693703

694704
def initialize(info = {})
@@ -700,7 +710,7 @@ def initialize(info = {})
700710
# most browsers. as such, they are not added by default. The
701711
# mixin supports encoding using them, however they are not
702712
# listed in the Option.
703-
OptEnum.new('HTML::unicode', [false, 'Enable HTTP obfuscation via unicode', 'none', ['none', 'utf-16le', 'utf-16be', 'utf-16be-marker', 'utf-32le', 'utf-32be']]),
713+
OptEnum.new('HTML::unicode', [false, 'Enable HTTP obfuscation via unicode', UTF_NONE, [UTF_NONE, UTF_16_LE, UTF_16_BE, UTF_16_BE_MARKER, UTF_32_LE, UTF_32_BE]]),
704714
OptEnum.new('HTML::base64', [false, 'Enable HTML obfuscation via an embeded base64 html object (IE not supported)', 'none', ['none', 'plain', 'single_pad', 'double_pad', 'random_space_injection']]),
705715
OptInt.new('HTML::javascript::escape', [false, 'Enable HTML obfuscation via HTML escaping (number of iterations)', 0]),
706716
], Exploit::Remote::HttpServer::HTML)
@@ -894,19 +904,19 @@ def send_response_html(cli, body, headers = {})
894904
}
895905
end
896906

897-
if ['utf-16le','utf-16be','utf32-le','utf32-be','utf-7','utf-8'].include?(datastore['HTML::unicode'])
907+
if [UTF_16_LE, UTF_16_BE, UTF_32_LE, UTF_32_BE, UTF_7, UTF_8].include?(datastore['HTML::unicode'])
898908
headers['Content-Type'] = 'text/html; charset= ' + datastore['HTML::unicode']
899909
body = Rex::Text.to_unicode(body, datastore['HTML::unicode'])
900910
else
901911
# special cases
902912
case datastore['HTML::unicode']
903-
when 'utf-16be-marker'
913+
when UTF_16_BE_MARKER
904914
headers['Content-Type'] = 'text/html'
905-
body = "\xFE\xFF" + Rex::Text.to_unicode(body, 'utf-16be')
906-
when 'utf-7-all'
907-
headers['Content-Type'] = 'text/html; charset=utf-7'
908-
body = Rex::Text.to_unicode(body, 'utf-7', 'all')
909-
when 'none'
915+
body = "\xFE\xFF" + Rex::Text.to_unicode(body, UTF_16_BE)
916+
when UTF_7_ALL
917+
headers['Content-Type'] = "text/html; charset=#{UTF_7}"
918+
body = Rex::Text.to_unicode(body, UTF_7, 'all')
919+
when UTF_NONE
910920
# do nothing
911921
else
912922
raise RuntimeError, 'Invalid unicode. how did you get here?'

lib/msf/core/handler/reverse_tcp.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def initialize(info = {})
7070
#
7171
def setup_handler
7272
if datastore['Proxies'] and not datastore['ReverseAllowProxy']
73-
raise RuntimeError, 'TCP connect-back payloads cannot be used with Proxies. Can be overriden by setting ReverseAllowProxy to true'
73+
raise RuntimeError, "TCP connect-back payloads cannot be used with Proxies. Use 'set ReverseAllowProxy true' to override this behaviour."
7474
end
7575

7676
ex = false

lib/msf/core/rpc/v10/client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def initialize(info={})
2121
:port => 3790,
2222
:uri => '/api/',
2323
:ssl => true,
24-
:ssl_version => 'SSLv3',
24+
:ssl_version => 'TLS1',
2525
:context => {}
2626
}.merge(info)
2727

lib/msf/ui/console/command_dispatcher/core.rb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,7 @@ def cmd_set_tabs(str, words)
20092009
res << 'ENCODER'
20102010
end
20112011

2012-
if (mod.auxiliary?)
2012+
if mod.kind_of?(Msf::Module::HasActions)
20132013
res << "ACTION"
20142014
end
20152015

@@ -2149,10 +2149,10 @@ def cmd_show(*args)
21492149
print_error("No exploit module selected.")
21502150
end
21512151
when "actions"
2152-
if (mod and (mod.auxiliary? or mod.post?))
2152+
if mod && mod.kind_of?(Msf::Module::HasActions)
21532153
show_actions(mod)
21542154
else
2155-
print_error("No auxiliary module selected.")
2155+
print_error("No module with actions selected.")
21562156
end
21572157

21582158
else
@@ -2721,8 +2721,8 @@ def tab_complete_option(str, words)
27212721
return option_values_encoders() if opt.upcase == 'StageEncoder'
27222722
end
27232723

2724-
# Well-known option names specific to auxiliaries
2725-
if (mod.auxiliary?)
2724+
# Well-known option names specific to modules with actions
2725+
if mod.kind_of?(Msf::Module::HasActions)
27262726
return option_values_actions() if opt.upcase == 'ACTION'
27272727
end
27282728

@@ -2869,7 +2869,7 @@ def option_values_targets
28692869

28702870

28712871
#
2872-
# Provide valid action options for the current auxiliary module
2872+
# Provide valid action options for the current module
28732873
#
28742874
def option_values_actions
28752875
res = []
@@ -3146,6 +3146,12 @@ def show_options(mod) # :nodoc:
31463146
print("\nExploit target:\n\n#{mod_targ}\n") if (mod_targ and mod_targ.length > 0)
31473147
end
31483148

3149+
# Print the selected action
3150+
if mod.kind_of?(Msf::Module::HasActions) && mod.action
3151+
mod_action = Serializer::ReadableText.dump_module_action(mod, ' ')
3152+
print("\n#{mod.type.capitalize} action:\n\n#{mod_action}\n") if (mod_action and mod_action.length > 0)
3153+
end
3154+
31493155
# Uncomment this line if u want target like msf2 format
31503156
#print("\nTarget: #{mod.target.name}\n\n")
31513157
end
@@ -3202,8 +3208,8 @@ def show_targets(mod) # :nodoc:
32023208
end
32033209

32043210
def show_actions(mod) # :nodoc:
3205-
mod_actions = Serializer::ReadableText.dump_auxiliary_actions(mod, ' ')
3206-
print("\nAuxiliary actions:\n\n#{mod_actions}\n") if (mod_actions and mod_actions.length > 0)
3211+
mod_actions = Serializer::ReadableText.dump_module_actions(mod, ' ')
3212+
print("\n#{mod.type.capitalize} actions:\n\n#{mod_actions}\n") if (mod_actions and mod_actions.length > 0)
32073213
end
32083214

32093215
def show_advanced_options(mod) # :nodoc:

lib/msf/ui/console/module_command_dispatcher.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,22 @@ def check_simple(instance=nil)
188188
print_status("#{peer} - #{code[1]}")
189189
end
190190
else
191-
print_error("#{peer} - Check failed: The state could not be determined.")
191+
msg = "#{peer} - Check failed: The state could not be determined."
192+
print_error(msg)
193+
elog("#{msg}\n#{caller.join("\n")}")
192194
end
193-
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error
195+
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error => e
194196
# Connection issues while running check should be handled by the module
195-
rescue ::RuntimeError
197+
elog("#{e.message}\n#{e.backtrace.join("\n")}")
198+
rescue ::RuntimeError => e
196199
# Some modules raise RuntimeError but we don't necessarily care about those when we run check()
200+
elog("#{e.message}\n#{e.backtrace.join("\n")}")
197201
rescue Msf::OptionValidateError => e
198202
print_error("Check failed: #{e.message}")
203+
elog("#{e.message}\n#{e.backtrace.join("\n")}")
199204
rescue ::Exception => e
200205
print_error("#{peer} - Check failed: #{e.class} #{e}")
206+
elog("#{e.message}\n#{e.backtrace.join("\n")}")
201207
end
202208
end
203209

0 commit comments

Comments
 (0)