meterpreter console (shell)
git-svn-id: file:///home/svn/framework3/trunk@5027 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
49e63b95b5
commit
883f33759b
|
@ -10,109 +10,18 @@ module Msf
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
class Shell < Msf::Ui::Gtk2::SkeletonConsole
|
class Shell < Msf::Ui::Gtk2::SkeletonConsole
|
||||||
module InteractiveChannel
|
|
||||||
|
|
||||||
include Rex::Ui::Interactive
|
|
||||||
|
|
||||||
#
|
|
||||||
# Interacts with self.
|
|
||||||
#
|
|
||||||
def _interact
|
|
||||||
# If the channel has a left-side socket, then we can interact with it.
|
|
||||||
if (self.lsock)
|
|
||||||
self.interactive(true)
|
|
||||||
|
|
||||||
interact_stream(self)
|
|
||||||
|
|
||||||
self.interactive(false)
|
|
||||||
else
|
|
||||||
print_error("Channel #{self.cid} does not support interaction.")
|
|
||||||
|
|
||||||
self.interacting = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Called when an interrupt is sent.
|
|
||||||
#
|
|
||||||
def _interrupt
|
|
||||||
prompt_yesno("Terminate channel #{self.cid}?")
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Suspends interaction with the channel.
|
|
||||||
#
|
|
||||||
def _suspend
|
|
||||||
# Ask the user if they would like to background the session
|
|
||||||
if (prompt_yesno("Background channel #{self.cid}?") == true)
|
|
||||||
self.interactive(false)
|
|
||||||
|
|
||||||
self.interacting = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Closes the channel like it aint no thang.
|
|
||||||
#
|
|
||||||
def _interact_complete
|
|
||||||
begin
|
|
||||||
self.interactive(false)
|
|
||||||
|
|
||||||
self.close
|
|
||||||
rescue IOError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Reads data from local input and writes it remotely.
|
|
||||||
#
|
|
||||||
def _stream_read_local_write_remote(channel)
|
|
||||||
data = user_input.gets
|
|
||||||
|
|
||||||
self.write(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Reads from the channel and writes locally.
|
|
||||||
#
|
|
||||||
def _stream_read_remote_write_local(channel)
|
|
||||||
data = self.lsock.sysread(16384)
|
|
||||||
|
|
||||||
user_output.print(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Returns the remote file descriptor to select on
|
|
||||||
#
|
|
||||||
def _remote_fd(stream)
|
|
||||||
self.lsock
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Pipe
|
|
||||||
#
|
|
||||||
# Interacts with the supplied channel.
|
|
||||||
#
|
|
||||||
def interact_with_channel(channel, pipe)
|
|
||||||
channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
|
|
||||||
@t_run = Thread.new do
|
|
||||||
channel.interact(pipe, pipe)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(iter)
|
def initialize(iter)
|
||||||
session = iter[3]
|
session = iter[3]
|
||||||
super(iter)
|
super(iter)
|
||||||
|
|
||||||
if (session.type == "meterpreter")
|
if (session.type == "meterpreter")
|
||||||
|
require 'msf/ui/gtk2/console/interactive_channel.rb'
|
||||||
|
|
||||||
self.type = "shell"
|
self.type = "shell"
|
||||||
|
|
||||||
# TODO: use the API instead writing into the pipe
|
|
||||||
meterconsole = Rex::Post::Meterpreter::Ui::Console.new(session)
|
meterconsole = Rex::Post::Meterpreter::Ui::Console.new(session)
|
||||||
meterconsole.extend(Pipe)
|
meterconsole.extend(Pipe)
|
||||||
#send_cmd("execute -f cmd.exe -i -H")
|
|
||||||
cmd_exec = "cmd.exe"
|
cmd_exec = "cmd.exe"
|
||||||
cmd_args = nil
|
cmd_args = nil
|
||||||
channelized = true
|
channelized = true
|
||||||
|
@ -124,24 +33,25 @@ module Msf
|
||||||
'Hidden' => hidden,
|
'Hidden' => hidden,
|
||||||
'InMemory' => (from_mem) ? dummy_exec : nil)
|
'InMemory' => (from_mem) ? dummy_exec : nil)
|
||||||
|
|
||||||
|
# Create a new pipe to not use the pipe class
|
||||||
@pipe = Rex::IO::BidirectionalPipe.new
|
@pipe = Rex::IO::BidirectionalPipe.new
|
||||||
|
|
||||||
# Create a subscriber with a callback for the UI
|
# Create a subscriber with a callback for the UI
|
||||||
@pipe.create_subscriber_proc() do |data|
|
@pipe.create_subscriber_proc() do |data|
|
||||||
self.insert_text(Rex::Text.to_utf8(data))
|
self.insert_text(Rex::Text.to_utf8(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Interact with the supplied channel
|
||||||
meterconsole.interact_with_channel(p.channel, @pipe)
|
meterconsole.interact_with_channel(p.channel, @pipe)
|
||||||
|
|
||||||
end
|
end
|
||||||
#
|
end
|
||||||
# Send command to bidirectionnal_pipe
|
|
||||||
#
|
|
||||||
def send_cmd(cmd)
|
|
||||||
# What time is it ?
|
|
||||||
# update_access
|
|
||||||
|
|
||||||
# Write the command plus a newline to the input
|
#
|
||||||
@pipe.write_input(cmd + "\n")
|
# Send command to bidirectionnal_pipe
|
||||||
end
|
#
|
||||||
|
def send_cmd(cmd)
|
||||||
|
# Write the command plus a newline to the input
|
||||||
|
@pipe.write_input(cmd + "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
end # Console::Shell
|
end # Console::Shell
|
||||||
|
@ -152,16 +62,39 @@ module Msf
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
class Meterpreter < Msf::Ui::Gtk2::SkeletonConsole
|
class Meterpreter < Msf::Ui::Gtk2::SkeletonConsole
|
||||||
|
#require 'msf/ui/gtk2/console/interactive_channel.rb'
|
||||||
|
|
||||||
def initialize(iter)
|
def initialize(iter)
|
||||||
# meterpreter client
|
# meterpreter client
|
||||||
client = iter[3]
|
session = iter[3]
|
||||||
|
|
||||||
# call the parent
|
# call the parent
|
||||||
super(iter)
|
super(iter)
|
||||||
|
|
||||||
# TODO: use the API instead writing into the pipe
|
meterconsole = Rex::Post::Meterpreter::Ui::Console.new(session)
|
||||||
send_cmd("help")
|
# meterconsole.extend(Pipe)
|
||||||
|
|
||||||
|
# Create a new pipe to not use the pipe class
|
||||||
|
@pipe = Rex::IO::BidirectionalPipe.new
|
||||||
|
|
||||||
|
# Create a subscriber with a callback for the UI
|
||||||
|
@pipe.create_subscriber_proc() do |data|
|
||||||
|
self.insert_text(Rex::Text.to_utf8(data))
|
||||||
|
end
|
||||||
|
|
||||||
|
meterconsole.init_ui(@pipe, @pipe)
|
||||||
|
|
||||||
|
@t_run = Thread.new do
|
||||||
|
meterconsole.interact { self.interacting != true }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Send command to bidirectionnal_pipe
|
||||||
|
#
|
||||||
|
def send_cmd(cmd)
|
||||||
|
# Write the command plus a newline to the input
|
||||||
|
@pipe.write_input(cmd + "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
end # Console::Meterpreter
|
end # Console::Meterpreter
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
module Msf
|
||||||
|
module Ui
|
||||||
|
module Gtk2
|
||||||
|
|
||||||
|
module InteractiveChannel
|
||||||
|
|
||||||
|
include Rex::Ui::Interactive
|
||||||
|
|
||||||
|
#
|
||||||
|
# Interacts with self.
|
||||||
|
#
|
||||||
|
def _interact
|
||||||
|
# If the channel has a left-side socket, then we can interact with it.
|
||||||
|
if (self.lsock)
|
||||||
|
self.interactive(true)
|
||||||
|
|
||||||
|
interact_stream(self)
|
||||||
|
|
||||||
|
self.interactive(false)
|
||||||
|
else
|
||||||
|
print_error("Channel #{self.cid} does not support interaction.")
|
||||||
|
|
||||||
|
self.interacting = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Called when an interrupt is sent.
|
||||||
|
#
|
||||||
|
def _interrupt
|
||||||
|
prompt_yesno("Terminate channel #{self.cid}?")
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Suspends interaction with the channel.
|
||||||
|
#
|
||||||
|
def _suspend
|
||||||
|
# Ask the user if they would like to background the session
|
||||||
|
if (prompt_yesno("Background channel #{self.cid}?") == true)
|
||||||
|
self.interactive(false)
|
||||||
|
|
||||||
|
self.interacting = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Closes the channel like it aint no thang.
|
||||||
|
#
|
||||||
|
def _interact_complete
|
||||||
|
begin
|
||||||
|
self.interactive(false)
|
||||||
|
|
||||||
|
self.close
|
||||||
|
rescue IOError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Reads data from local input and writes it remotely.
|
||||||
|
#
|
||||||
|
def _stream_read_local_write_remote(channel)
|
||||||
|
data = user_input.gets
|
||||||
|
|
||||||
|
self.write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Reads from the channel and writes locally.
|
||||||
|
#
|
||||||
|
def _stream_read_remote_write_local(channel)
|
||||||
|
data = self.lsock.sysread(16384)
|
||||||
|
|
||||||
|
user_output.print(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the remote file descriptor to select on
|
||||||
|
#
|
||||||
|
def _remote_fd(stream)
|
||||||
|
self.lsock
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pipe
|
||||||
|
#
|
||||||
|
# Interacts with the supplied channel.
|
||||||
|
#
|
||||||
|
def interact_with_channel(channel, pipe)
|
||||||
|
channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
|
||||||
|
@t_run = Thread.new do
|
||||||
|
channel.interact(pipe, pipe)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue