threatinator 0.1.6 → 0.2.0

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 (197) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -2
  3. data/Gemfile +18 -13
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/feeds/ET_block-ip_reputation.feed +26 -0
  7. data/feeds/ET_openbadlist-ip_reputation.feed +35 -0
  8. data/feeds/bambenek_c2_masterlist-domain_reputation.feed +15 -0
  9. data/feeds/bambenek_c2_masterlist-ip_reputation.feed +15 -0
  10. data/feeds/bambenek_dga_feed-domain_reputation.feed +15 -0
  11. data/feeds/berkeley-ip_reputation.feed +23 -0
  12. data/feeds/bitcash_cz_blacklist.feed +20 -0
  13. data/feeds/botscout-ip_reputation.feed +24 -0
  14. data/feeds/cert_mxpoison-ip_reputation.feed +21 -0
  15. data/feeds/chaosreigns-ip_reputation.feed +36 -0
  16. data/feeds/cydef_torexit-ip_reputation.feed +24 -0
  17. data/feeds/danger_bruteforce-ip_reputation.feed +23 -0
  18. data/feeds/falconcrest-ip_reputation.feed +18 -0
  19. data/feeds/h3x_asprox.feed +17 -0
  20. data/feeds/hosts-file_hphostspartial-domain_reputation.feed +18 -0
  21. data/feeds/infiltrated_vabl-ip_reputation.feed +29 -0
  22. data/feeds/isc_suspicious_high-domain_reputation.feed +25 -0
  23. data/feeds/isc_suspicious_low-domain_reputation.feed +25 -0
  24. data/feeds/isc_suspicious_medium-domain_reputation.feed +25 -0
  25. data/feeds/malwaredomainlist-url_reputation.feed +16 -0
  26. data/feeds/malwaredomains-domain_reputation.feed +27 -0
  27. data/feeds/malwaredomains_dyndns-domain_reputation.feed +27 -0
  28. data/feeds/malwaredomains_justdomains-domain_reputation.feed +18 -0
  29. data/feeds/multiproxy-ip_reputation.feed +20 -0
  30. data/feeds/openphish-url_reputation.feed +22 -0
  31. data/feeds/packetmail_perimeterbad-ip_reputation.feed +26 -0
  32. data/feeds/phishtank.feed +1 -1
  33. data/feeds/sigmaproject_atma.feed +25 -0
  34. data/feeds/sigmaproject_spyware.feed +24 -0
  35. data/feeds/sigmaproject_webexploit.feed +26 -0
  36. data/feeds/snort_bpf-ip_reputation.feed +19 -0
  37. data/feeds/steeman-ip_reputation.feed +19 -0
  38. data/feeds/trustedsec-ip_reputation.feed +17 -0
  39. data/feeds/virbl-ip_reputation.feed +24 -0
  40. data/feeds/vxvault-url_reputation.feed +22 -0
  41. data/feeds/yoyo_adservers-domain_reputation.feed +16 -0
  42. data/lib/threatinator/actions/run/action.rb +15 -3
  43. data/lib/threatinator/actions/run/coverage_observer.rb +12 -7
  44. data/lib/threatinator/actions/run/status_observer.rb +37 -0
  45. data/lib/threatinator/cli.rb +9 -3
  46. data/lib/threatinator/cli/parser.rb +14 -4
  47. data/lib/threatinator/config.rb +1 -0
  48. data/lib/threatinator/config/logger.rb +14 -0
  49. data/lib/threatinator/event.rb +28 -18
  50. data/lib/threatinator/event_builder.rb +52 -23
  51. data/lib/threatinator/exceptions.rb +3 -6
  52. data/lib/threatinator/feed.rb +1 -1
  53. data/lib/threatinator/feed_runner.rb +63 -7
  54. data/lib/threatinator/logger.rb +66 -0
  55. data/lib/threatinator/logging.rb +20 -0
  56. data/lib/threatinator/model/base.rb +23 -0
  57. data/lib/threatinator/model/collection.rb +64 -0
  58. data/lib/threatinator/model/observables/fqdn_collection.rb +13 -0
  59. data/lib/threatinator/model/observables/ipv4.rb +30 -0
  60. data/lib/threatinator/model/observables/ipv4_collection.rb +14 -0
  61. data/lib/threatinator/model/observables/url_collection.rb +16 -0
  62. data/lib/threatinator/model/validations.rb +1 -0
  63. data/lib/threatinator/model/validations/type.rb +21 -0
  64. data/lib/threatinator/plugins/output/csv.rb +20 -9
  65. data/spec/feeds/ET_block-ip_reputation_spec.rb +50 -0
  66. data/spec/feeds/ET_compromised-ip_reputation_spec.rb +2 -5
  67. data/spec/feeds/ET_openbadlist-ip_reputation_spec.rb +56 -0
  68. data/spec/feeds/alienvault-ip_reputation_spec.rb +2 -5
  69. data/spec/feeds/arbor_fastflux-domain_reputation_spec.rb +0 -3
  70. data/spec/feeds/arbor_ssh-ip_reputation_spec.rb +2 -5
  71. data/spec/feeds/autoshun_shunlist_spec.rb +1 -4
  72. data/spec/feeds/bambenek_c2_masterlist-domain_reputation_spec.rb +39 -0
  73. data/spec/feeds/bambenek_c2_masterlist-ip_reputation_spec.rb +39 -0
  74. data/spec/feeds/bambenek_dga_feed-domain_reputation_spec.rb +39 -0
  75. data/spec/feeds/berkeley-ip_reputation_spec.rb +47 -0
  76. data/spec/feeds/bitcash_cz_blacklist-ip_reputation_spec.rb +50 -0
  77. data/spec/feeds/blocklist_de_apache-ip_reputation_spec.rb +2 -5
  78. data/spec/feeds/blocklist_de_bots-ip_reputation_spec.rb +2 -5
  79. data/spec/feeds/blocklist_de_ftp-ip_reputation_spec.rb +2 -5
  80. data/spec/feeds/blocklist_de_imap-ip_reputation_spec.rb +2 -5
  81. data/spec/feeds/blocklist_de_pop3-ip_reputation_spec.rb +2 -5
  82. data/spec/feeds/blocklist_de_proftpd-ip_reputation_spec.rb +2 -5
  83. data/spec/feeds/blocklist_de_sip-ip_reputation_spec.rb +2 -5
  84. data/spec/feeds/blocklist_de_ssh-ip_reputation_spec.rb +2 -5
  85. data/spec/feeds/blocklist_de_strongips-ip_reputation_spec.rb +2 -5
  86. data/spec/feeds/botscout-ip_reputation_spec.rb +50 -0
  87. data/spec/feeds/cert_mxpoison-ip_reputation_spec.rb +47 -0
  88. data/spec/feeds/chaosreigns-ip_reputation_spec.rb +50 -0
  89. data/spec/feeds/ciarmy-ip_reputation_spec.rb +2 -5
  90. data/spec/feeds/cruzit-ip_reputation_spec.rb +2 -5
  91. data/spec/feeds/cydef_torexit-ip_reputation_spec.rb +47 -0
  92. data/spec/feeds/dan_me_uk_torlist-ip_reputation_spec.rb +2 -5
  93. data/spec/feeds/danger_bruteforce-ip_reputation_spec.rb +47 -0
  94. data/spec/feeds/data/ET_block-ip_reputation.txt +80 -0
  95. data/spec/feeds/data/ET_openbadlist-ip_reputation.txt +62 -0
  96. data/spec/feeds/data/bambenek_c2-dommasterlist.csv +30 -0
  97. data/spec/feeds/data/bambenek_c2-ipmasterlist.csv +27 -0
  98. data/spec/feeds/data/bambenek_dga_feed.csv +42 -0
  99. data/spec/feeds/data/berkeley.txt +29 -0
  100. data/spec/feeds/data/bitcash_cz_blacklist.txt +7 -0
  101. data/spec/feeds/data/botscout-ip-reputation.txt +713 -0
  102. data/spec/feeds/data/cert_mxpoison-ip_reputation.txt +17 -0
  103. data/spec/feeds/data/chaosreigns-ip-reputation.txt +26 -0
  104. data/spec/feeds/data/cydef_torexit-ip_reputation.txt +27 -0
  105. data/spec/feeds/data/danger_bruteforce-ip_reputation.txt +12 -0
  106. data/spec/feeds/data/falconcrest_iplist.txt +345 -0
  107. data/spec/feeds/data/h3x_asprox.txt +20 -0
  108. data/spec/feeds/data/hosts-file_hphostspartial_domainlist.txt +24 -0
  109. data/spec/feeds/data/infiltrated_vabl_iplist.txt +33 -0
  110. data/spec/feeds/data/isc_suspicious_high_domainlist.txt +26 -0
  111. data/spec/feeds/data/isc_suspicious_low_domainlist.txt +34 -0
  112. data/spec/feeds/data/isc_suspicious_medium_domainlist.txt +32 -0
  113. data/spec/feeds/data/malwaredomainlist-url-reputation.txt +8 -0
  114. data/spec/feeds/data/malwaredomains_domainlist.txt +24 -0
  115. data/spec/feeds/data/malwaredomains_dyndns_domainlist.txt +34 -0
  116. data/spec/feeds/data/malwaredomains_justdomains_domainlist.txt +18 -0
  117. data/spec/feeds/data/multiproxy_iplist.txt +15 -0
  118. data/spec/feeds/data/openphish-url-reputation.txt +16 -0
  119. data/spec/feeds/data/packetmail_perimeterbad-ip_reputation.txt +44 -0
  120. data/spec/feeds/data/sigmaproject_atma.return.gz +0 -0
  121. data/spec/feeds/data/sigmaproject_spyware.return.gz +0 -0
  122. data/spec/feeds/data/sigmaproject_webexploit.return.gz +0 -0
  123. data/spec/feeds/data/snort_bpf-ip_reputation.txt +16 -0
  124. data/spec/feeds/data/steeman-ip-reputation.txt +13 -0
  125. data/spec/feeds/data/trustedsec-ip-reputation.txt +12 -0
  126. data/spec/feeds/data/virbl-ip_reputation.txt +14 -0
  127. data/spec/feeds/data/vxvault-url-reputation.txt +15 -0
  128. data/spec/feeds/data/yoyo_adservers.txt +25 -0
  129. data/spec/feeds/dshield_attackers-top1000_spec.rb +1 -4
  130. data/spec/feeds/falconcrest-ip_reputation_spec.rb +37 -0
  131. data/spec/feeds/feodo-domain_reputation_spec.rb +0 -3
  132. data/spec/feeds/feodo-ip_reputation_spec.rb +2 -5
  133. data/spec/feeds/h3x_asprox-ip_reputation_spec.rb +50 -0
  134. data/spec/feeds/hosts-file_hphostspartial-domain_reputation_spec.rb +47 -0
  135. data/spec/feeds/infiltrated-ip_reputation_spec.rb +2 -5
  136. data/spec/feeds/infiltrated_vabl-ip_reputation_spec.rb +47 -0
  137. data/spec/feeds/isc_suspicious_high-domain_reputation_spec.rb +47 -0
  138. data/spec/feeds/isc_suspicious_low-domain_reputation_spec.rb +47 -0
  139. data/spec/feeds/isc_suspicious_medium-domain_reputation_spec.rb +47 -0
  140. data/spec/feeds/malc0de-domain_reputation_spec.rb +0 -3
  141. data/spec/feeds/malc0de-ip_reputation_spec.rb +2 -5
  142. data/spec/feeds/malwaredomainlist_url_reputation_spec.rb +50 -0
  143. data/spec/feeds/malwaredomains-domain_reputation_spec.rb +47 -0
  144. data/spec/feeds/malwaredomains_dyndns-domain_reputation_spec.rb +47 -0
  145. data/spec/feeds/malwaredomains_justdomains-domain_reputation_spec.rb +47 -0
  146. data/spec/feeds/mirc-domain_reputation_spec.rb +0 -3
  147. data/spec/feeds/multiproxy-ip_reputation_spec.rb +47 -0
  148. data/spec/feeds/nothink_irc-ip_reputation_spec.rb +2 -5
  149. data/spec/feeds/nothink_ssh-ip_reputation_spec.rb +2 -5
  150. data/spec/feeds/openbl-ip_reputation_spec.rb +2 -5
  151. data/spec/feeds/openphish_url_reputation_spec.rb +50 -0
  152. data/spec/feeds/packetmail_perimeterbad-ip_reputation_spec.rb +47 -0
  153. data/spec/feeds/palevo-domain_reputation_spec.rb +0 -3
  154. data/spec/feeds/palevo-ip_reputation_spec.rb +2 -5
  155. data/spec/feeds/phishtank_spec.rb +2 -5
  156. data/spec/feeds/sigmaproject_atma_spec.rb +63 -0
  157. data/spec/feeds/sigmaproject_spyware_spec.rb +64 -0
  158. data/spec/feeds/sigmaproject_webexploit_spec.rb +63 -0
  159. data/spec/feeds/snort_bpf-ip_reputation_spec.rb +47 -0
  160. data/spec/feeds/spyeye-domain_reputation_spec.rb +0 -3
  161. data/spec/feeds/spyeye-ip_reputation_spec.rb +2 -5
  162. data/spec/feeds/steeman-ip_reputation_spec.rb +50 -0
  163. data/spec/feeds/t-arend-de_ssh-ip_reputation_spec.rb +2 -5
  164. data/spec/feeds/the_haleys_ssh-ip_reputation_spec.rb +2 -5
  165. data/spec/feeds/trustedsec-ip_reputation_spec.rb +47 -0
  166. data/spec/feeds/virbl-ip_reputation_spec.rb +47 -0
  167. data/spec/feeds/vxvault_url_reputation_spec.rb +50 -0
  168. data/spec/feeds/yourcmc_ssh-ip_reputation_spec.rb +2 -5
  169. data/spec/feeds/yoyo_adservers_spec.rb +47 -0
  170. data/spec/feeds/zeus-domain_reputation_spec.rb +0 -3
  171. data/spec/feeds/zeus-ip_reputation_spec.rb +2 -5
  172. data/spec/spec_helper.rb +2 -0
  173. data/spec/support/factories/event.rb +11 -7
  174. data/spec/support/factories/feed.rb +28 -1
  175. data/spec/support/factories/ipv4.rb +36 -0
  176. data/spec/support/factories/url.rb +34 -0
  177. data/spec/support/shared/feed_runner_observer.rb +136 -0
  178. data/spec/support/shared/feeds.rb +19 -4
  179. data/spec/support/shared/model/collection.rb +164 -0
  180. data/spec/threatinator/actions/run/action_spec.rb +27 -10
  181. data/spec/threatinator/actions/run/coverage_observer_spec.rb +39 -4
  182. data/spec/threatinator/actions/run/status_observer_spec.rb +86 -0
  183. data/spec/threatinator/event_builder_spec.rb +111 -21
  184. data/spec/threatinator/event_spec.rb +237 -13
  185. data/spec/threatinator/event_spec.rb.new +319 -0
  186. data/spec/threatinator/feed_builder_spec.rb +0 -3
  187. data/spec/threatinator/feed_runner_spec.rb +254 -70
  188. data/spec/threatinator/logger_spec.rb +29 -0
  189. data/spec/threatinator/model/observables/fqdn_collection_spec.rb +42 -0
  190. data/spec/threatinator/model/observables/ipv4_collection_spec.rb +36 -0
  191. data/spec/threatinator/model/observables/ipv4_spec.rb +75 -0
  192. data/spec/threatinator/model/observables/url_collection_spec.rb +45 -0
  193. data/spec/threatinator/model/validations/type_spec.rb +37 -0
  194. data/spec/threatinator/plugins/output/csv_spec.rb +4 -3
  195. metadata +216 -19
  196. data/lib/threatinator/property_definer.rb +0 -101
  197. data/spec/threatinator/property_definer_spec.rb +0 -155
