Module: FIDIUS::EvasionDB

Defined in:
lib/evasion-db/base.rb,
lib/db/db-install.rb,
lib/fidius-evasiondb.rb,
lib/evasion-db/version.rb,
lib/evasion-db/knowledge.rb,
lib/evasion-db/log_matches_helper.rb,
lib/evasion-db/recorders/recorders.rb,
lib/evasion-db/idmef-fetchers/fetchers.rb,
lib/evasion-db/rule_fetchers/rule_fetchers.rb,
lib/evasion-db/rule_fetchers/snort/lib/snort.rb,
lib/evasion-db/recorders/msf-recorder/lib/msf-recorder.rb,
lib/evasion-db/idmef-fetchers/test-fetcher/lib/test_fetcher.rb,
lib/evasion-db/idmef-fetchers/prelude-db/lib/prelude_event_fetcher.rb

Overview

EvasionDB is a knowledge database which provides information about idmef-events which are thrown by an ids like prelude. You can use this gem in two ways. One way is to generate knowledge via running exploits whithin metasploit. The other way is require this gem and query existing knowledge estimate how loud an exploit might be.

Defined Under Namespace

Modules: Knowledge, LogMatchesHelper, MsfRecorder, PreludeEventFetcher, SnortRuleFetcher, TestFetcher Classes: Fetcher, Recorder, RuleFetcher

Constant Summary collapse

GEM_BASE =
File.expand_path('..', __FILE__)
VERSION =
"0.0.2"
@@yml_config =

stores content of configuration yml

nil
@@current_fetcher =
nil
@@current_recorder =
nil
@@current_rule_fetcher =
nil

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.config(yml_file) ⇒ Object

Configures EvasionDB.

sample config can be created with ‘fidius-evasiondb -e’

Parameters:

  • path (String)

    to an yml-file containing db-connection settings for ids_db and evasion_db



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/evasion-db/base.rb', line 20

def self.config(yml_file)
  if yml_file.class == String
    raise "#{yml_file} does not exist" unless File.exists? File.expand_path(yml_file)
    @@yml_config = YAML.load(File.read(yml_file))
    evasion_db = @@yml_config['evasion_db']
  elsif yml_file.class == Hash
    # also react on connection settings given as hash
    evasion_db = yml_file
  else
    raise "please input string or hash"
  end
  unless evasion_db
    raise "no evasion_db part found in file"
  else
    #self.load_db_adapter(evasion_db['adapter'])
    FIDIUS::EvasionDB::Knowledge::Connection.establish_connection evasion_db
    #require File.join(GEM_BASE, 'evasion-db', 'postgres_patch.rb')
    FIDIUS::EvasionDB::Knowledge::Connection.connection
  end
end

.current_fetcherObject

Returns the current recorder

Raises:

  • RuntimeError if fetcher was not set

See Also:

  • #use_fetcher


89
90
91
92
# File 'lib/evasion-db/base.rb', line 89

def self.current_fetcher
  raise "no fetcher set. Use FIDIUS::EvasionDB.use_fetcher" unless @@current_fetcher
  @@current_fetcher
end

.current_recorderObject

Returns the current recorder

Raises:

  • RuntimeError if recorder was not set

See Also:

  • #use_recorder


80
81
82
83
# File 'lib/evasion-db/base.rb', line 80

def self.current_recorder
  raise "no recorder set. Use FIDIUS::EvasionDB.use_recorder" unless @@current_recorder
  @@current_recorder
end

.current_rule_fetcherObject

Returns the current rule fetcher

See Also:

  • #use_rule_fetcher


98
99
100
# File 'lib/evasion-db/base.rb', line 98

def self.current_rule_fetcher
  @@current_rule_fetcher
end

.fetcher(name, &block) ⇒ Object



3
4
5
# File 'lib/evasion-db/idmef-fetchers/fetchers.rb', line 3

def self.fetcher(name,&block)
  FIDIUS::EvasionDB::Fetcher.new(name,&block)
end

.install_fetchersObject



7
8
9
10
11
12
# File 'lib/evasion-db/idmef-fetchers/fetchers.rb', line 7

def self.install_fetchers
  $logger.debug "installing fetchers"
  FIDIUS::EvasionDB::Fetcher.all.each do |fetcher|
    fetcher.run_install
  end
end

.install_recordersObject



7
8
9
10
11
12
# File 'lib/evasion-db/recorders/recorders.rb', line 7

def self.install_recorders
  $logger.debug "installing recoders"
  FIDIUS::EvasionDB::Recorder.all.each do |recorder|
    recorder.run_install
  end
end

.install_rule_fetchersObject



7
8
9
10
11
12
# File 'lib/evasion-db/rule_fetchers/rule_fetchers.rb', line 7

def self.install_rule_fetchers
  $logger.debug "installing rule fetchers"
  FIDIUS::EvasionDB::RuleFetcher.all.each do |fetcher|
    fetcher.run_install
  end
end

.migrate(migrations_path, db_config_path) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/db/db-install.rb', line 8

