fidius-evasiondb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/.gitignore +9 -0
  2. data/.yardopts +6 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +57 -0
  5. data/README.md +180 -0
  6. data/Rakefile +33 -0
  7. data/bin/fidius-evasiondb +111 -0
  8. data/evasion-db.gemspec +37 -0
  9. data/lib/db/db-install.rb +103 -0
  10. data/lib/db/migrations/001_create_packets.rb +18 -0
  11. data/lib/db/migrations/002_create_idmef_events.rb +23 -0
  12. data/lib/db/migrations/003_create_attack_modules.rb +14 -0
  13. data/lib/db/migrations/004_create_attack_options.rb +14 -0
  14. data/lib/db/migrations/005_create_attack_payloads.rb +13 -0
  15. data/lib/evasion-db/base.rb +80 -0
  16. data/lib/evasion-db/idmef-fetchers/fetchers.rb +67 -0
  17. data/lib/evasion-db/idmef-fetchers/prelude-db/fetcher.rb +8 -0
  18. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/additional_data.rb +16 -0
  19. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/address.rb +8 -0
  20. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/alert.rb +46 -0
  21. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/analyzer.rb +18 -0
  22. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/classification.rb +10 -0
  23. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/connection.rb +10 -0
  24. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/detect_time.rb +10 -0
  25. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/impact.rb +19 -0
  26. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/prelude_event.rb +120 -0
  27. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/models/service.rb +10 -0
  28. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/patches/postgres_patch.rb +12 -0
  29. data/lib/evasion-db/idmef-fetchers/prelude-db/lib/prelude_event_fetcher.rb +67 -0
  30. data/lib/evasion-db/idmef-fetchers/test-fetcher/fetcher.rb +6 -0
  31. data/lib/evasion-db/idmef-fetchers/test-fetcher/lib/test_fetcher.rb +19 -0
  32. data/lib/evasion-db/knowledge/attack_module.rb +41 -0
  33. data/lib/evasion-db/knowledge/attack_option.rb +12 -0
  34. data/lib/evasion-db/knowledge/attack_payload.rb +13 -0
  35. data/lib/evasion-db/knowledge/connection.rb +7 -0
  36. data/lib/evasion-db/knowledge/idmef_event.rb +21 -0
  37. data/lib/evasion-db/knowledge/packet.rb +17 -0
  38. data/lib/evasion-db/knowledge.rb +128 -0
  39. data/lib/evasion-db/log_matches_helper.rb +43 -0
  40. data/lib/evasion-db/recorders/msf-recorder/lib/msf-recorder.rb +78 -0
  41. data/lib/evasion-db/recorders/msf-recorder/recorder.rb +6 -0
  42. data/lib/evasion-db/recorders/recorders.rb +61 -0
  43. data/lib/evasion-db/version.rb +5 -0
  44. data/lib/fidius-evasiondb.rb +27 -0
  45. data/lib/msf-plugins/database.yml.example +24 -0
  46. data/lib/msf-plugins/evasiondb.rb +378 -0
  47. data/test/config/database.yml +11 -0
  48. data/test/config/prelude.sql +439 -0
  49. data/test/helper.rb +50 -0
  50. data/test/preludedb_helper.rb +70 -0
  51. data/test/test_fetchers.rb +34 -0
  52. data/test/test_knowledge.rb +102 -0
  53. data/test/test_preludedb.rb +41 -0
  54. data/test/test_recorders.rb +115 -0
  55. metadata +238 -0
