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,378 @@
1
+ # encoding: UTF-8
2
+ module Msf
3
+ class Plugin::EvasionDB < Msf::Plugin
4
+ class ConsoleCommandDispatcher
5
+ include Msf::Ui::Console::CommandDispatcher
6
+ def name
7
+ "FIDIUS-EvasionDB"
8
+ end
9
+
10
+ def explain_db_connection
11
+ print_status("Usage: ")
12
+ print_status("evasion_db_connect path/to/database.yml")
13
+ print_status()
14
+ print_status("database.yml must have evasion_db entry which points to prelude db")
15
+ print_status()
16
+ print_status("example:")
17
+ print_status("evasion_db:")
18
+ print_status(" adapter: mysql")
19
+ print_status(" host: localhost")
20
+ print_status(" port: 3306")
21
+ print_status(" encoding: utf8")
22
+ print_status(" database: msf")
23
+ print_status(" username: root")
24
+ print_status(" password:")
25
+ end
26
+
27
+ def commands
28
+ {
29
+ "fetch_events" => "fetch events which were created in the meanwhile",
30
+ "show_events" => "shows all fetched idmef-events",
31
+ "show_event" => "shows information about an idmef-event",
32
+ "show_packet" => "shows information about a packet",
33
+ "send_packet" => "send a given packet to generate false positive",
34
+ "send_event_payload" => "send a given payload of an idmef-event to generate false positive",
35
+ "config_exploit" => "configures an exploit with the options of a previous runtime",
36
+ "delete_events" => "deletes events from knowledge",
37
+ "set_autologging" => "true|false automatically log all executed modules"
38
+ }
39
+ end
40
+
41
+ def run_cmd(cmd)
42
+ $console.run_single(cmd)
43
+ end
44
+
45
+ def to_hex_dump(str, from=-1, to=-1)
46
+ width=16
47
+ buf = ''
48
+ idx = 0
49
+ cnt = 0
50
+ snl = false
51
+ lst = 0
52
+ rclosed = true
53
+ while (idx < str.length)
54
+ chunk = str[idx, width]
55
+ line = chunk.unpack("H*")[0].scan(/../).join(" ")
56
+ if from >= idx && from < idx+width
57
+ line[(idx-from).abs*3] = "%bld%red#{line[(idx-from).abs*3]}"
58
+ end
59
+ if to >= idx && to < idx+width
60
+ offset = 0
61
+ offset = "%bld%red".length if line["%bld%red"]
62
+ begin
63
+ line[(idx-to).abs*3+offset+1] = "#{line[(idx-to).abs*3+offset+1]}%clr"
64
+ rescue
65
+ # rescue if the index is out of range, than end mark
66
+ line[line.length-1] = "#{line[line.length-1]}%clr"
67
+ end
68
+ end
69
+ buf << line
70
+
71
+ line_length = line.gsub("%bld%red","").gsub("%clr","").length
72
+ if (lst == 0)
73
+ lst = line_length
74
+ buf << " " * 4
75
+ else
76
+ buf << " " * ((lst - line_length) + 4).abs
77
+ end
78
+
79
+ index = 0
80
+ chunk.unpack("C*").each do |c|
81
+ if from >= idx && from < idx+width && (idx-from).abs == index || !rclosed
82
+ buf << "%bld%red"
83
+ rclosed = false
84
+ end
85
+
86
+ if (c > 0x1f and c < 0x7f)
87
+ buf << c.chr
88
+ else
89
+ buf << "."
90
+ end
91
+ if to >= idx && to < idx+width && (idx-to).abs == index
92
+ buf << "%clr"
93
+ rclosed = true
94
+ end
95
+
96
+ index = index+1
97
+ end
98
+ buf << "\n"
99
+
100
+ idx += width
101
+ end
102
+ buf << "%clr" unless rclosed
103
+ buf << "\n"
104
+ end
105
+
106
+ def send_payload_to_host(payload,host,port)
107
+ begin
108
+ c = Rex::Socket.create_tcp('PeerHost'=>host,'PeerPort' => port)
109
+ c.write(payload)
110
+ c.close
111
+ rescue
112
+ print_error "#{$!} in #{$!.backtrace}"
113
+ end
114
+ end
115
+
116
+ def cmd_send_packet(*args)
117
+ raise "please provide packet id" if args.size != 1
118
+ packet = FIDIUS::EvasionDB::Knowledge.get_packet(args[0].to_i)
119
+ send_payload_to_host(packet.payload,packet.dest_addr,packet.dest_port)
120
+ end
121
+
122
+ def cmd_send_event_payload(*args)
123
+ raise "please provide packet id" if args.size != 1
124
+ event = FIDIUS::EvasionDB::Knowledge.get_event(args[0].to_i)
125
+ send_payload_to_host(event.payload,event.dest_ip,445)
126
+ end
127
+
128
+ def cmd_show_events(*args)
129
+ exploits = FIDIUS::EvasionDB::Knowledge.get_exploits
130
+ exploits.each do |exploit|
131
+ events = exploit.idmef_events
132
+ print_line "-"*60
133
+ print_line "(#{exploit.id})#{exploit.name} with #{exploit.attack_options.size} options"
134
+ print_line "-"*60
135
+ print_line "#{events.size} idmef-events fetched"
136
+ print_line "-"*60
137
+ events.each do |event|
138
+ print_line "(#{event.id})#{event.text} with #{event.payload_size} bytes payload"
139
+ end
140
+ end
141
+ end
142
+
143
+ def cmd_set_autologging(*args)
144
+ raise "please use set_autologging true|false" if args.size != 1
145
+ $auto_logging = args[0] == true
146
+ end
147
+
148
+ def cmd_delete_events(*args)
149
+ raise "please provide id" if args.size != 1
150
+ exploit = FIDIUS::EvasionDB::Knowledge.get_exploit(args[0].to_i)
151
+ exploit.destroy
152
+ end
153
+
154
+ def cmd_config_exploit(*args)
155
+ raise "please provide id" if args.size != 1
156
+ exploit = FIDIUS::EvasionDB::Knowledge.get_exploit(args[0].to_i)
157
+ run_cmd("use #{exploit.name}")
158
+ exploit.attack_options.each do |option|
159
+ run_cmd("set #{option.option_key} #{option.option_value}")
160
+ end
161
+ end
162
+
163
+ def cmd_show_packet(*args)
164
+ raise "please provide packet_id" if args.size != 1
165
+ packet = FIDIUS::EvasionDB::Knowledge::Packet.find(args[0].to_i)
166
+
167
+ hex = to_hex_dump(packet.payload)
168
+ print_line hex
169
+ end
170
+
171
+ def cmd_show_event(*args)
172
+ raise "please provide event_id" if args.size != 1
173
+ event_id = args[0].to_i
174
+ print_line "event_id:#{event_id}"
175
+ event = FIDIUS::EvasionDB::Knowledge.get_event(event_id)
176
+ packet = FIDIUS::EvasionDB::Knowledge.get_packet_for_event(event_id)
177
+ print_line "(#{event.id}) Event(#{event.text}) : #{event.payload_size} bytes payload"
178
+ if packet
179
+ print_line "#{packet.inspect}"
180
+ print_line "#{packet[:packet].inspect}"
181
+ print_line "PACKET(#{packet[:packet].id}): "
182
+ print_line "#{packet[:packet].payload.size} bytes"
183
+ print_line "match #{packet[:index]} - #{packet[:index]+packet[:length]-1}"
184
+ hex = to_hex_dump(packet[:packet].payload,packet[:index],packet[:index]+packet[:length]-1)
185
+ print_line hex
186
+ else
187
+ print_line "no packets available"
188
+ end
189
+ print_line "EVENT PAYLOAD(#{event.payload.size}) bytes:"
190
+ hex = to_hex_dump(event.payload)
191
+ print_line hex
192
+ end
193
+
194
+ def cmd_fetch_events(*args)
195
+ #events = FIDIUS::EvasionDB::Knowledge.fetch_events
196
+ FIDIUS::EvasionDB.current_fetcher.local_ip = nil
197
+ events = FIDIUS::EvasionDB.current_fetcher.fetch_events
198
+ if events
199
+ print_status "#{events.size} events generated"
200
+ print_status
201
+ events.each do |e|
202
+ print_line "(#{e.id}) Event(#{e.text}) : #{e.payload_size} bytes payload (#{e.src_ip} -> #{e.dest_ip})"
203
+ print_status "#{e}"
204
+ end
205
+ else
206
+ print_status "0 events generated"
207
+ end
208
+ FIDIUS::EvasionDB.current_fetcher.begin_record
209
+ end
210
+ end
211
+
212
+ def initialize(framework, opts)
213
+ super
214
+ require 'fidius-evasiondb'
215
+ msf_home = File.expand_path("../..",__FILE__)
216
+ dbconfig_path = File.join(msf_home,"data","database.yml")
217
+ raise "no database.yml in #{dbconfig_path}" if !File.exists?(dbconfig_path)
218
+
219
+ $console = opts['ConsoleDriver']
220
+ $auto_logging = true
221
+ FIDIUS::EvasionDB.config(dbconfig_path)
222
+ FIDIUS::EvasionDB.use_recoder "Msf-Recorder"
223
+ FIDIUS::EvasionDB.use_fetcher "PreludeDB"
224
+
225
+ add_console_dispatcher(ConsoleCommandDispatcher)
226
+ framework.events.add_general_subscriber(FIDIUS::ModuleRunCallback.new)
227
+
228
+ FIDIUS::PacketLogger.init_with_framework(framework)
229
+ FIDIUS::PacketLogger.on_log do |caused_by, data, socket|
230
+ FIDIUS::EvasionDB.current_recorder.log_packet(caused_by,data,socket)
231
+ end
232
+ FIDIUS::EvasionDB.current_fetcher.begin_record
233
+ print_status("EvasionDB plugin loaded.")
234
+ end
235
+
236
+ def cleanup
237
+ remove_console_dispatcher(ConsoleCommandDispatcher)
238
+ end
239
+
240
+ def name
241
+ "FIDIUS-EvasionDB"
242
+ end
243
+
244
+ def desc
245
+ ""
246
+ end
247
+ end
248
+
249
+ end
250
+
251
+ module FIDIUS
252
+ class PacketLogger
253
+ def self.on_log(&block)
254
+ $block = block
255
+ end
256
+
257
+ def self.log_packet(socket,data,module_instance=nil)
258
+ begin
259
+ $block.call module_instance, data, socket
260
+ rescue
261
+ #PUT HERE IS RESPONSIBLE FOR NO SESSION ? $stdout.puts "ERROR #{$!}:#{$!.backtract}"
262
+ end
263
+ end
264
+
265
+ def self.inspect_socket(socket)
266
+ "#{socket.localhost}:#{socket.localport} -> #{socket.peerhost}:#{socket.peerport}"
267
+ end
268
+
269
+ class MySocketEventHandler
270
+ include Rex::Socket::Comm::Events
271
+
272
+ def initialize
273
+
274
+ end
275
+
276
+ def on_before_socket_create(comm, param)
277
+ end
278
+
279
+ def on_socket_created(comm, sock, param)
280
+ sock.extend(FIDIUS::SocketTracer)
281
+ sock.context = param.context
282
+ sock.params = param
283
+ sock.initlog
284
+ end
285
+ end
286
+
287
+ def self.init_with_framework(framework)
288
+ $eh = MySocketEventHandler.new
289
+ Rex::Socket::Comm::Local.register_event_handler($eh)
290
+ end
291
+
292
+ def self.cleanup
293
+ Rex::Socket::Comm::Local.deregister_event_handler($eh)
294
+ end
295
+ end #PacketLogger
296
+
297
+ class ModuleRunCallback
298
+ def on_module_run(instance)
299
+ FIDIUS::EvasionDB.current_recorder.module_started(instance) if $auto_logging
300
+ end
301
+ #
302
+ # Called when a module finishes
303
+ #
304
+ def on_module_complete(instance)
305
+ FIDIUS::EvasionDB.current_recorder.module_completed(instance) if $auto_logging
306
+ end
307
+
308
+ #
309
+ # Called when a module raises an exception
310
+ #
311
+ def on_module_error(instance, exception)
312
+ FIDIUS::EvasionDB.current_recorder.module_error(instance,exception) if $auto_logging
313
+ end
314
+ end #class ModuleRunCallback
315
+
316
+ end #FIDIUS
317
+
318
+ # This extends the PacketDispatcher from Rex
319
+ # with Logging
320
+ # Original Source is: lib/rex/post/meterpreter/packet_dispatcher.rb
321
+ module Rex::Post::Meterpreter::PacketDispatcher
322
+ def send_packet(packet, completion_routine = nil, completion_param = nil)
323
+ FIDIUS::PacketLogger.log_packet(self.sock,packet.to_r,"Meterpreter")
324
+ if (completion_routine)
325
+ add_response_waiter(packet, completion_routine, completion_param)
326
+ end
327
+
328
+ bytes = 0
329
+ raw = packet.to_r
330
+
331
+ if (raw)
332
+ begin
333
+ bytes = self.sock.write(raw)
334
+ rescue ::Exception => e
335
+ # Mark the session itself as dead
336
+ self.alive = false
337
+
338
+ # Indicate that the dispatcher should shut down too
339
+ @finish = true
340
+
341
+ # Reraise the error to the top-level caller
342
+ raise e
343
+ end
344
+ end
345
+
346
+ return bytes
347
+ end
348
+ end
349
+
350
+ # This module extends the captured socket instance
351
+ # Copied from plugins/socket_logger.rb
352
+ module FIDIUS
353
+ module SocketTracer
354
+ @@last_id = 0
355
+
356
+ attr_accessor :context, :params
357
+
358
+ # Hook the write method
359
+ def write(buf, opts = {})
360
+ module_instance = context['MsfExploit'] if context['MsfExploit']
361
+ FIDIUS::PacketLogger.log_packet(self,buf,module_instance)
362
+ super(buf, opts)
363
+ end
364
+
365
+ # Hook the read method
366
+ def read(length = nil, opts = {})
367
+ r = super(length, opts)
368
+ return r
369
+ end
370
+
371
+ def close(*args)
372
+ super(*args)
373
+ end
374
+
375
+ def initlog
376
+ end
377
+ end #SocketTracer
378
+ end #FIDIUS
@@ -0,0 +1,11 @@
1
+ evasion_db:
2
+ adapter: sqlite3
3
+ database: evasion_db.sqlite3
4
+ pool: 5
5
+ timeout: 5000
6
+
7
+ ids_db:
8
+ adapter: sqlite3
9
+ database: ids_db.sqlite3
10
+ pool: 5
11
+ timeout: 5000