@@ -0,0 +1,22 @@
1
+ provider "vxvault"
2
+ name "url_reputation"
3
+ fetch_http('http://vxvault.siri-urz.net/URL_List.php')
4
+
5
+ filter_whitespace
6
+ filter_comments
7
+
8
+ # Filter out any lines that don't start with a URL
9
+ filter do |record|
10
+ !(record.data =~ /^http/)
11
+ end
12
+
13
+ parse_eachline(:separator => "\n") do |event_generator, record|
14
+ url = record.data.strip
15
+ next if url.nil?
16
+
17
+ event_generator.call() do |event|
18
+ event.type = :malware_host
19
+ event.add_url(url) do |url_event|
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ provider "yoyo"
2
+ name "adservers"
3
+ fetch_http('http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml')
4
+
5
+ filter_whitespace
6
+ filter_comments
7
+
8
+ parse_eachline(:separator => "\n") do |event_generator, record|
9
+ domain = record.data.strip()
10
+ next if domain.nil?
11
+
12
+ event_generator.call() do |event|
13
+ event.type = :scanning
14
+ event.add_fqdn(domain)
15
+ end
16
+ end
@@ -1,12 +1,16 @@
1
1
  require 'threatinator/action'
2
2
  require 'threatinator/exceptions'
3
3
  require 'threatinator/feed_runner'
