Skip to content

Commit a745c3a

Browse files
committed
metasploit_data_models 0.3.0 installed in gemcache
1 parent 558b8b0 commit a745c3a

File tree

93 files changed

+2897
-1998
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+2897
-1998
lines changed

lib/gemcache/ruby/1.9.1/bin/mdm_console

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@ require 'rubygems'
1010

1111
version = ">= 0"
1212

13-
if ARGV.first
14-
str = ARGV.first
15-
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
16-
if str =~ /\A_(.*)_\z/
17-
version = $1
18-
ARGV.shift
19-
end
13+
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
14+
version = $1
15+
ARGV.shift
2016
end
2117

2218
gem 'metasploit_data_models', version
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1-
.rvmrc
1+
# bundler configuration
2+
.bundle
3+
# Mac OS X folder attributes
24
.DS_Store
5+
# built gems
36
*.gem
4-
.bundle
7+
# Rubymine project configuration
8+
.idea
9+
# Don't check in rvmrc since this is a gem
10+
.rvmrc
11+
# Installed gem versions. Not stored for the same reasons as .rvmrc
512
Gemfile.lock
13+
# Packaging directory for builds
614
pkg/*
15+
# Database configuration (with passwords) for specs
16+
spec/dummy/config/database.yml
17+
# logs
18+
*.log

lib/gemcache/ruby/1.9.1/gems/metasploit_data_models-0.3.0/Gemfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@ source "http://rubygems.org"
22

33
# Specify your gem's dependencies in metasploit_data_models.gemspec
44
gemspec
5+
6+
group :test do
7+
# rails is only used for testing with a dummy application in spec/dummy
8+
gem 'rails'
9+
gem 'rspec-rails'
10+
end

lib/gemcache/ruby/1.9.1/gems/metasploit_data_models-0.3.0/README.md

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,48 @@ __MetasploitDataModels__ exists to do several key things:
1717

1818
### Rails
1919

20-
In a Rails application we simply include the ActiveRecord mixins directly, usually inside models with similar names.
21-
22-
### MSF
23-
When MetasploitDataModels is included by MSF, the gem dynamically creates
24-
ActiveRecord model classes.
25-
26-
Both of these behaviors are based on the assumption that the files in
27-
__lib/metasploit_data_models/active_record_models__, though implemented here as
28-
mixins, actually represent the basic ActiveRecord model structure that both Metasploit Framework and Metasploit Pro use.
20+
In a Rails application, MetasploitDataModels acts a
21+
[Rails Engine](http://edgeapi.rubyonrails.org/classes/Rails/Engine.html) and the models are available to application
22+
just as if they were defined under app/models. If your Rails appliation needs to modify the models, this can be done
23+
using ActiveSupport.on_load hooks in initializers. The block passed to on_load hook is evaluated in the context of the
24+
model class, so defining method and including modules will work just like reopeninng the class, but
25+
ActiveSupport.on_load ensures that the monkey patches will work after reloading in development mode. Each class has a
26+
different on_load name, which is just the class name converted to an underscored symbol, so Mdm::ApiKey runs the
27+
:mdm_api_key load hooks, etc.
28+
29+
# Gemfile
30+
gem :metasploiit_data_models, :git => git://github.com/rapid7/metasploit_data_models.git, :tag => 'v0.3.0'
31+
32+
# config/initializers/metasploit_data_models.rb
33+
ActiveSupport.on_load(:mdm_api_key) do
34+
# Returns the String obfuscated token for display. Meant to avoid CSRF
35+
# api-key stealing attackes.
36+
def obfuscated_token
37+
token[0..3] + "****************************"
38+
end
39+
end
40+
41+
### Metasploit Framework
42+
43+
In Metasploit Framework, `MetasploitDataModels.require_models` is called by the `Msf::DbManager` to use the data models
44+
only if the user wants to use the database.
2945

3046
### Elsewhere
3147

32-
__NOTE: This isn't in RubyGems yet. Using a Gemfile entry pointing to this repo (i.e., using [Bundler](http://gembundler.com)) is the suggested option for now.__
48+
__NOTE: This isn't in RubyGems yet. Using a Gemfile entry pointing to this repo (i.e., using
49+
[Bundler](http://gembundler.com)) is the suggested option for now.__
3350

51+
Usage outside of Rapid7 is still alpha, as reflected in the pre-1.0.0 version, and we're not making many promises. That
52+
being said, usage is easy:
3453

35-
Usage outside of Rapid7 is still alpha, and we're not making many promises. That being said, usage is easy:
36-
37-
```ruby
38-
connection_info = YAML.load_file("path/to/rails-style/db_config_file")
39-
ActiveRecord::Base.establish_connection(connection_info['development'])
40-
include MetasploitDataModels
41-
MetasploitDataModels.create_and_load_ar_classes
42-
```
54+
connection_info = YAML.load_file("path/to/rails-style/db_config_file")
55+
ActiveRecord::Base.establish_connection(connection_info['development'])
56+
MetasploitDataModels.require_models
4357

4458
Basically you need to do the following things:
4559

4660
1. Establish an ActiveRecord connection. A Rails __config/database.yml__ is ideal for this.
47-
2. Include the MetasploitDataModels module.
48-
3. Call the class method that builds the AR models into the Mdm namespace( __MetasploitDataModels.create_and_load_ar_classes__ ).
61+
2. `MetasploitDataModels.require_models`
4962

5063

5164
## Developer Info
@@ -57,19 +70,3 @@ Give it a path to a working MSF database.yml file for full
5770
ActiveRecord-based access to your data.
5871

5972
__Note:__ "development" mode is hardcoded into the console currently.
60-
61-
### ActiveRecord::ConnectionError issues
62-
Because the gem is defining mixins, there can be no knowledge of the
63-
specifics of any "current" ActiveRecord connection. But if ActiveRecord
64-
encounters something in a child class that would require knowledge of
65-
the connection adapter (e.g. the use of an RDBMS-specific function in
66-
a named scope's "WHERE" clause), it will check to see if the adapter
67-
supports it and then throw an exception when the connection object
68-
(which provides the adapter) is nil.
69-
70-
This means that, for all but the most trivial cases, you need to use Arel
71-
versions of queries instead of ones utilizing straight SQL.
72-
73-
You'll encounter this sometimes if you do dev work on this gem. A good
74-
rule of thumb: anything that goes into the class_eval block must be able
75-
to work without knowledge of the AR connection adapter type.
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
require "bundler/gem_tasks"
1+
require 'bundler/gem_tasks'
2+
require 'rspec/core/rake_task'
3+
4+
RSpec::Core::RakeTask.new(:spec)
5+
6+
task :default => :spec
7+
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
1-
module MetasploitDataModels::ActiveRecordModels::ApiKey
2-
def self.included(base)
3-
base.class_eval {
1+
class Mdm::ApiKey < ActiveRecord::Base
2+
#
3+
# Validators
4+
#
45

5-
validate do |key|
6-
lic = License.get
6+
validate :supports_api
7+
validates :token, :presence => true, :length => { :minimum => 8 }
78

8-
if lic and not lic.supports_api?
9-
key.errors[:unsupported_product] = " - this product does not support API access"
10-
end
9+
protected
1110

12-
if key.token.to_s.empty?
13-
key.errors[:blank_token] = " - the specified authentication token is empty"
14-
end
11+
def supports_api
12+
license = License.get
1513

16-
if key.token.to_s.length < 8
17-
key.errors[:token_too_short] = " - the specified authentication token must be at least 8 characters long"
18-
end
19-
end
20-
}
14+
if license and not license.supports_api?
15+
errors[:license] = " - this product does not support API access"
16+
end
2117
end
18+
19+
ActiveSupport.run_load_hooks(:mdm_api_key, self)
2220
end
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
module MetasploitDataModels::ActiveRecordModels::Client
2-
def self.included(base)
3-
base.class_eval {
4-
belongs_to :host, :class_name => "Mdm::Host"
5-
belongs_to :campaign, :class_name => "Campaign"
6-
}
7-
end
1+
class Mdm::Client < ActiveRecord::Base
2+
#
3+
# Relations
4+
#
5+
belongs_to :campaign, :class_name => 'Mdm::Campaign'
6+
belongs_to :host, :class_name => 'Mdm::Host'
7+
8+
ActiveSupport.run_load_hooks(:mdm_client, self)
89
end
Lines changed: 69 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,80 @@
1-
module MetasploitDataModels::ActiveRecordModels::Cred
2-
def self.included(base)
3-
base.class_eval{
4-
belongs_to :service, :class_name => "Mdm::Service"
1+
class Mdm::Cred < ActiveRecord::Base
2+
#
3+
# CONSTANTS
4+
#
5+
KEY_ID_REGEX = /([0-9a-fA-F:]{47})/
6+
PTYPES = {
7+
'read/write password' => 'password_rw',
8+
'read-only password' => 'password_ro',
9+
'SMB hash' => 'smb_hash',
10+
'SSH private key' => 'ssh_key',
11+
'SSH public key' => 'ssh_pubkey'
12+
}
513

6-
unless defined? PTYPES
7-
const_def =<<-CONST_DEF
8-
PTYPES = {
9-
"read/write password" => "password_rw",
10-
"read-only password" => "password_ro",
11-
"SMB hash" => "smb_hash",
12-
"SSH private key" => "ssh_key",
13-
"SSH public key" => "ssh_pubkey"
14-
}
15-
CONST_DEF
16-
eval(const_def)
17-
end
14+
#
15+
# Relations
16+
#
17+
belongs_to :service, :class_name => "Mdm::Service"
1818

19-
eval("KEY_ID_REGEX = /([0-9a-fA-F:]{47})/") unless defined?(KEY_ID_REGEX) # Could be more strict
19+
def ptype_human
20+
humanized = PTYPES.select do |k, v|
21+
v == ptype
22+
end.keys[0]
2023

21-
def ptype_human
22-
humanized = PTYPES.select do |k, v|
23-
v == ptype
24-
end.keys[0]
25-
26-
humanized ? humanized : ptype
27-
end
24+
humanized ? humanized : ptype
25+
end
2826

29-
# Returns its workspace
30-
def workspace
31-
self.service.host.workspace
32-
end
27+
# Returns its key id. If this is not an ssh-type key, returns nil.
28+
def ssh_key_id
29+
return nil unless self.ptype =~ /^ssh_/
30+
return nil unless self.proof =~ KEY_ID_REGEX
31+
$1.downcase # Can't run into NilClass problems.
32+
end
3333

34-
# Returns its key id. If this is not an ssh-type key, returns nil.
35-
def ssh_key_id
36-
return nil unless self.ptype =~ /^ssh_/
37-
return nil unless self.proof =~ KEY_ID_REGEX
38-
$1.downcase # Can't run into NilClass problems.
39-
end
34+
def ssh_key_matches?(other_cred)
35+
return false unless other_cred.kind_of? self.class
36+
return false unless self.ptype == other_cred.ptype
37+
case self.ptype
38+
when "ssh_key"
39+
matches = self.ssh_private_keys
40+
when "ssh_pubkey"
41+
matches = self.ssh_public_keys
42+
else
43+
false
44+
end
45+
matches.include?(self) and matches.include?(other_cred)
46+
end
4047

41-
# Returns all private keys with matching key ids, including itself
42-
# If this is not an ssh-type key, always returns an empty array.
43-
def ssh_private_keys
44-
return [] unless self.ssh_key_id
45-
matches = self.class.all(:conditions => ["creds.ptype = ? AND creds.proof ILIKE ?", "ssh_key", "%#{self.ssh_key_id}%"])
46-
matches.select {|c| c.workspace == self.workspace}
47-
end
48+
# Returns all keys with matching key ids, including itself
49+
# If this is not an ssh-type key, always returns an empty array.
50+
def ssh_keys
51+
(self.ssh_private_keys | self.ssh_public_keys)
52+
end
4853

49-
# Returns all public keys with matching key ids, including itself
50-
# If this is not an ssh-type key, always returns an empty array.
51-
def ssh_public_keys
52-
return [] unless self.ssh_key_id
53-
matches = self.class.all(:conditions => ["creds.ptype = ? AND creds.proof ILIKE ?", "ssh_pubkey", "%#{self.ssh_key_id}%"])
54-
matches.select {|c| c.workspace == self.workspace}
55-
end
54+
# Returns all private keys with matching key ids, including itself
55+
# If this is not an ssh-type key, always returns an empty array.
56+
def ssh_private_keys
57+
return [] unless self.ssh_key_id
58+
matches = self.class.all(
59+
:conditions => ["creds.ptype = ? AND creds.proof ILIKE ?", "ssh_key", "%#{self.ssh_key_id}%"]
60+
)
61+
matches.select {|c| c.workspace == self.workspace}
62+
end
5663

57-
# Returns all keys with matching key ids, including itself
58-
# If this is not an ssh-type key, always returns an empty array.
59-
def ssh_keys
60-
(self.ssh_private_keys | self.ssh_public_keys)
61-
end
64+
# Returns all public keys with matching key ids, including itself
65+
# If this is not an ssh-type key, always returns an empty array.
66+
def ssh_public_keys
67+
return [] unless self.ssh_key_id
68+
matches = self.class.all(
69+
:conditions => ["creds.ptype = ? AND creds.proof ILIKE ?", "ssh_pubkey", "%#{self.ssh_key_id}%"]
70+
)
71+
matches.select {|c| c.workspace == self.workspace}
72+
end
6273

63-
def ssh_key_matches?(other_cred)
64-
return false unless other_cred.kind_of? self.class
65-
return false unless self.ptype == other_cred.ptype
66-
case self.ptype
67-
when "ssh_key"
68-
matches = self.ssh_private_keys
69-
when "ssh_pubkey"
70-
matches = self.ssh_public_keys
71-
else
72-
false
73-
end
74-
matches.include?(self) and matches.include?(other_cred)
75-
end
76-
}
74+
# Returns its workspace
75+
def workspace
76+
self.service.host.workspace
7777
end
78+
79+
ActiveSupport.run_load_hooks(:mdm_cred, self)
7880
end
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
module MetasploitDataModels::ActiveRecordModels::CredFile
2-
def self.included(base)
3-
base.class_eval{
1+
class Mdm::CredFile < ActiveRecord::Base
2+
#
3+
# Relations
4+
#
5+
belongs_to :workspace, :class_name => 'Mdm::Workspace'
46

5-
belongs_to :workspace, :class_name => "Mdm::Workspace"
6-
}
7-
end
7+
ActiveSupport.run_load_hooks(:mdm_cred_file, self)
88
end

0 commit comments

Comments
 (0)