@@ -0,0 +1,128 @@
1
+ module FIDIUS
2
+ module EvasionDB
3
+ # This module provides active-record classes for the knowledge database.
4
+ # Some handy query methods are also available.
5
+ module Knowledge
6
+ # used in find_events_for_exploit
7
+ # to indicate that the exploit with minimal events should be searched
8
+ MIN_EVENTS = 1
9
+ # used in find_events_for_exploit
10
+ # to indicate that the exploit with maximal events should be searched
11
+ MAX_EVENTS = 2
12
+
13
+ autoload :AttackModule, 'evasion-db/knowledge/attack_module'
14
+ autoload :AttackOption, 'evasion-db/knowledge/attack_option'
15
+ autoload :AttackPayload, 'evasion-db/knowledge/attack_payload'
16
+ autoload :Connection, 'evasion-db/knowledge/connection'
17
+ autoload :IdmefEvent, 'evasion-db/knowledge/idmef_event'
18
+ autoload :Packet, 'evasion-db/knowledge/packet'
19
+
20
+ # returns all modules(exploits) in knowledge database
21
+ def self.get_exploits
22
+ AttackModule.all
23
+ end
24
+
25
+ def self.get_exploit(id)
26
+ AttackModule.find(id)
27
+ end
28
+
29
+ # finds a packet within an id
30
+ #
31
+ #@param [integer] packet id
32
+ def self.get_packet(id)
33
+ Packet.find(id)
34
+ end
35
+
36
+ # returns all idmef-events
37
+ def self.get_events
38
+ IdmefEvent.all
39
+ end
40
+
41
+ # return an certain event
42
+ #
43
+ #@param [integer] event id
44
+ def self.get_event(event_id)
45
+ IdmefEvent.find(event_id)
46
+ end
47
+
48
+ # returns a certain packet
49
+ #
50
+ #@param [integer] packet id
51
+ def self.get_packet(pid)
52
+ Packet.find(pid)
53
+ end
54
+
55
+ # returns all exploits for the given service
56
+ #
57
+ #@param [integer] port
58
+ def self.find_exploits_for_service(port)
59
+ option_set = AttackOption.where(:option_key => "RPORT",
60
+ :option_value => port)
61
+ exploits = []
62
+ option_set.each { |opt| exploits << opt.attack_module }
63
+ exploits
64
+ end
65
+
66
+ # returns the packets which might be responsible for the given event
67
+ #
68
+ # @param [integer] event id
69
+ def self.get_packet_for_event(event_id)
70
+ event = IdmefEvent.find(event_id)
71
+ FIDIUS::EvasionDB::LogMatchesHelper.find_packets_for_event(event,Packet.all)
72
+ end
73
+
74
+ # find out the events raised by the given payload
75
+ #
76
+ #@param [string] payload
77
+ def self.get_events_for_payload(payload)
78
+ #TODO: Search all packets which belong to this event
79
+ events = []
80
+ search_payload = FIDIUS::EvasionDB::LogMatchesHelper.to_hex(payload)
81
+ IdmefEvent.find_each do |event|
82
+ event_payload = FIDIUS::EvasionDB::LogMatchesHelper.to_hex(event.payload)
83
+ events << event if event_payload.include?(search_payload)
84
+ end
85
+
86
+ events
87
+ end
88
+
89
+ # find events for an module(exploit). you can restrict your results by setting options
90
+ # which sould be used by the exploit. You can even determine if minimal or maximal size of
91
+ # events should be returned
92
+ #
93
+ #@param [string] exploit/module name
94
+ #@param [hash] options which should be used
95
+ #@param [integer] MIN_EVENTS||MAX_EVENTS
96
+ def self.find_events_for_exploit(name,options={},result = MIN_EVENTS)
97
+ attacks = AttackModule.find_all_by_name(name).delete_if do |attack|
98
+ !attack.has_options(options)
99
+ end
100
+
101
+ if attacks.size > 0
102
+ res = nil
103
+ if result == MIN_EVENTS
104
+ min_cnt = 1073741823 #max value
105
+ attacks.each do |attack|
106
+ events_cnt = attack.idmef_events.size
107
+ if events_cnt < min_cnt
108
+ min_cnt = events_cnt
109
+ res = attack
110
+ end
111
+ end
112
+ elsif result == MAX_EVENTS
113
+ min_cnt = 0 #min value
114
+ attacks.each do |attack|
115
+ events_cnt = attack.idmef_events.size
116
+ if events_cnt > min_cnt
117
+ min_cnt = events_cnt
118
+ res = attack
119
+ end
120
+ end
121
+ end
122
+ return res.idmef_events if result
123
+ end
124
+ nil
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,43 @@
1
+ module FIDIUS
2
+ module EvasionDB
3
+ # This helper is indented to find matches between logged packets and idmef-events
4
+ # by comparing their payload.
5
+ module LogMatchesHelper
6
+
7
+ # this method is from Rex::Text of metasploit
8
+ def self.to_hex(str, prefix = "\\x", count = 1)
9
+ raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
10
+
11
+ # XXX: Regexp.new is used here since using /.{#{count}}/o would compile
12
+ # the regex the first time it is used and never check again. Since we
13
+ # want to know how many to capture on every instance, we do it this
14
+ # way.
15
+ return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s }
16
+ end
17
+
18
+ # tries to find the packet which generated the given event
19
+ #
20
+ #@param [IdmefEvent] a certain idmef event
21
+ #@param [Array] Array of Packet
22
+ #@return [hash] {:packet=>:index,:length} index and length are indicating where the match between both payloads is.
23
+ def self.find_packets_for_event(event,packets)
24
+ event_payload = nil
25
+ return unless event.payload
26
+ if event.payload.size > 0
27
+ event_payload = self.to_hex(event.payload).gsub("\\x","")
28
+ end
29
+ return unless event_payload
30
+
31
+ packets.each do |packet|
32
+ str = nil
33
+ # lets find the payload of the prelude event
34
+ # in one of the logged payloads
35
+ packet_payload = self.to_hex(packet.payload).gsub("\\x","")
36
+ str = packet_payload[event_payload]
37
+ return {:packet=>packet,:index=>packet.payload.index(event.payload),:length=>event.payload.size} if str != nil
38
+ end
39
+ nil
40
+ end
41
+ end#module LogMatchesHelper
42
+ end#module EvasionDB
43
+ end#module FIDIUS
@@ -0,0 +1,78 @@
1
+ module FIDIUS
2
+ module EvasionDB
3
+ # This recorder provides an interface for the metasploit console
4
+ # it is used to have callbacks when modules are executed.
5
+ #
6
+ # @see {file:msf-plugins/evasiondb.rb}
7
+ module MsfRecorder
8
+ def module_started(module_instance)
9
+ @@current_exploit = FIDIUS::EvasionDB::Knowledge::AttackModule.find_or_create_by_name_and_options(module_instance.fullname,module_instance.datastore)
10
+ FIDIUS::EvasionDB.current_fetcher.begin_record
11
+ end
12
+
13
+ def module_completed(module_instance)
14
+ begin
15
+ # TODO: refactor this
16
+ if module_instance.datastore["RHOST"]
17
+ FIDIUS::EvasionDB.current_fetcher.local_ip = FIDIUS::Common.get_my_ip(module_instance.datastore["RHOST"])
18
+ end
19
+ if module_instance.datastore["RHOSTS"]
20
+ FIDIUS::EvasionDB.current_fetcher.local_ip = FIDIUS::Common.get_my_ip(module_instance.datastore["RHOSTS"])
21
+ end
22
+ unless @@current_exploit.finished
23
+ $logger.debug("module #{module_instance} finished")
24
+ idmef_events = FIDIUS::EvasionDB.current_fetcher.fetch_events(module_instance)
25
+ $logger.debug("found #{idmef_events.size} events")
26
+ idmef_events.each do |idmef_event|
27
+ if module_instance && module_instance.respond_to?("fullname")
28
+ $logger.debug "idmef_events << #{idmef_event}"
29
+ @@current_exploit.idmef_events << idmef_event
30
+ # meterpreter is not a module and does not respond to fullname
31
+ # we handle this seperatly
32
+ elsif module_instance == "Meterpreter"
33
+ $logger.debug "attack_payload.idmef_events << #{idmef_event}"
34
+ @@current_exploit.attack_payload.idmef_events << idmef_event
35
+ end
36
+ end
37
+ @@current_exploit.finished = true
38
+ @@current_exploit.save
39
+ end
40
+ rescue
41
+ $logger.error $!.message+":"+$!.backtrace.to_s
42
+ end
43
+ end
44
+
45
+ def module_error(module_instance,exception)
46
+ module_completed(module_instance)
47
+ end
48
+
49
+ def log_packet(module_instance,data,socket)
50
+ begin
51
+ # set local ip, if there is no
52
+ #FIDIUS::EvasionDB.current_fetcher.local_ip = FIDIUS::Common.get_my_ip(socket.peerhost)
53
+ $logger.debug "logged module_instance: #{module_instance} with #{data.size} bytes payload"
54
+ # TODO: what shall we do with meterpreter?
55
+ # it has not options and no fullname, logger assigns only the string "meterpreter"
56
+ if module_instance.respond_to?("fullname")
57
+ unless @@current_exploit.finished
58
+ @@current_exploit.packets << FIDIUS::EvasionDB::Knowledge::Packet.create(:payload=>data,:src_addr=>socket.localhost,:src_port=>socket.localport,:dest_addr=>socket.peerhost,:dest_port=>socket.peerport)
59
+ @@current_exploit.save
60
+ end
61
+ # meterpreter is not a module and does not respond to fullname
62
+ # we handle this seperatly
63
+ elsif module_instance == "Meterpreter"
64
+ $logger.debug "module_instance is meterpreter"
65
+ $logger.debug "putting package to attack_payload"
66
+ @@current_exploit.attack_payload.packets << FIDIUS::EvasionDB::Knowledge::Packet.create(:payload=>data,:src_addr=>socket.localhost,:src_port=>socket.localport,:dest_addr=>socket.peerhost,:dest_port=>socket.peerport)
67
+ @@current_exploit.save
68
+ end
69
+ $logger.debug "LOG: #{module_instance} #{data.size} Bytes on #{socket}"
70
+ rescue ActiveRecord::StatementInvalid
71
+ $logger.error "StatementInvalid"
72
+ rescue
73
+ $logger.error "error:" # "#{$!.message}" ##{$!.inspect}:#{$!.backtrace}"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,6 @@
1
+ FIDIUS::EvasionDB.recorder "Msf-Recorder" do
2
+ install do
3
+ require (File.join File.dirname(__FILE__), 'lib', 'msf-recorder.rb')
4
+ self.extend FIDIUS::EvasionDB::MsfRecorder
5
+ end
6
+ end
@@ -0,0 +1,61 @@
1
+ module FIDIUS
2
+ module EvasionDB
3
+ def self.recorder(name,&block)
4
+ FIDIUS::EvasionDB::Recorder.new(name,&block)
5
+ end
6
+
7
+ def self.install_recorders
8
+ $logger.debug "installing recoders"
9
+ FIDIUS::EvasionDB::Recorder.all.each do |recorder|
10
+ recorder.run_install
11
+ end
12
+ end
13
+
14
+ # A Recorder us used to log packets for an executed attack
15
+ class Recorder
16
+ @@recorders = []
17
+ attr_accessor :name
18
+
19
+ def initialize(name,&block)
20
+ self.instance_eval(&block)
21
+ @name = name
22
+ @@recorders << self
23
+ end
24
+
25
+ def install(&block)
26
+ $logger.debug "setting installblock"
27
+ @install = block
28
+ end
29
+
30
+ def run_install
31
+ raise "no install block given" unless @install
32
+ $logger.debug "run install of #{@name}"
33
+ @install.call
34
+ end
35
+
36
+ def self.all
37
+ @@recorders
38
+ end
39
+
40
+ def self.by_name(name)
41
+ self.all.each do |recorder|
42
+ return recorder if recorder.name == name
43
+ end
44
+ nil
45
+ end
46
+
47
+ def start
48
+ raise "overwrite this"
49
+ end
50
+
51
+ def log_packet
52
+ raise "overwrite this"
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ Dir[File.join(File.dirname(__FILE__), "*/recorder.rb")].each{|fetch_require|
59
+ $logger.debug "load #{fetch_require}"
60
+ require fetch_require
61
+ }
@@ -0,0 +1,5 @@
1
+ module FIDIUS
2
+ module EvasionDB
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'logger'
4
+ require 'fidius-common'
5
+ require 'active_record'
6
+ require 'evasion-db/base'
7
+
8
+ module FIDIUS
9
+ module EvasionDB
10
+ $logger = Logger.new(STDOUT)
11
+ $logger.level = Logger::ERROR
12
+ GEM_BASE = File.expand_path('..', __FILE__)
13
+ $logger.debug "GEM_BASE ist: #{GEM_BASE}"
14
+
15
+ autoload :VERSION, 'evasion-db/version'
16
+ autoload :LogMatchesHelper, 'evasion-db/log_matches_helper'
17
+ autoload :Knowledge, 'evasion-db/knowledge'
18
+
19
+ # install fetchers
20
+ require File.join(GEM_BASE, 'evasion-db', 'idmef-fetchers', 'fetchers.rb')
21
+ FIDIUS::EvasionDB.install_fetchers
22
+
23
+ # install recorders
24
+ require File.join(GEM_BASE, 'evasion-db', 'recorders', 'recorders.rb')
25
+ FIDIUS::EvasionDB.install_recorders
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ ids_db:
2
+ adapter: postgresql
3
+ host: 10.10.10.253
4
+ port: 5432
5
+ encoding: utf8
6
+ database: preludemanager
7
+ username: preludemanager
8
+ password: fidius09
9
+ read_timeout: 1
10
+ write_timeout: 1
11
+ wait_timeout: 1
12
+ timeout: 1
13
+ pool: 1
14
+ retry: 3
15
+
16
+ evasion_db:
17
+ adapter: mysql2
18
+ host: localhost
19
+ port: 3306
20
+ encoding: utf8
21
+ database: evasion_db
22
+ username: root
23
+ password:
24
+ socket: /opt/lampp/var/mysql/mysql.sock