4
+ require 'threatinator/logging'
5
+ require 'threatinator/actions/run/status_observer'
4
6
  require 'csv'
5
7
 
6
8
  module Threatinator
7
9
  module Actions
8
10
  module Run
9
11
  class Action < Threatinator::Action
12
+ include Logging
13
+
10
14
  def initialize(registry, config)
11
15
  super(registry)
12
16
  @config = config
@@ -21,12 +25,15 @@ module Threatinator
21
25
 
22
26
  feed = registry.get(@config.feed_provider, @config.feed_name)
23
27
  if feed.nil?
28
+ logger.error("Unknown feed: provider = #{@config.feed_provider}, name = #{@config.feed_name}")
24
29
  raise Threatinator::Exceptions::UnknownFeed.new(@config.feed_provider, @config.feed_name)
25
30
  end
26
31
 
27
32
  output = build_output
28
33
 
29
34
  feed_runner = Threatinator::FeedRunner.new(feed, output)
35
+ status = StatusObserver.new
36
+ feed_runner.add_observer(status)
30
37
 
31
38
  @config.observers.each do |observer|
32
39
  feed_runner.add_observer(observer)
@@ -34,10 +41,15 @@ module Threatinator
34
41
 
35
42
  feed_runner.run
36
43
 
37
- # if feed_report.num_records_missed != 0
38
- # $stderr.puts "WARNING: #{feed_report.num_records_missed} lines/records were MISSED (neither filtered nor parsed). You may need to update your feed specification! Rerun with --coverage to see which records are parsed/filtered/missed"
39
- # end
44
+ if status.missed?
45
+ logger.error "#{status.missed} records were MISSED (neither parsed nor filtered). You may need to update your feed specification! Try increasing the logging level to DEBUG, or re-run with run.coverage_output='output.csv' to see which records were parsed/filtered/missed."
46
+ end
47
+
48
+ if status.errors?
49
+ logger.error "#{status.errors} records had errors! You may have a bug in your feed specification! Try increasing the logging level to DEBUG, or re-run with run.coverage_output='output.csv' to see which records had errors."
50
+ end
40
51
 