def self.migrate migrations_path, db_config_path
  @CFG_D = db_config_path

  self.connection_data

  begin
    self.drop_database @connection_data['evasion_db']
  rescue
    puts "DB drop: Could not find database #{@connection_data['database']}"
  end

  self.create_database @connection_data['evasion_db']

  self.with_db do
    ActiveRecord::Migrator.migrate(migrations_path, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  end
end

.recorder(name, &block) ⇒ Object



3
4
5
# File 'lib/evasion-db/recorders/recorders.rb', line 3

def self.recorder(name,&block)
  FIDIUS::EvasionDB::Recorder.new(name,&block)
end

.rule_fetcher(name, &block) ⇒ Object



3
4
5
# File 'lib/evasion-db/rule_fetchers/rule_fetchers.rb', line 3

def self.rule_fetcher(name,&block)
  FIDIUS::EvasionDB::RuleFetcher.new(name,&block)
end

.use_fetcher(fetcher_name) ⇒ Object

Use a given fetcher. Fetchers are used to fetch idmef-events after an exploit is finished. Currently there is only the Prelude-Fetcher available. Use it by setting FIDIUS::EvasionDB.use_fetcher “PreludeDB”

Parameters:

  • fetcher_name (String)

Raises:

  • RuntimeError if fetcher not found



57
58
59
60
61
62
# File 'lib/evasion-db/base.rb', line 57

def self.use_fetcher(fetcher_name)
  raise "not configured. use FIDIUS::EvasionDB.config first" unless @@yml_config
  @@current_fetcher = Fetcher.by_name(fetcher_name)
  raise "fetcher #{fetcher_name} not found" unless @@current_fetcher    
  @@current_fetcher.config(@@yml_config)
end

.use_recoder(recorder_name) ⇒ Object

Use a given recorder. Recorders are used to log packets while an exploit is running. Currently there is only the msf-recorder available. Use it by setting FIDIUS::EvasionDB.use_recorder “Msf-Recorder”

Parameters:

  • recordername (String)

Raises:

  • RuntimeError if recorder not found



46
47
48
49
50
# File 'lib/evasion-db/base.rb', line 46

def self.use_recoder(recorder_name)
  raise "not configured. use FIDIUS::EvasionDB.config first" unless @@yml_config
  @@current_recorder = Recorder.by_name(recorder_name)
  raise "recorder #{recorder_name} not found" unless @@current_recorder
end

.use_rule_fetcher(rule_fetcher_name) ⇒ Object

Use a given rule-fetcher. RuleFetchers are used to fetch rules from an rule based ids. Currently there is only the Fetcher for a Snort IDS.

Parameters:

  • rule_fetcher_name (String)

Raises:

  • RuntimeError if fetcher not found



69
70
71
72
73
74
# File 'lib/evasion-db/base.rb', line 69

def self.use_rule_fetcher(rule_fetcher_name)
  raise "not configured. use FIDIUS::EvasionDB.config first" unless @@yml_config
  @@current_rule_fetcher = RuleFetcher.by_name(rule_fetcher_name)
  raise "rule-fetcher #{rule_fetcher_name} not found" unless @@current_rule_fetcher    
  @@current_rule_fetcher.config(@@yml_config)
end

Instance Method Details

#connection_dataObject



26
27
28
# File 'lib/db/db-install.rb', line 26

def connection_data
  @connection_data ||= YAML.load_file("#{@CFG_D}/database.yml")
end

#create_database(config) ⇒ Object

dito



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/db/db-install.rb', line 58

def create_database(config)
  case config['adapter']

  when /mysql/
    require 'mysql'
    @charset   = ENV['CHARSET']   || 'utf8'
    @collation = ENV['COLLATION'] || 'utf8_unicode_ci'
    creation_options = {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)}
    begin
      error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
    rescue
      error_class = Mysql::Error
    end
    access_denied_error = 1045
    begin
      ActiveRecord::Base.establish_connection(config.merge('database' => nil))
      ActiveRecord::Base.connection.create_database(config['database'], creation_options)
      ActiveRecord::Base.establish_connection(config)
    rescue error_class => sqlerr
      if sqlerr.errno == access_denied_error
        print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
      root_password = $stdin.gets.strip
        grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
        "TO '#{config['username']}'@'localhost' " \
        "IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
        ActiveRecord::Base.establish_connection(config.merge('database' => nil, 'username' => 'root', 'password' => root_password))
        ActiveRecord::Base.connection.create_database(config['database'], creation_options)
        ActiveRecord::Base.connection.execute grant_statement
        ActiveRecord::Base.establish_connection(config)
      else
        $stderr.puts sqlerr.error
        $stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation}"
        $stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
      end
    end
  when 'postgresql'
    @encoding = config['encoding'] || ENV['CHARSET'] || 'utf8'
    begin
      ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
      ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
      ActiveRecord::Base.establish_connection(config)
    rescue Exception => e
      $stderr.puts e, *(e.backtrace)
      $stderr.puts "Couldn't create database for #{config.inspect}"
    end
  end

end

#drop_database(config) ⇒ Object

copied and modified activerecord-3.0.4/lib/active_record/railties/database.rake



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/db/db-install.rb', line 44

def drop_database(config)
  case config['adapter']
  when /sqlite/
    FileUtils.rm (config['database'])
  when /mysql/
    ActiveRecord::Base.establish_connection(config)
    ActiveRecord::Base.connection.drop_database config['database']
  when 'postgresql'
    ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
    ActiveRecord::Base.connection.drop_database config['database']
  end
end

#with_db(&block) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/db/db-install.rb', line 30

def with_db &block
  begin
    ActiveRecord::Base.establish_connection(connection_data['evasion_db'])
    ActiveRecord::Base.logger = Logger.new(STDOUT)
    ActiveRecord::Base.logger.level = Logger::WARN
    yield connection_data
  rescue
    raise
  ensure
    ActiveRecord::Base.connection.disconnect!
  end
end