nipper_parser 1.0.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5eb54da76791f956afd5e6c7c845127c02bbb39b
4
- data.tar.gz: 68702d1dd51b46f06b97d82bfb45940d5137dc0f
3
+ metadata.gz: 4a042f45d32532f487c29dca148378d91aa7e599
4
+ data.tar.gz: 6403288acfcc080a3e27bac6c0a91ae450b9ed3f
5
5
  SHA512:
6
- metadata.gz: 3c1e8c381bf6ced1f2324841c17a3b3f6e873744914b902a0bf408e5d0ce3956b28f9b7a025396378f6f2729b826c6e298f7f1a55e6b41bce9e58803af0bc2f6
7
- data.tar.gz: afa11d53d7ae2ca158ca347cd3279d893a64f1f3c5b852e0985bddc49c331999499e1249483e6c7e9ffeb495c68a551fad2fca6208ec0231462fc2c644665ba9
6
+ metadata.gz: eb512be1015bfd3c4cab072828b6122cdb9062b76dc127ea8058fd2c97e62743961fd505930890fedcc931d8b1f4f0a5d577806076049927e407be6fb7bc3d40
7
+ data.tar.gz: 718322087f9b8c07cb6c4ac02f110402c742383447b0b9265880ab8ee6d3cf16df3e22ab2213bd4c9a905f425140c677815363072b13881bcd3c26d46ba36847
@@ -1,5 +1,8 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.1
5
- before_install: gem install bundler -v 1.14.5
4
+ - 2.3.0
5
+ - 2.4.0
6
+ before_install:
7
+ - gem install bundler -v 1.14.5
8
+ - bundle install
data/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # NipperParser
2
- [![travis-cli](https://api.travis-ci.org/KINGSABRI/nipper_parser.svg)](https://travis-ci.org/KINGSABRI/nipper_parser/)
2
+ [![Gem Version](https://badge.fury.io/rb/nipper_parser.svg)](https://badge.fury.io/rb/nipper_parser)
3
3
  [![Code Climate](https://codeclimate.com/github/KINGSABRI/nipper_parser/badges/gpa.svg)](https://codeclimate.com/github/KINGSABRI/nipper_parser)
4
4
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8c81748967664cc5bb92147581fb6802)](https://www.codacy.com/app/king-sabri/attack-domain?utm_source=github.com&utm_medium=referral&utm_content=KINGSABRI/nipper_parser&utm_campaign=Badge_Grade)
5
5
  [![inch-ci](https://inch-ci.org/github/KINGSABRI/nipper_parser.svg?branch=master)](https://inch-ci.org/github/KINGSABRI/nipper_parser)
6
- [![Gem Version](https://badge.fury.io/rb/nipper_parser.svg)](https://badge.fury.io/rb/nipper_parser)
7
6
 
8
7
  NipperParser gem is an unofficial parser for [Titania Nipper Studio](https://www.titania.com/products/nipper-studio) XML report.
9
8
 
@@ -12,21 +11,21 @@ NipperParser gem is an unofficial parser for [Titania Nipper Studio](https://www
12
11
 
13
12
  | Modules / Sections | Supported |
14
13
  |------------------------|-----------|
15
- | Information | x |
16
- | Security Audit | x |
17
- | Vulnerability Audit | x |
14
+ | Information | |
15
+ | Security Audit | |
16
+ | Vulnerability Audit | |
18
17
  | CIS Benchmarks | |
19
18
  | STIG Compliance | |
20
19
  | SANS Policy Compliance | |
21
20
  | PCI Audit | |
22
- | Filtering Complexity | |
21
+ | Filtering Complexity ||
23
22
  | Configuration Report | |
24
23
  | Raw Configuration | |
25
24
  | Raw Change Tracking | |
26
25
  | Appendix | |
27
26
 
28
27
 
29
- ## Installation (not published yet)
28
+ ## Installation
30
29
 
31
30
  ```ruby
32
31
  gem install nipper_parser
@@ -1,11 +1,13 @@
1
- # lib = File.expand_path('..', __FILE__)
2
- # $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
1
+ lib = File.expand_path('..', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  require 'nokogiri'
5
5
  require 'nipper_parser/version'
6
6
  require 'nipper_parser/parsers/parser_utils'
7
7
  require 'nipper_parser/parsers/information'
8
8
  require 'nipper_parser/parsers/security_audit'
9
+ require 'nipper_parser/parsers/vulnerability_audit'
10
+ require 'nipper_parser/parsers/filtering_complexity'
9
11
 
10
12
  module NipperParser
11
13
 
@@ -36,12 +38,23 @@ module NipperParser
36
38
  alias_method :open, :new
37
39
  end
38
40
 
39
- attr_reader :information, :security_audit
41
+ # @!attribute #information for report general information section, it calls [Information] class
42
+ attr_reader :information
43
+ # @!attribute #security_audit for security audit section, it calls [SecurityAudit] class
44
+ attr_reader :security_audit
45
+ # @!attribute #vulnerability_audit for report vulnerability audit section, it calls [VulnerabilityAudit] class
46
+ attr_reader :vulnerability_audit
47
+ # @!attribute #filtering_complexity for report filtering complexity section, it calls [FilteringComplexity] class
48
+ attr_reader :filtering_complexity
49
+
40
50
  def initialize(file)
41
51
  config_parsed = Nokogiri::XML(File.open(file))
52
+
42
53
  # instantiate all parsers
43
- @information = Information.new(config_parsed)
44
- @security_audit = SecurityAudit.new(config_parsed)
54
+ @information = Information.new(config_parsed)
55
+ @security_audit = SecurityAudit.new(config_parsed)
56
+ @vulnerability_audit = VulnerabilityAudit.new(config_parsed)
57
+ @filtering_complexity = FilteringComplexity.new(config_parsed)
45
58
  end
46
59
  end
47
60
 
@@ -55,13 +68,48 @@ if __FILE__ == $0
55
68
  pp nipper_parser.information.title
56
69
  pp nipper_parser.information.author
57
70
  pp nipper_parser.information.date
58
- pp nipper_parser.security_audit
71
+ pp nipper_parser.security_audit.title
72
+ pp nipper_parser.security_audit.introduction.security_issue_overview
59
73
  pp nipper_parser.security_audit.findings
60
- pp nipper_parser.security_audit.findings[0].class
61
- pp nipper_parser.security_audit.findings[0].title
62
- pp nipper_parser.security_audit.findings[0].impact
74
+ finding = nipper_parser.security_audit.findings[0]
75
+ pp finding.class
76
+ pp finding.title
77
+ pp finding.impact
63
78
  pp nipper_parser.security_audit.conclusions
64
79
  pp nipper_parser.security_audit.conclusions.per_device
65
80
  pp nipper_parser.security_audit.recommendations.list
66
81
  pp nipper_parser.security_audit.mitigation_classification
82
+ pp nipper_parser.vulnerability_audit.class
83
+ pp nipper_parser.vulnerability_audit.title
84
+ pp nipper_parser.vulnerability_audit.introduction
85
+ pp nipper_parser.vulnerability_audit.introduction.excluded_devices
86
+ cve = nipper_parser.vulnerability_audit.cves[0]
87
+ pp cve.title
88
+ pp cve.rating
89
+ pp cve.summary
90
+ pp cve.affected_devices
91
+ pp cve.vendor_sec_advisories
92
+ pp cve.references
93
+ pp nipper_parser.vulnerability_audit.conclusions
94
+ pp nipper_parser.vulnerability_audit.conclusions.list_critical
95
+ pp nipper_parser.vulnerability_audit.recommendations
96
+ pp nipper_parser.filtering_complexity
97
+ pp nipper_parser.filtering_complexity.title
98
+ pp nipper_parser.filtering_complexity.introduction
99
+ pp nipper_parser.filtering_complexity.introduction.devices
100
+ observations = nipper_parser.filtering_complexity.observations
101
+ puts "Number of observations: #{observations.size}"
102
+ observation = observations[2]
103
+ pp observation.title
104
+ pp observation.index
105
+ pp observation.ref
106
+ pp observation.overview
107
+ pp observation.affected_devices
108
+ pp observation.affected_devices[0].title
109
+ puts
110
+ pp observation.affected_devices[0].details
111
+ puts
112
+ pp observation.affected_devices[0].details_tables[0].title
113
+ pp observation.affected_devices[0].details_tables[0].tables
114
+
67
115
  end
@@ -41,14 +41,14 @@ experience.
41
41
  #### Usage
42
42
 
43
43
  ```ruby
44
+ pp security_audit = nipper_parser.security_audit
45
+
44
46
  # - Introduction
45
47
  pp security_audit.introduction.class
46
48
  pp security_audit.introduction.title
47
49
  pp security_audit.introduction.date
48
50
  pp security_audit.introduction.security_issue_overview
49
-
50
51
  # - Findings
51
- pp security_audit = nipper_parser.security_audit
52
52
  pp security_audit.findings
53
53
  finding = security_audit.findings[0] # Play wit a finding
54
54
  pp finding.class
@@ -85,18 +85,33 @@ A report detailing publically known software vulnerabilities in the device firmw
85
85
  manufacturer and third-party references.
86
86
 
87
87
  **Vulnerability Audit Section Contains:**
88
- - Introduction [not yet implemented - PR is welcome]
89
- - CVEs list [not yet implemented - PR is welcome]
90
- - Conclusions [not yet implemented - PR is welcome]
91
- - Recommendations [not yet implemented - PR is welcome]
88
+ - Introduction [implemented]
89
+ - CVEs list [implemented]
90
+ - Conclusions [implemented]
91
+ - Recommendations [implemented]
92
92
 
93
93
  #### Usage
94
94
 
95
95
  ```ruby
96
+ vulnerability_audit = nipper_parser.vulnerability_audit
97
+
96
98
  # - Introduction
99
+ pp vulnerability_audit.class
100
+ pp vulnerability_audit.introduction
101
+ pp vulnerability_audit.introduction.excluded_devices
97
102
  # - CVEs
103
+ cve = vulnerability_audit.cves[0]
104
+ pp cve.title
105
+ pp cve.rating
106
+ pp cve.summary
107
+ pp cve.affected_devices
108
+ pp cve.vendor_sec_advisories
109
+ pp cve.references
98
110
  # - Conclusions
111
+ pp vulnerability_audit.conclusions.class
112
+ pp vulnerability_audit.conclusions.list_critical
99
113
  # - Recommendations
114
+ pp vulnerability_audit.recommendations.list
100
115
  ```
101
116
 
102
117
  ### CIS Benchmarks
@@ -174,7 +189,24 @@ group recursion and more.
174
189
 
175
190
  ```ruby
176
191
  # - Introduction
192
+ filtering = nipper_parser.filtering_complexity
193
+ pp filtering.title
194
+ pp filtering.introduction
195
+ pp filtering.introduction.devices
196
+
177
197
  # - Observations
198
+ observations = filtering.observations
199
+ puts "Number of observations: #{observations.size}"
200
+ observation = observations[0]
201
+ pp observation.title
202
+ pp observation.index
203
+ pp observation.ref
204
+ pp observation.overview
205
+ pp observation.affected_devices
206
+ pp observation.affected_devices[0].title
207
+ pp observation.affected_devices[0].details
208
+ pp observation.affected_devices[0].details_tables[0].title
209
+ pp observation.affected_devices[0].details_tables[0].tables
178
210
  ```
179
211
 
180
212
  ### Configuration Report
@@ -0,0 +1,155 @@
1
+ module NipperParser
2
+
3
+ # FilteringComplexity parses the 'Filtering Complexity' part.
4
+ # Filtering Complexity part contains the following sections:
5
+ # - introduction
6
+ # - Observations
7
+ #
8
+ # @example Basic Usage:
9
+ # require 'nokogiri'
10
+ # require 'pp'
11
+ # config = Nokogiri::XML open(ARGV[0])
12
+ # vulnerability_audit = NipperParser::FilteringComplexity.new(config)
13
+ # pp FilteringComplexity.class
14
+ # pp FilteringComplexity.introduction
15
+ # pp FilteringComplexity.introduction.excluded_devices
16
+ # filter = FilteringComplexity.cves[0]
17
+ #
18
+ # @param config [Nokogiri::XML] parsed XML
19
+ # @attr_reader title the report title
20
+ # @attr_reader config a parsed XML [Nokogiri::XML] object
21
+ class FilteringComplexity
22
+ include ParserUtils
23
+
24
+ # Skeleton for SecurityAudit parts
25
+
26
+ Introduction = Struct.new(
27
+ :index,
28
+ :title, :ref, :devices,
29
+ :security_issue_overview, :rating
30
+ )
31
+
32
+ Observation = Struct.new(
33
+ :index, :title, :ref, :overview,
34
+ :affected_devices, :false_positive
35
+ )
36
+
37
+ attr_reader :config, :title
38
+
39
+ # @param config [Nokogiri::XML::Document]
40
+ def initialize(config)
41
+ part = config.xpath("//report/part[@ref='COMPLEXITY']")
42
+ @config = part[0].elements
43
+ @title = part[0].attributes['title'].text
44
+
45
+ end
46
+
47
+ # Introduction of the Security Audit report
48
+ def introduction
49
+ intro = @config[0]
50
+ attribute = attributes(intro)
51
+ index = attribute.index
52
+ title = attribute.title
53
+ reference = attribute.ref
54
+ devices = generate_table(intro.elements[1].elements)
55
+
56
+ Introduction.new(index, title, reference, devices)
57
+ end
58
+
59
+ # observations parses observations
60
+ #
61
+ # @return [Array<Observation>]
62
+ def observations
63
+ obs = @config.to_a.clone
64
+ obs.shift # pop first item, the introduction
65
+ @observations = obs.map do |observation|
66
+
67
+ Observation.new(
68
+ attributes(observation).index,
69
+ attributes(observation).title,
70
+ attributes(observation).ref,
71
+ observation.elements[0].text.strip, # overview
72
+ affected_devices(observation), # affected_devices
73
+ false # observation can be marked as a false positive
74
+ )
75
+ end
76
+
77
+ end
78
+
79
+ # List all false positive observations
80
+ #
81
+ # @return [Array<Observation>]
82
+ def false_positive
83
+ observations.select(&:false_positive)
84
+ end
85
+
86
+ private
87
+ AffectedDevice = Struct.new(
88
+ :index, :title, :ref,
89
+ :details, :details_tables
90
+ )
91
+ # affected_devices parses affected devices from give Observation object. @see #observations
92
+ #
93
+ # @param observation [Nokogiri::XML::Element]
94
+ # @return [Array<AffectedDevices>]
95
+ def affected_devices(observation)
96
+ obs_devices = observation.elements
97
+ obs_devices.shift # pop first item, the overview
98
+
99
+ obs_devices.map do |device|
100
+ AffectedDevice.new(
101
+ attributes(device).index, #fixme affected device index should not be same as observation index
102
+ attributes(device).title,
103
+ attributes(device).ref,
104
+ device.elements[0].text, # details
105
+ details_tables(device) # details tables
106
+ )
107
+ end
108
+ end
109
+
110
+ DetailsTable = Struct.new(
111
+ :index, :title, :ref,
112
+ :tables
113
+ )
114
+ # details_tables parses tables of affected devices from give device. @see #affected_devices
115
+ #
116
+ # @param device [Nokogiri::XML::Element]
117
+ # @return [Array<AffectedDevices>]
118
+ def details_tables(device)
119
+ tables = device.elements
120
+ tables.shift
121
+ begin
122
+ tables.map do |table|
123
+ DetailsTable.new(
124
+ attributes(table).index,
125
+ attributes(table).title,
126
+ attributes(table).ref,
127
+ generate_table(table.elements) # tables
128
+ )
129
+ end
130
+ rescue
131
+ # tables.map do |table|
132
+ # DetailsTable.new(
133
+ # nil, nil, nil,
134
+ # tables.xpath('listitem').map(&:text)
135
+ # )
136
+ # end
137
+
138
+ tables.xpath('listitem').map(&:text)
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+ end
145
+
146
+
147
+
148
+ if __FILE__ == $0
149
+ require 'nokogiri'
150
+ require 'pp'
151
+ config = Nokogiri::XML open(ARGV[0])
152
+ filter = NipperParser::FilteringComplexity.new(config)
153
+ pp filter.introduction.class
154
+ pp filter.introduction.index
155
+ end
@@ -1,3 +1,6 @@
1
+ require 'date'
2
+
3
+
1
4
  module NipperParser
2
5
 
3
6
  # ParserUtils is a helper module for parsers' quick and dirty operations.
@@ -26,13 +29,16 @@ module NipperParser
26
29
  end
27
30
 
28
31
  Attribute = Struct.new(:index, :title, :ref)
29
- # @param attr [Nokogiri::XML::Element] attributes
30
- # @return [Hash<Attribute>]
32
+ # @param attr [Nokogiri::XML::Element]
33
+ # @return [ParserUtils::Attribute]
31
34
  def attributes(attr)
35
+ require 'pp'
36
+ # pp caller_locations
37
+
32
38
  Attribute.new(
33
- attr.attributes['index'].text,
39
+ attr.attributes['index'].text.to_f,
34
40
  attr.attributes['title'].text,
35
- attr.attributes['ref'].text
41
+ attr.attributes['ref'].text,
36
42
  )
37
43
  end
38
44
 
@@ -1,5 +1,6 @@
1
1
  require 'date'
2
2
  require_relative 'parser_utils'
3
+
3
4
  module NipperParser
4
5
 
5
6
  # SecurityAudit parses the 'Security Audit' part including all it's sections.
@@ -96,10 +97,13 @@ module NipperParser
96
97
  )
97
98
 
98
99
  attr_reader :config, :title
100
+
99
101
  # @param config [Nokogiri::XML::Document]
100
102
  def initialize(config)
101
- @config = config.xpath("//report/part[@ref='SECURITYAUDIT']")[0].elements
102
- @title = @config[0].elements[1].attributes['title'].text
103
+ part = config.xpath("//report/part[@ref='SECURITYAUDIT']")
104
+ @config = part[0].elements
105
+ @title = part[0].attributes['title'].text
106
+
103
107
  introduction
104
108
  findings
105
109
  end
@@ -107,9 +111,10 @@ module NipperParser
107
111
  # Introduction of the Security Audit report
108
112
  def introduction
109
113
  intro = @config[0]
110
- index = attributes(intro).index
111
- title = attributes(intro).title
112
- reference = attributes(intro).ref.to_i
114
+ attribute = attributes(intro)
115
+ index = attribute.index
116
+ title = attribute.title
117
+ reference = attribute.ref
113
118
  date = Date.parse(intro.elements[0].text).to_s
114
119
  devices = generate_table(intro.elements[1].elements)
115
120
  security_issue_overview = {}
@@ -133,7 +138,7 @@ module NipperParser
133
138
 
134
139
  @findings = findings.map do |finding|
135
140
  Finding.new(
136
- attributes(finding).index.to_f,
141
+ attributes(finding).index,
137
142
  attributes(finding).title,
138
143
  attributes(finding).ref,
139
144
  finding.elements[0].elements[0].elements.map(&:attributes), # affected_devices
@@ -149,7 +154,7 @@ module NipperParser
149
154
  # Conclusions
150
155
  def conclusions
151
156
  conc = @config.search("section[@ref='SECURITY.CONCLUSIONS']")[0]
152
- index = attributes(conc).index.to_f
157
+ index = attributes(conc).index
153
158
  title = attributes(conc).title
154
159
  reference = attributes(conc).ref
155
160
  per_device = generate_table(conc.elements[1].elements)
@@ -171,7 +176,7 @@ module NipperParser
171
176
  # Recommendations
172
177
  def recommendations
173
178
  recom = @config.search("section[@ref='SECURITY.RECOMMENDATIONS']")[0]
174
- index = attributes(recom).index.to_f
179
+ index = attributes(recom).index
175
180
  title = attributes(recom).title
176
181
  reference = attributes(recom).ref
177
182
  list = generate_table(recom.elements[1].elements)
@@ -286,7 +291,6 @@ end
286
291
  if __FILE__ == $0
287
292
  require 'nokogiri'
288
293
  require 'pp'
289
- require_relative 'parser_utils'
290
294
  config = Nokogiri::XML open(ARGV[0])
291
295
  security_audit = NipperParser::SecurityAudit.new(config)
292
296
  pp security_audit.introduction.class
@@ -0,0 +1,158 @@
1
+ module NipperParser
2
+
3
+ # VulnerabilityAudit parse the 'Vulnerability Audit' part.
4
+ # Vulnerability Audit part contains the following sections:
5
+ # - introduction
6
+ # - CVEs
7
+ # - Conclusions
8
+ # - Recommendations
9
+ #
10
+ # @example Basic Usage:
11
+ # require 'nokogiri'
12
+ # require 'pp'
13
+ # config = Nokogiri::XML open(ARGV[0])
14
+ # vulnerability_audit = NipperParser::VulnerabilityAudit.new(config)
15
+ # pp vulnerability_audit.class
16
+ # pp vulnerability_audit.introduction
17
+ # pp vulnerability_audit.introduction.excluded_devices
18
+ # cve = vulnerability_audit.cves[0]
19
+ # pp cve.title
20
+ # pp cve.rating
21
+ # pp cve.summary
22
+ # pp cve.affected_devices
23
+ # pp cve.vendor_sec_advisories
24
+ # pp cve.references
25
+ # pp nipper_parser.vulnerability_audit.conclusions
26
+ # pp nipper_parser.vulnerability_audit.conclusions.list_critical
27
+ # pp nipper_parser.vulnerability_audit.recommendations
28
+ #
29
+ # @param config [Nokogiri::XML] parsed XML
30
+ # @attr_reader title the report title
31
+ # @attr_reader config a parsed XML [Nokogiri::XML] object
32
+ class VulnerabilityAudit
33
+ include ParserUtils
34
+
35
+ # Skeleton for SecurityAudit parts
36
+ Introduction = Struct.new(
37
+ :index, :title, :ref, :date, :devices,
38
+ :excluded_devices
39
+ )
40
+ CVE = Struct.new(
41
+ :index, :title, :ref,
42
+ :rating, :summary, :affected_devices,
43
+ :vendor_sec_advisories, :references
44
+ )
45
+ Conclusion = Struct.new(
46
+ :index, :title, :ref,
47
+ :per_device, :per_rating,
48
+ :list_critical, :list_high,
49
+ :list_medium, :list_low
50
+ )
51
+ Recommendations = Struct.new(
52
+ :index, :title, :ref,
53
+ :list
54
+ )
55
+
56
+ attr_reader :config, :title
57
+
58
+ # @param config [Nokogiri::XML::Document]
59
+ def initialize(config)
60
+ part = config.xpath("//report/part[@ref='VULNAUDIT']")
61
+ @config = part[0].elements
62
+ @title = part[0].attributes['title'].text
63
+ end
64
+
65
+ # Introduction of the Security Audit report
66
+ def introduction
67
+ intro = @config[0]
68
+ attribute = attributes(intro)
69
+ index = attribute.index
70
+ title = attribute.title
71
+ reference = attribute.ref
72
+ date = Date.parse(intro.elements[0].text).to_s
73
+ devices = generate_table(intro.elements[1].elements)
74
+ excluded = {devices: @config[0].elements[3].elements.map(&:text), # TODO enhance excluded results, need more excluded cases to see structure
75
+ reason: @config[0].elements[2].text}
76
+
77
+ Introduction.new(
78
+ index, title, reference,
79
+ date, devices, excluded
80
+ )
81
+ end
82
+
83
+
84
+ def cves
85
+ cves = @config.to_a.clone
86
+ cves.shift # pop first item, the introduction
87
+ cves.pop(2) # pop last 2 items, conclusion, recommendations
88
+
89
+ cves.map.with_index do |cve, i|
90
+ CVE.new(
91
+ attributes(cve).index,
92
+ attributes(cve).title,
93
+ attributes(cve).ref,
94
+ cve.elements[0], # FIXME rating
95
+ cve.elements[1].elements.text, # summary
96
+ # cve.elements[2].elements[1].nil?? cve.elements[2].elements.map{|d| d.text} : cve.elements[2].elements[1].elements.map(&:text),
97
+ # this fix some affected devices scenario
98
+ if cve.elements[2].elements[1].nil?
99
+ cve.elements[2].elements.map{|d| d.text}
100
+ else
101
+ cve.elements[2].elements[1].elements.map(&:text)
102
+ end,
103
+ cve.elements[3].elements[1].elements.map(&:text), # vendor_sec_advisories
104
+ cve.elements[4].nil?? [] : cve.elements[4].elements[1].elements.map(&:text) # references, check if no references
105
+ )
106
+ end
107
+ end
108
+
109
+ # Conclusions
110
+ def conclusions
111
+ conc = @config.search("section[@ref='VULNAUDIT.CONCLUSIONS']")[0]
112
+ attribute = attributes(conc)
113
+ index = attribute.index
114
+ title = attribute.title
115
+ reference = attribute.ref
116
+ per_device = generate_table(conc.elements[1].elements)
117
+ summary_findings = generate_table(conc.elements[3].elements)
118
+ per_rating = {
119
+ critical: summary_findings.select{|finding| finding[:rating] == 'Critical'},
120
+ high: summary_findings.select{|finding| finding[:rating] == 'High'},
121
+ medium: summary_findings.select{|finding| finding[:rating] == 'Medium'},
122
+ low: summary_findings.select{|finding| finding[:rating] == 'Low'},
123
+ }
124
+
125
+ Conclusion.new(
126
+ index, title, reference, per_device, per_rating,
127
+ per_rating[:critical], per_rating[:high],
128
+ per_rating[:medium], per_rating[:low]
129
+ )
130
+ end
131
+
132
+ # Recommendations
133
+ def recommendations
134
+ recom = @config.search("section[@ref='VULNAUDIT.RECOMMENDATIONS']")[0]
135
+ attribute = attributes(recom)
136
+ index = attribute.index
137
+ title = attribute.title
138
+ reference = attribute.ref
139
+ list = recom.elements[2].elements.map(&:text)
140
+
141
+ Recommendations.new(
142
+ index, title, reference,
143
+ list
144
+ )
145
+ end
146
+
147
+ end
148
+ end
149
+
150
+
151
+
152
+ if __FILE__ == $0
153
+ require 'nokogiri'
154
+ require 'pp'
155
+ require_relative 'parser_utils'
156
+
157
+
158
+ end
@@ -1,3 +1,3 @@
1
1
  module NipperParser
2
- VERSION = '1.0.0'
2
+ VERSION = '1.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nipper_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - KING SABRI
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-09 00:00:00.000000000 Z
11
+ date: 2017-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -71,13 +71,14 @@ files:
71
71
  - lib/nipper_parser.rb
72
72
  - lib/nipper_parser/parsers/README.md
73
73
  - lib/nipper_parser/parsers/cis_compliance.rb
74
+ - lib/nipper_parser/parsers/filtering_complexity.rb
74
75
  - lib/nipper_parser/parsers/information.rb
75
76
  - lib/nipper_parser/parsers/parser_utils.rb
76
77
  - lib/nipper_parser/parsers/pci_audit.rb
77
78
  - lib/nipper_parser/parsers/sans_compliance.rb
78
79
  - lib/nipper_parser/parsers/security_audit.rb
79
80
  - lib/nipper_parser/parsers/stig_compliance.rb
80
- - lib/nipper_parser/parsers/vulnerabilty_audit.rb
81
+ - lib/nipper_parser/parsers/vulnerability_audit.rb
81
82
  - lib/nipper_parser/version.rb
82
83
  - nipper_parser.gemspec
83
84
  homepage: https://github.com/KINGSABRI/nipper_parser
@@ -1,102 +0,0 @@
1
- module NipperParser
2
-
3
- # VulnerabilityAudit parse the 'Vulnerability Audit' part.
4
- # Vulnerability Audit part contains the following sections:
5
- # - introduction
6
- # - CVEs
7
- # - Conclusions
8
- # - Recommendations
9
- #
10
- #
11
- #
12
- #
13
- class VulnerabilityAudit
14
- include ParserUtils
15
-
16
- # Skeleton for SecurityAudit parts
17
- Introduction = Struct.new(
18
- :index, :title, :ref, :date, :devices,
19
- :security_issue_overview, :rating
20
- )
21
- CVE = Struct.new(
22
- :index, :title, :ref,
23
- :rating, :summary, :affected_devices,
24
- :vendor_sec_advisories, :references
25
- )
26
- Conclusion = Struct.new(
27
- :index, :title, :ref,
28
- :per_device, :per_rating,
29
- :list_critical, :list_high,
30
- :list_medium, :list_low, :list_info
31
- )
32
- Recommendations = Struct.new(
33
- :index, :title, :ref,
34
- :list
35
- )
36
-
37
- attr_reader :config, :title
38
-
39
- def initialize(config)
40
- @config = config.xpath("//report/part[@ref='VULNAUDIT']")[0].elements
41
- @title = @config[0].elements[1].attributes['title'].text
42
- end
43
-
44
- # CVEs
45
- def cves
46
- cves = @config.to_a.clone
47
- cves.shift # pop first item, the introduction
48
- cves.pop(2) # pop last 2 item, conclusion, recommendations
49
-
50
- cves.map do |cve|
51
- CVE.new(
52
- attributes(cve).index,
53
- attributes(cve).title,
54
- attributes(cve).ref,
55
- cve.elements[0], # FIXME
56
- cve.elements[1].elements.text, # summary
57
- cve.elements[2].elements[1].elements.map(&:text), # affect_devices
58
- cve.elements[3].elements[1].elements.map(&:text), # vendor_sec_advisories
59
- cve.elements[4].elements[1].elements.map(&:text), # references
60
- )
61
- end
62
-
63
- end
64
-
65
- # Conclusions
66
- def conclusions
67
- conc = @config[-2]
68
- index = attributes(conc).index
69
- title = attributes(conc).title
70
- reference = attributes(conc).ref
71
- per_device = generate_table(conc.elements[1].elements)
72
- per_rating = {
73
- critical: conc.elements[3].elements.map(&:text),
74
- high: conc.elements[5].elements.map(&:text),
75
- medium: conc.elements[7].elements.map(&:text),
76
- low: conc.elements[9].elements.map(&:text),
77
- info: conc.elements[11].elements.map(&:text)
78
- }
79
-
80
- Conclusion.new(
81
- index, title, reference, per_device, per_rating,
82
- per_rating[:critical], per_rating[:high],
83
- per_rating[:medium], per_rating[:low], per_rating[:info],
84
- )
85
- end
86
-
87
- # Recommendations
88
- def recommendations
89
- recom = @config[-1]
90
- index = attributes(recom).index
91
- title = attributes(recom).title
92
- reference = attributes(recom).ref
93
- list = generate_table(recom.elements[1].elements)
94
-
95
- Recommendations.new(
96
- index, title, reference,
97
- list
98
- )
99
- end
100
-
101
- end
102
- end