52
+ logger.info "#{status.total} records processed. #{status.parsed} parsed, #{status.filtered} filtered, #{status.missed} missed, #{status.errors} errors"
41
53
  end
42
54
  end
43
55
  end
@@ -16,18 +16,23 @@ module Threatinator
16
16
  end
17
17
 
18
18
  def open
19
- @csv = ::CSV.open(@filename, "wb", :headers => [:status, :event_count, :line_number, :pos_start, :pos_end, :data], :write_headers => true)
19
+ @csv = ::CSV.open(@filename, "wb", :headers => [:status, :event_count, :line_number, :pos_start, :pos_end, :data, :message], :write_headers => true)
20
20
  end
21
21
 
22
22
  # Handles FeedRunner observations
23
23
  def update(message, *args)
24
24
  case message
25
25
  when :record_missed
26
- log_record(:missed, args.shift, [])
26
+ log_record(:missed, args.shift, 0)
27
27
  when :record_filtered
28
- log_record(:filtered, args.shift, [])
28
+ log_record(:filtered, args.shift, 0)
29
29
  when :record_parsed
30
- log_record(:parsed, args.shift, args.shift)
30
+ log_record(:parsed, args.shift, args.shift.count)
31
+ when :record_error
32
+ record = args.shift
33
+ errors = args.shift
34
+ message = errors.map { |e| e.message }.join(', ')
35
+ log_record(:error, record, 0, message)
31
36
  when :end
