continued
parent
140621ad9b
commit
6072697126
|
@ -16,6 +16,7 @@ PATH
|
||||||
metasploit-payloads (= 1.1.11)
|
metasploit-payloads (= 1.1.11)
|
||||||
metasploit_data_models
|
metasploit_data_models
|
||||||
msgpack
|
msgpack
|
||||||
|
net-ssh
|
||||||
network_interface
|
network_interface
|
||||||
nokogiri
|
nokogiri
|
||||||
octokit
|
octokit
|
||||||
|
@ -134,7 +135,7 @@ GEM
|
||||||
activemodel (~> 4.2.6)
|
activemodel (~> 4.2.6)
|
||||||
activesupport (~> 4.2.6)
|
activesupport (~> 4.2.6)
|
||||||
railties (~> 4.2.6)
|
railties (~> 4.2.6)
|
||||||
metasploit-credential (2.0.2)
|
metasploit-credential (2.0.3)
|
||||||
metasploit-concern
|
metasploit-concern
|
||||||
metasploit-model
|
metasploit-model
|
||||||
metasploit_data_models
|
metasploit_data_models
|
||||||
|
@ -167,6 +168,7 @@ GEM
|
||||||
multi_json (1.12.0)
|
multi_json (1.12.0)
|
||||||
multi_test (0.1.2)
|
multi_test (0.1.2)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
|
net-ssh (3.2.0)
|
||||||
network_interface (0.0.1)
|
network_interface (0.0.1)
|
||||||
nokogiri (1.6.7.2)
|
nokogiri (1.6.7.2)
|
||||||
mini_portile2 (~> 2.0.0.rc2)
|
mini_portile2 (~> 2.0.0.rc2)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require 'net/ssh'
|
require 'net/ssh'
|
||||||
require 'metasploit/framework/login_scanner/base'
|
require 'metasploit/framework/login_scanner/base'
|
||||||
|
require 'rex/socket/ssh_factory'
|
||||||
|
|
||||||
module Metasploit
|
module Metasploit
|
||||||
module Framework
|
module Framework
|
||||||
|
@ -47,12 +48,13 @@ module Metasploit
|
||||||
# @note The caller *must* close {#ssh_socket}
|
# @note The caller *must* close {#ssh_socket}
|
||||||
def attempt_login(credential)
|
def attempt_login(credential)
|
||||||
self.ssh_socket = nil
|
self.ssh_socket = nil
|
||||||
|
factory = Rex::Socket::SSHFactory.new(framework,framework_module, proxies)
|
||||||
opt_hash = {
|
opt_hash = {
|
||||||
:port => port,
|
:port => port,
|
||||||
:disable_agent => true,
|
:use_agent => false,
|
||||||
:config => false,
|
:config => false,
|
||||||
:verbose => verbosity,
|
:verbose => verbosity,
|
||||||
:proxies => proxies
|
:proxy => factory
|
||||||
}
|
}
|
||||||
case credential.private_type
|
case credential.private_type
|
||||||
when :password, nil
|
when :password, nil
|
||||||
|
|
|
@ -207,7 +207,7 @@ protected
|
||||||
initialize_abstraction
|
initialize_abstraction
|
||||||
|
|
||||||
self.lsock.extend(TcpReverseDoubleChannelExt)
|
self.lsock.extend(TcpReverseDoubleChannelExt)
|
||||||
self.lsock.peerinfo = @sock_inp.getpeername[1,2].map{|x| x.to_s}.join(":")
|
self.lsock.peerinfo = @sock_inp.getpeername_as_array[1,2].map{|x| x.to_s}.join(":")
|
||||||
self.lsock.localinfo = @sock_inp.getsockname[1,2].map{|x| x.to_s}.join(":")
|
self.lsock.localinfo = @sock_inp.getsockname[1,2].map{|x| x.to_s}.join(":")
|
||||||
|
|
||||||
monitor_shell_stdout
|
monitor_shell_stdout
|
||||||
|
|
|
@ -256,7 +256,7 @@ protected
|
||||||
initialize_abstraction
|
initialize_abstraction
|
||||||
|
|
||||||
self.lsock.extend(TcpReverseDoubleSSLChannelExt)
|
self.lsock.extend(TcpReverseDoubleSSLChannelExt)
|
||||||
self.lsock.peerinfo = @sock_inp.getpeername[1,2].map{|x| x.to_s}.join(":")
|
self.lsock.peerinfo = @sock_inp.getpeername_as_array[1,2].map{|x| x.to_s}.join(":")
|
||||||
self.lsock.localinfo = @sock_inp.getsockname[1,2].map{|x| x.to_s}.join(":")
|
self.lsock.localinfo = @sock_inp.getsockname[1,2].map{|x| x.to_s}.join(":")
|
||||||
|
|
||||||
monitor_shell_stdout
|
monitor_shell_stdout
|
||||||
|
|
|
@ -39,14 +39,14 @@ module SocketAbstraction
|
||||||
hops += 1
|
hops += 1
|
||||||
end
|
end
|
||||||
_address_family,caddr,_cport = csock.getsockname
|
_address_family,caddr,_cport = csock.getsockname
|
||||||
address_family,raddr,_rport = csock.getpeername
|
address_family,raddr,_rport = csock.getpeername_as_array
|
||||||
_maddr,mport = [ channel.params.localhost, channel.params.localport ]
|
_maddr,mport = [ channel.params.localhost, channel.params.localport ]
|
||||||
[ address_family, "#{caddr}#{(hops > 0) ? "-_#{hops}_" : ""}-#{raddr}", "#{mport}" ]
|
[ address_family, "#{caddr}#{(hops > 0) ? "-_#{hops}_" : ""}-#{raddr}", "#{mport}" ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def getpeername
|
def getpeername
|
||||||
return super if not channel
|
return super if not channel
|
||||||
address_family,_caddr,_cport = channel.client.sock.getpeername
|
address_family,_caddr,_cport = channel.client.sock.getpeername_as_array
|
||||||
maddr,mport = [ channel.params.peerhost, channel.params.peerport ]
|
maddr,mport = [ channel.params.peerhost, channel.params.peerport ]
|
||||||
[ address_family, "#{maddr}", "#{mport}" ]
|
[ address_family, "#{maddr}", "#{mport}" ]
|
||||||
end
|
end
|
||||||
|
|
|
@ -283,7 +283,7 @@ class Socks4a
|
||||||
# close the listening socket
|
# close the listening socket
|
||||||
bsock.close
|
bsock.close
|
||||||
# verify the connection is from the dest_ip origionally specified by the client
|
# verify the connection is from the dest_ip origionally specified by the client
|
||||||
rpeer = @rsock.getpeername
|
rpeer = @rsock.getpeername_as_array
|
||||||
raise "Got connection from an invalid peer." if( rpeer[HOST] != request.dest_ip )
|
raise "Got connection from an invalid peer." if( rpeer[HOST] != request.dest_ip )
|
||||||
# send back the client connect success to the client
|
# send back the client connect success to the client
|
||||||
#
|
#
|
||||||
|
|
|
@ -731,7 +731,7 @@ module Socket
|
||||||
#
|
#
|
||||||
# Return peer connection information.
|
# Return peer connection information.
|
||||||
#
|
#
|
||||||
def getpeername
|
def getpeername_as_array
|
||||||
peer_name = nil
|
peer_name = nil
|
||||||
begin
|
begin
|
||||||
peer_name = Socket.from_sockaddr(super)
|
peer_name = Socket.from_sockaddr(super)
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
module Rex
|
||||||
|
module Socket
|
||||||
|
|
||||||
|
# This class exists to abuse the Proxy capabilities in the Net::SSH library to allow the use of Rex::Sockets
|
||||||
|
# for the transport layer in Net::SSH. The SSHFactory object will respond to the #open method and create the
|
||||||
|
# {Rex::Socket::Tcp}
|
||||||
|
class SSHFactory
|
||||||
|
|
||||||
|
# @!attribute msfraemwork
|
||||||
|
# @return [Object] The framework instance object
|
||||||
|
attr_accessor :msframework
|
||||||
|
# @!attribute msfmodule
|
||||||
|
# @return [Object] The metasploit module this socket belongs to
|
||||||
|
attr_accessor :msfmodule
|
||||||
|
# @!attribute proxies
|
||||||
|
# @return [String] Any proxies to use for the connection
|
||||||
|
attr_accessor :proxies
|
||||||
|
|
||||||
|
def initialize(framework, msfmodule, proxies)
|
||||||
|
@msframework = framework
|
||||||
|
@msfmodule = msfmodule
|
||||||
|
@proxies = proxies
|
||||||
|
end
|
||||||
|
|
||||||
|
# Responds to the proxy setup routine Net::SSH will call when
|
||||||
|
# initialising the Transport Layer. This will instead create our
|
||||||
|
# {Rex::Socket::Tcp} and tie the socket back to the calling module
|
||||||
|
# @param host [String] The host to open the connection to
|
||||||
|
# @param port [Fixnum] the port to open the connection on
|
||||||
|
# @param options [Hash] the options hash
|
||||||
|
def open(host, port, options={})
|
||||||
|
socket = Rex::Socket::Tcp.create(
|
||||||
|
'PeerHost' => host,
|
||||||
|
'PeerPort' => port,
|
||||||
|
'Proxies' => proxies,
|
||||||
|
'Context' => {
|
||||||
|
'Msf' => msframework,
|
||||||
|
'MsfExploit' => msfmodule
|
||||||
|
}
|
||||||
|
)
|
||||||
|
msfmodule.add_socket(socket) if msfmodule
|
||||||
|
socket
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -57,7 +57,7 @@ module Rex::Socket::Tcp
|
||||||
# Returns peer information (host + port) in host:port format.
|
# Returns peer information (host + port) in host:port format.
|
||||||
#
|
#
|
||||||
def peerinfo
|
def peerinfo
|
||||||
if (pi = getpeername)
|
if (pi = getpeername_as_array)
|
||||||
return pi[1] + ':' + pi[2].to_s
|
return pi[1] + ':' + pi[2].to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,7 +54,7 @@ module Rex::Socket::TcpServer
|
||||||
t.extend(Rex::Socket::Tcp)
|
t.extend(Rex::Socket::Tcp)
|
||||||
t.context = self.context
|
t.context = self.context
|
||||||
|
|
||||||
pn = t.getpeername
|
pn = t.getpeername_as_array
|
||||||
|
|
||||||
# We hit a "getpeername(2)" from Ruby
|
# We hit a "getpeername(2)" from Ruby
|
||||||
return nil unless pn
|
return nil unless pn
|
||||||
|
|
|
@ -110,7 +110,13 @@ Gem::Specification.new do |spec|
|
||||||
spec.add_runtime_dependency 'rex-zip'
|
spec.add_runtime_dependency 'rex-zip'
|
||||||
# Library for parsing offline Windows Registry files
|
# Library for parsing offline Windows Registry files
|
||||||
spec.add_runtime_dependency 'rex-registry'
|
spec.add_runtime_dependency 'rex-registry'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Protocol Libraries
|
||||||
|
#
|
||||||
|
spec.add_runtime_dependency 'net-ssh'
|
||||||
|
|
||||||
|
|
||||||
# rb-readline doesn't work with Ruby Installer due to error with Fiddle:
|
# rb-readline doesn't work with Ruby Installer due to error with Fiddle:
|
||||||
# NoMethodError undefined method `dlopen' for Fiddle:Module
|
# NoMethodError undefined method `dlopen' for Fiddle:Module
|
||||||
unless Gem.win_platform?
|
unless Gem.win_platform?
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'net/ssh'
|
||||||
|
require 'rex/socket/ssh_factory'
|
||||||
|
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Auxiliary
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include Msf::Auxiliary::Scanner
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(
|
||||||
|
'Name' => 'SSH Proxy Test',
|
||||||
|
'Description' => %q{
|
||||||
|
This module will test ssh logins on a range of machines and
|
||||||
|
report successful logins. If you have loaded a database plugin
|
||||||
|
and connected to a database this module will record successful
|
||||||
|
logins and hosts so you can track your access.
|
||||||
|
},
|
||||||
|
'Author' => ['todb'],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '1999-0502'] # Weak password
|
||||||
|
],
|
||||||
|
'License' => MSF_LICENSE
|
||||||
|
)
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
Opt::RPORT(22)
|
||||||
|
], self.class
|
||||||
|
)
|
||||||
|
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
Opt::Proxies,
|
||||||
|
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
|
||||||
|
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def run_host(ip)
|
||||||
|
factory = Rex::Socket::SSHFactory.new(framework,self, datastore['Proxies'])
|
||||||
|
# socket = factory.open(ip,datastore['RPORT'])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -122,15 +122,17 @@ RSpec.describe Metasploit::Framework::LoginScanner::SSH do
|
||||||
|
|
||||||
context 'with a password' do
|
context 'with a password' do
|
||||||
it 'calls Net::SSH with the correct arguments' do
|
it 'calls Net::SSH with the correct arguments' do
|
||||||
|
factory = Rex::Socket::SSHFactory.new(nil,nil,nil)
|
||||||
opt_hash = {
|
opt_hash = {
|
||||||
:auth_methods => ['password','keyboard-interactive'],
|
|
||||||
:port => ssh_scanner.port,
|
:port => ssh_scanner.port,
|
||||||
:disable_agent => true,
|
:use_agent => false,
|
||||||
:password => private,
|
|
||||||
:config => false,
|
:config => false,
|
||||||
:verbose => ssh_scanner.verbosity,
|
:verbose => ssh_scanner.verbosity,
|
||||||
:proxies => nil
|
:proxy => factory,
|
||||||
|
:auth_methods => ['password','keyboard-interactive'],
|
||||||
|
:password => private,
|
||||||
}
|
}
|
||||||
|
allow(Rex::Socket::SSHFactory).to receive(:new).and_return factory
|
||||||
expect(Net::SSH).to receive(:start).with(
|
expect(Net::SSH).to receive(:start).with(
|
||||||
ssh_scanner.host,
|
ssh_scanner.host,
|
||||||
public,
|
public,
|
||||||
|
@ -142,15 +144,17 @@ RSpec.describe Metasploit::Framework::LoginScanner::SSH do
|
||||||
|
|
||||||
context 'with a key' do
|
context 'with a key' do
|
||||||
it 'calls Net::SSH with the correct arguments' do
|
it 'calls Net::SSH with the correct arguments' do
|
||||||
|
factory = Rex::Socket::SSHFactory.new(nil,nil,nil)
|
||||||
opt_hash = {
|
opt_hash = {
|
||||||
:auth_methods => ['publickey'],
|
:auth_methods => ['publickey'],
|
||||||
:port => ssh_scanner.port,
|
:port => ssh_scanner.port,
|
||||||
:disable_agent => true,
|
:use_agent => false,
|
||||||
:key_data => key,
|
:key_data => key,
|
||||||
:config => false,
|
:config => false,
|
||||||
:verbose => ssh_scanner.verbosity,
|
:verbose => ssh_scanner.verbosity,
|
||||||
:proxies => nil
|
:proxy => factory
|
||||||
}
|
}
|
||||||
|
allow(Rex::Socket::SSHFactory).to receive(:new).and_return factory
|
||||||
expect(Net::SSH).to receive(:start).with(
|
expect(Net::SSH).to receive(:start).with(
|
||||||
ssh_scanner.host,
|
ssh_scanner.host,
|
||||||
public,
|
public,
|
||||||
|
|
Loading…
Reference in New Issue