32
37
  close
33
38
  when :start
@@ -38,11 +43,11 @@ module Threatinator
38
43
  # @param [Symbol] status :parsed, :missed, :filtered
39
44
  # @param [Threatinator::Record] record
40
45
  # @param [Array<Threatinator::Event>] events
41
- def log_record(status, record, events = [])
46
+ def log_record(status, record, event_count, message = '')
42
47
  return if closed?
43
48
  @csv.add_row( [
44
- status, events.count, record.line_number,
45
- record.pos_start, record.pos_end, record.data.inspect])
49
+ status, event_count, record.line_number,
50
+ record.pos_start, record.pos_end, record.data.inspect, message])
46
51
  end
47
52
 
48
53
  def close
@@ -0,0 +1,37 @@
1
+ module Threatinator
2
+ module Actions
3
+ module Run
4
+ class StatusObserver
5
+ attr_reader :missed, :filtered, :parsed, :errors
6
+ def initialize
7
+ @missed = @filtered = @parsed = @errors = 0
8
+ end
9
+
10
+ def total
11
+ @missed + @filtered + @parsed + @errors
12
+ end
13
+
14
+ # Handles FeedRunner observations
15
+ def update(message, *args)
16
+ case message
17
+ when :record_missed
18
+ @missed += 1
19
+ when :record_filtered
20
+ @filtered += 1
21
+ when :record_parsed
22
+ @parsed += 1
23
+ when :record_error
24
+ @errors += 1
25
+ end
26
+ end
27
+
28
+ def missed?; @missed > 0; end
29
+ def parsed?; @parsed > 0; end
30
+ def filtered?; @filtered > 0; end
31
+ def errors?; @errors > 0; end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -1,12 +1,18 @@
1
1
  require 'threatinator/cli/parser'
2
+ require 'threatinator/config/logger'
3
+ require 'threatinator/logger'
2
4
  module Threatinator
3
5
  module CLI
4
6
  def self.process!(args)
5
7
  parser = Parser.new
6
8
  ret = parser.parse(args)
7
- if builder = parser.builder
8
- builder.build.exec
9
- end
9
+ builder = parser.builder
10
+ return ret if builder.nil?
11
+
12
+ conf = Threatinator::Config::Logger.new(parser.config_hash['logger'])
13
+ Threatinator::Logger.configure_logger(conf)
14
+
15
+ builder.build.exec
10
16
  ret
11
17
  end
12
18
  end
@@ -2,6 +2,7 @@ require 'gli'
2
2
  require 'threatinator/actions/run'
3
3
  require 'threatinator/actions/list'
4
4
  require 'threatinator/config/feed_search'
5
+ require 'threatinator/config/logger'
5
6
  require 'threatinator/cli/list_action_builder'
6
7
  require 'threatinator/cli/run_action_builder'
7
8
  require 'threatinator/plugin_loader'
@@ -49,7 +50,10 @@ module Threatinator
49
50
  end
50
51
 
51
52
  class Parser
53
+ include Helpers
54
+
52
55
  attr_accessor :builder
56
+ attr_reader :config_hash, :extra_args
53
57
  attr_reader :run_action_config_class
54
58
 
55
59
  def initialize
@@ -64,6 +68,11 @@ module Threatinator
64
68
  @mod.run(args)
65
69
  end
66
70
 
71
+ def set_opts(global_options, options, args)
72
+ @config_hash = fix_opts(global_options.merge(options))
73
+ @extra_args = args
74
+ end
75
+
67
76
  def _init_mod
68
77
  parser = self
69
78
  Module.new do
@@ -72,6 +81,7 @@ module Threatinator
72
81
 
73
82
  program_desc 'Threatinator!'
74
83
 
84
+ add_cli_args(self, Threatinator::Config::Logger.properties('logger'))
75
85
  add_cli_args(self, Threatinator::Config::FeedSearch.properties('feed_search'))
76
86
 
77
87
  desc "fetch and parse a feed"
@@ -88,9 +98,9 @@ module Threatinator
88
98
  options["run.feed_name"] = args.shift
89
99
  end
90
100
 
91
- opts = fix_opts(global_options.merge(options))
101
+ parser.set_opts(global_options, options, args)
92
102
 
93
- builder = Threatinator::CLI::RunActionBuilder.new(opts, args, parser.run_action_config_class)
103
+ builder = Threatinator::CLI::RunActionBuilder.new(parser.config_hash, parser.extra_args, parser.run_action_config_class)
94
104
  parser.builder = builder
95
105
  end
96
106
  end
@@ -99,8 +109,8 @@ module Threatinator
99
109
  command :list do |c|
100
110
  add_cli_args(c, Threatinator::Actions::List::Config.properties('list'))
101
111
  c.action do |global_options, options, args|
102
- opts = fix_opts(global_options.merge(options))
103
- parser.builder = Threatinator::CLI::ListActionBuilder.new(opts, args)
112
+ parser.set_opts(global_options, options, args)
113
+ parser.builder = Threatinator::CLI::ListActionBuilder.new(parser.config_hash, parser.extra_args)
104
114
  end
105
115
  end
106
116
  end
@@ -1,6 +1,7 @@
1
1
  module Threatinator
2
2
  module Config
3
3
  require 'threatinator/config/feed_search'
4
+ require 'threatinator/config/logger'
4
5
  end
5
6
  end
6
7
 
@@ -0,0 +1,14 @@
1
+ require 'threatinator/config/base'
2
+ require 'threatinator/logger'
3
+
4
+ module Threatinator
5
+ module Config
6
+ class Logger < Threatinator::Config::Base
7
+ attribute :level, String, default: Threatinator::Logger.level_string,
8
+ coercer: lambda { |v| v.to_s.upcase },
9
+ description: "Set the logging level: #{::Threatinator::Logger.levels.join(',')}"
10
+ end
11
+ end
12
+ end
13
+
14
+
@@ -1,28 +1,38 @@
1
- require 'threatinator/property_definer'
1
+ require 'threatinator/model/base'
2
+ require 'threatinator/model/observables/ipv4_collection'
3
+ require 'threatinator/model/observables/fqdn_collection'
4
+ require 'threatinator/model/observables/url_collection'
5
+ require 'equalizer'
2
6
  require 'set'
3
7
 
4
8
  module Threatinator
5
- class Event
6
- include Threatinator::PropertyDefiner
9
+ class Event < Threatinator::Model::Base
10
+ include Equalizer.new(:feed_provider, :feed_name, :type, :ipv4s, :fqdns, :urls)
11
+ attr_reader :feed_provider, :feed_name, :type, :ipv4s, :fqdns, :urls
7
12
 
8
13
  VALID_TYPES = Set.new([:c2, :attacker, :malware_host, :spamming, :scanning, :phishing])
9
14
 
10
- def initialize(opts = {})
11
- _parse_properties(opts)
12
- end
13
-
14
- property :feed_provider, type: String
15
- property :feed_name, type: String
16
- property :type, type: Symbol, validate: lambda { |obj, val| VALID_TYPES.include?(val) }
17
- property :ipv4s, type: Array, default: lambda { Array.new }
18
- property :fqdns, type: Array, default: lambda { Array.new }
15
+ validates :feed_provider, :feed_name, type: ::String
16
+ validates :type, type: ::Symbol, allow_nil: false, inclusion: {in: VALID_TYPES}
17
+ validates :ipv4s, type: Threatinator::Model::Observables::Ipv4Collection
18
+ validates :fqdns, type: Threatinator::Model::Observables::FqdnCollection
19
+ validates :urls, type: Threatinator::Model::Observables::UrlCollection
19
20
 
20
- def add_ipv4(ipv4)
21
- self.ipv4s << ipv4
22
- end
23
-
24
- def add_fqdn(fqdn)
25
- self.fqdns << fqdn
21
+ # @param [Hash] opts
22
+ # @option opts [String] :feed_provider The name of the feed provider
23
+ # @option opts [String] :feed_name The name of the feed
24
+ # @option opts [Symbol] :type The 'type' of feed.
25
+ # @option opts [#each] :ipv4s A collection of ipv4s
26
+ # @option opts [#each] :fqdns A collection of FQDNs
27
+ # @option opts [#each] :urls A collection of Urls
28
+ def initialize(opts = {})
29
+ @feed_provider = opts[:feed_provider]
30
+ @feed_name = opts[:feed_name]
31
+ @type = opts[:type]
32
+ @ipv4s = Threatinator::Model::Observables::Ipv4Collection.new(opts[:ipv4s] || [])
33
+ @fqdns = Threatinator::Model::Observables::FqdnCollection.new(opts[:fqdns] || [])
34
+ @urls = Threatinator::Model::Observables::UrlCollection.new(opts[:urls] || [])
35
+ super()
26
36
  end
27
37
  end
28
38
  end
@@ -1,41 +1,70 @@
1
1
  require 'threatinator/event'
2
+ require 'threatinator/exceptions'
3
+ require 'threatinator/model/observables/ipv4'
4
+ require 'ip'
2
5
 
3
6
  module Threatinator
4
7
  class EventBuilder
5
- attr_reader :total
6
- def initialize(feed)
7
- @feed = feed
8
- @built_events = []
9
- @total = 0
8
+ attr_writer :type
9
+
10
+ def initialize(feed_provider, feed_name)
11
+ @feed_provider = feed_provider
12
+ @feed_name = feed_name
13
+ self.reset
10
14
  end
11
15
 
12
- def each_built_event
13
- @built_events.each do |event|
14
- yield event
15
- end
16
- @built_events.clear
16
+ def reset
17
+ @type = nil
18
+ @ipv4s = []
19
+ @fqdns = []
20
+ @urls = []
17
21
  end
18
22
 
19
- def count
20
- @built_events.count
23
+ def build
24
+ opts = {
25
+ feed_provider: @feed_provider,
26
+ feed_name: @feed_name,
27
+ }
28
+ opts[:type] = @type unless @type.nil?
29
+
30
+ ret = Threatinator::Event.new(opts)
31
+
32
+ @ipv4s.each do |ipv4, opts|
33
+ opts = opts.dup
34
+ if ipv4.is_a?(::String)
35
+ ipv4 = ::IP::V4.parse(ipv4)
36
+ end
37
+ opts[:ipv4] = ipv4
38
+ ret.ipv4s << Threatinator::Model::Observables::Ipv4.new(opts)
39
+ end
40
+ @fqdns.each do |fqdn|
41
+ ret.fqdns << fqdn
42
+ end
43
+ @urls.each do |url|
44
+ url = begin
45
+ ::Addressable::URI.parse(url)
46
+ rescue TypeError => e
47
+ raise Threatinator::Exceptions::EventBuildError, "Failed to parse URL"
48
+ end
49
+ ret.urls << url
50
+ end
51
+ ret
52
+ rescue Threatinator::Exceptions::InvalidAttributeError => e
53
+ raise Threatinator::Exceptions::EventBuildError, e.message
21
54
  end
22
55
 
23
- def clear
24
- @built_events.clear
56
+ def add_fqdn(fqdn)
57
+ @fqdns << fqdn
25
58
  end
26
59
 
27
- def create_event_proc
28
- self.method(:create_event).to_proc
60
+ def add_ipv4(ipv4, opts = {})
61
+ @ipv4s << [ipv4, opts]
29
62
  end
30
63
 
31
- def create_event
32
- event = Threatinator::Event.new
33
- event.feed_provider = @feed.provider
34
- event.feed_name = @feed.name
35
- yield(event)
36
- @total += 1
37
- @built_events << event
64
+ def add_url(url)
65
+ @urls << url
38
66
  end
39
67
  end
40
68
  end
41
69
 
70
+
@@ -30,12 +30,9 @@ module Threatinator
30
30
  end
31
31
 
32
32
  class InvalidAttributeError < StandardError
33
- attr_reader :attribute, :got
34
- def initialize(attribute, got)
35
- @attribute = attribute
36
- @got = got
37
- super("Invalid value for attribute '#{attribute}'. Got " + got.inspect)
38
- end
33
+ end
34
+
35
+ class EventBuildError < StandardError
39
36
  end
40
37
 
41
38
  class AlreadyRegisteredError < StandardError