ruby-nikto 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+ require 'nikto/xml/scan_details'
3
+ require 'nokogiri'
4
+
5
+ describe Nikto::XML::ScanDetails do
6
+ let(:fixtures_dir) { File.expand_path(File.join(__dir__,'..','fixtures')) }
7
+ let(:path) { File.join(fixtures_dir,'nikto.xml') }
8
+ let(:xml) { File.read(path) }
9
+ let(:doc) { Nokogiri::XML(File.open(path)) }
10
+ let(:node) { doc.at_xpath('/niktoscan/scandetails') }
11
+
12
+ subject { described_class.new(node) }
13
+
14
+ describe "#target_ip" do
15
+ subject { super().target_ip }
16
+
17
+ it "must return a String" do
18
+ expect(subject).to be_kind_of(String)
19
+ end
20
+
21
+ it "must return the 'targetip' attribute" do
22
+ expect(subject).to eq(node['targetip'])
23
+ end
24
+ end
25
+
26
+ describe "#target_hostname" do
27
+ subject { super().target_hostname }
28
+
29
+ it "must return a String" do
30
+ expect(subject).to be_kind_of(String)
31
+ end
32
+
33
+ it "must return the 'targethostname' attribute" do
34
+ expect(subject).to eq(node['targethostname'])
35
+ end
36
+ end
37
+
38
+ describe "#target_port" do
39
+ subject { super().target_port }
40
+
41
+ it "must return the 'targetport' attribute as an Integer" do
42
+ expect(subject).to eq(node['targetport'].to_i)
43
+ end
44
+
45
+ it "must be > 0" do
46
+ expect(subject).to be > 0
47
+ end
48
+ end
49
+
50
+ describe "#target_banner" do
51
+ subject { super().target_banner }
52
+
53
+ it "must return a String" do
54
+ expect(subject).to be_kind_of(String)
55
+ end
56
+
57
+ it "must return the 'targetbanner' attribute" do
58
+ expect(subject).to eq(node['targetbanner'])
59
+ end
60
+ end
61
+
62
+ describe "#start_time" do
63
+ subject { super().start_time }
64
+
65
+ it "must return the 'starttime' attribute as a Time object" do
66
+ expect(subject).to eq(Time.parse(node['starttime']))
67
+ end
68
+ end
69
+
70
+ describe "#site_name" do
71
+ subject { super().site_name }
72
+
73
+ it "must return a String" do
74
+ expect(subject).to be_kind_of(String)
75
+ end
76
+
77
+ it "must return the 'sitename' attribute" do
78
+ expect(subject).to eq(node['sitename'])
79
+ end
80
+ end
81
+
82
+ describe "#site_ip" do
83
+ subject { super().site_ip }
84
+
85
+ it "must return a String" do
86
+ expect(subject).to be_kind_of(String)
87
+ end
88
+
89
+ it "must return the 'siteip' attribute" do
90
+ expect(subject).to eq(node['siteip'])
91
+ end
92
+ end
93
+
94
+ describe "#host_header" do
95
+ subject { super().host_header }
96
+
97
+ it "must return a String" do
98
+ expect(subject).to be_kind_of(String)
99
+ end
100
+
101
+ it "must return the 'hostheader' attribute" do
102
+ expect(subject).to eq(node['hostheader'])
103
+ end
104
+ end
105
+
106
+ describe "#errors" do
107
+ subject { super().errors }
108
+
109
+ it "must return the 'errors' attribute as an Integer" do
110
+ expect(subject).to eq(node['errors'].to_i)
111
+ end
112
+ end
113
+
114
+ describe "#errors?" do
115
+ context "when #errors is 0" do
116
+ before { allow(subject).to receive(:errors).and_return(0) }
117
+
118
+ it "must return false" do
119
+ expect(subject.errors?).to be(false)
120
+ end
121
+ end
122
+
123
+ context "when #errors is greater than 0" do
124
+ before { allow(subject).to receive(:errors).and_return(1) }
125
+
126
+ it "must return true" do
127
+ expect(subject.errors?).to be(true)
128
+ end
129
+ end
130
+ end
131
+
132
+ describe "#checks" do
133
+ subject { super().checks }
134
+
135
+ it "must return the 'checks' attribute as an Integer" do
136
+ expect(subject).to eq(node['checks'].to_i)
137
+ end
138
+
139
+ it "must be > 0" do
140
+ expect(subject).to be > 0
141
+ end
142
+ end
143
+
144
+ let(:item_count) { node.xpath('item').count }
145
+
146
+ describe "#each_item" do
147
+ context "when given a block" do
148
+ it "must yield each Item object" do
149
+ expect { |b|
150
+ subject.each_item(&b)
151
+ }.to yield_successive_args(*Array.new(item_count,Nikto::XML::Item))
152
+ end
153
+ end
154
+
155
+ context "when no block is given" do
156
+ subject { super().each_item.to_a }
157
+
158
+ it "must return an Enumerator of Nikto::XML::Item objects" do
159
+ expect(subject.length).to be(item_count)
160
+ expect(subject).to all(be_kind_of(Nikto::XML::Item))
161
+ end
162
+ end
163
+ end
164
+
165
+ describe "#items" do
166
+ subject { super().items}
167
+
168
+ it "must return an Array of Nikto::XML::ScanDetails" do
169
+ expect(subject.length).to be(item_count)
170
+ expect(subject).to all(be_kind_of(Nikto::XML::Item))
171
+ end
172
+ end
173
+
174
+ describe "#statistics" do
175
+ subject { super().statistics }
176
+
177
+ it "must return a Statistics object" do
178
+ expect(subject).to be_kind_of(Nikto::XML::Statistics)
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'nikto/xml/statistics'
3
+ require 'nokogiri'
4
+
5
+ describe Nikto::XML::Statistics do
6
+ let(:fixtures_dir) { File.expand_path(File.join(__dir__,'..','fixtures')) }
7
+ let(:path) { File.join(fixtures_dir,'nikto.xml') }
8
+ let(:xml) { File.read(path) }
9
+ let(:doc) { Nokogiri::XML(File.open(path)) }
10
+ let(:node) { doc.at_xpath('/niktoscan/scandetails/statistics') }
11
+
12
+ subject { described_class.new(node) }
13
+
14
+ describe "#elapsed" do
15
+ subject { super().elapsed }
16
+
17
+ it "must return the 'elapsed' attribute as an Integer" do
18
+ expect(subject).to eq(node['elapsed'].to_i)
19
+ end
20
+
21
+ it "must be greater than 0" do
22
+ expect(subject).to be > 0
23
+ end
24
+ end
25
+
26
+ describe "#items_found" do
27
+ subject { super().items_found }
28
+
29
+ it "must return the 'itemsfound' attribute as an Integer" do
30
+ expect(subject).to eq(node['itemsfound'].to_i)
31
+ end
32
+
33
+ it "must be greater than 0" do
34
+ expect(subject).to be > 0
35
+ end
36
+ end
37
+
38
+ describe "#items_tested" do
39
+ subject { super().items_tested }
40
+
41
+ it "must return the 'itemstested' attribute as an Integer" do
42
+ expect(subject).to eq(node['itemstested'].to_i)
43
+ end
44
+
45
+ it "must be greater than 0" do
46
+ expect(subject).to be > 0
47
+ end
48
+ end
49
+
50
+ describe "#end_time" do
51
+ subject { super().end_time }
52
+
53
+ it "must return the 'endtime' attribute as a Time object" do
54
+ expect(subject).to eq(Time.parse(node['endtime']))
55
+ end
56
+ end
57
+ end
data/spec/xml_spec.rb ADDED
@@ -0,0 +1,190 @@
1
+ require 'spec_helper'
2
+ require 'nikto/xml'
3
+
4
+ describe Nikto::XML do
5
+ let(:fixtures_dir) { File.expand_path(File.join(__dir__,'fixtures')) }
6
+ let(:path) { File.join(fixtures_dir,'nikto.xml') }
7
+ let(:xml) { File.read(path) }
8
+ let(:doc) { Nokogiri::XML(File.open(path)) }
9
+
10
+ subject { described_class.new(doc, path: path) }
11
+
12
+ describe "#initialize" do
13
+ it "must set #doc" do
14
+ expect(subject.doc).to eq(doc)
15
+ end
16
+
17
+ context "when given a block" do
18
+ it "must yield the new XML object" do
19
+ expect { |b|
20
+ described_class.new(xml,&b)
21
+ }.to yield_with_args(described_class)
22
+ end
23
+ end
24
+
25
+ context "when the path: keyword argument is not given" do
26
+ subject { described_class.new(xml) }
27
+
28
+ it "must set #path to nil" do
29
+ expect(subject.path).to be(nil)
30
+ end
31
+ end
32
+
33
+ context "when the path: keyword argument is given" do
34
+ subject { described_class.new(xml, path: path) }
35
+
36
+ it "must set #path" do
37
+ expect(subject.path).to eq(path)
38
+ end
39
+ end
40
+ end
41
+
42
+ describe ".parse" do
43
+ subject { described_class.parse(xml) }
44
+
45
+ it "must parse the XML data" do
46
+ expect(subject.doc).to be_kind_of(Nokogiri::XML::Document)
47
+ end
48
+
49
+ it "must set #path to nil" do
50
+ expect(subject.path).to be(nil)
51
+ end
52
+ end
53
+
54
+ describe ".open" do
55
+ subject { described_class.open(path) }
56
+
57
+ it "must open the file and parse the XML" do
58
+ expect(subject.doc).to be_kind_of(Nokogiri::XML::Document)
59
+ end
60
+
61
+ it "must set #path" do
62
+ expect(subject.path).to eq(path)
63
+ end
64
+ end
65
+
66
+ describe "#hosts_test" do
67
+ subject { super().hosts_test }
68
+
69
+ it "must return the 'hoststest' attribute as an Integer" do
70
+ expect(subject).to eq(doc.root['hoststest'].to_i)
71
+ end
72
+ end
73
+
74
+ describe "#options" do
75
+ subject { super().options }
76
+
77
+ it "must return a String" do
78
+ expect(subject).to be_kind_of(String)
79
+ end
80
+
81
+ it "must return the 'options' attribute" do
82
+ expect(subject).to eq(doc.root['options'])
83
+ end
84
+ end
85
+
86
+ describe "#scan_start" do
87
+ subject { super().scan_start }
88
+
89
+ it "must return the 'scanstart' attribute as a Time object" do
90
+ expect(subject).to eq(Time.parse(doc.root['scanstart']))
91
+ end
92
+ end
93
+
94
+ describe "#scan_end" do
95
+ subject { super().scan_end }
96
+
97
+ it "must return the 'scanend' attribute as a Time object" do
98
+ expect(subject).to eq(Time.parse(doc.root['scanend']))
99
+ end
100
+ end
101
+
102
+ describe "#scan_elapsed" do
103
+ subject { super().scan_elapsed }
104
+
105
+ it "must return a String" do
106
+ expect(subject).to be_kind_of(String)
107
+ end
108
+
109
+ it "must return the 'scanelapsed' attribute" do
110
+ expect(subject).to eq(doc.root['scanelapsed'])
111
+ end
112
+ end
113
+
114
+ describe "#nikto_xml_version" do
115
+ subject { super().nikto_xml_version }
116
+
117
+ it "must return a String" do
118
+ expect(subject).to be_kind_of(String)
119
+ end
120
+
121
+ it "must return the 'nxmlversion' attribute" do
122
+ expect(subject).to eq(doc.root['nxmlversion'])
123
+ end
124
+ end
125
+
126
+ describe "#each_scan_details" do
127
+ context "when given a block" do
128
+ it "must yield each ScanDetails object" do
129
+ expect { |b|
130
+ subject.each_scan_details(&b)
131
+ }.to yield_successive_args(described_class::ScanDetails)
132
+ end
133
+ end
134
+
135
+ context "when no block is given" do
136
+ subject { super().each_scan_details.to_a }
137
+
138
+ it "must return an Enumerator of #{described_class}::ScanDetails objects" do
139
+ expect(subject.length).to be(1)
140
+ expect(subject[0]).to be_kind_of(described_class::ScanDetails)
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "#scan_details" do
146
+ subject { super().scan_details }
147
+
148
+ it "must return an Array of #{described_class}::ScanDetails" do
149
+ expect(subject).to be_kind_of(Array)
150
+ expect(subject.length).to be(1)
151
+ expect(subject[0]).to be_kind_of(described_class::ScanDetails)
152
+ end
153
+ end
154
+
155
+ describe "#target" do
156
+ let(:first_scan_details) { subject.scan_details.first }
157
+ let(:target) { subject.target }
158
+
159
+ it "must return the first #scan_details" do
160
+ expect(target.target_ip).to eq(first_scan_details.target_ip)
161
+ expect(target.target_hostname).to eq(first_scan_details.target_hostname)
162
+ expect(target.target_port).to eq(first_scan_details.target_port)
163
+ expect(target.target_banner).to eq(first_scan_details.target_banner)
164
+ expect(target.start_time).to eq(first_scan_details.start_time)
165
+ expect(target.site_name).to eq(first_scan_details.site_name)
166
+ expect(target.site_ip).to eq(first_scan_details.site_ip)
167
+ expect(target.host_header).to eq(first_scan_details.host_header)
168
+ expect(target.errors).to eq(first_scan_details.errors)
169
+ expect(target.checks).to eq(first_scan_details.checks)
170
+ end
171
+ end
172
+
173
+ describe "#to_s" do
174
+ context "when #path is set" do
175
+ subject { described_class.open(path) }
176
+
177
+ it "must return the #path" do
178
+ expect(subject.to_s).to eq(path)
179
+ end
180
+ end
181
+
182
+ context "when #path is nil" do
183
+ subject { described_class.parse(xml) }
184
+
185
+ it "must return the XML" do
186
+ expect(subject.to_s).to eq(doc.to_s)
187
+ end
188
+ end
189
+ end
190
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-nikto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Postmodern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: command_mapper
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ description: A Ruby interface to Nikto, the Web Server scanner.
56
+ email: postmodern.mod3@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - ChangeLog.md
61
+ - LICENSE.txt
62
+ - README.md
63
+ files:
64
+ - ".editorconfig"
65
+ - ".github/workflows/ruby.yml"
66
+ - ".gitignore"
67
+ - ".rspec"
68
+ - ".specopts"
69
+ - ".yardopts"
70
+ - ChangeLog.md
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - gemspec.yml
76
+ - lib/nikto.rb
77
+ - lib/nikto/command.rb
78
+ - lib/nikto/version.rb
79
+ - lib/nikto/xml.rb
80
+ - lib/nikto/xml/item.rb
81
+ - lib/nikto/xml/scan_details.rb
82
+ - lib/nikto/xml/statistics.rb
83
+ - ruby-nikto.gemspec
84
+ - spec/command_spec.rb
85
+ - spec/fixtures/nikto.xml
86
+ - spec/nikto_spec.rb
87
+ - spec/spec_helper.rb
88
+ - spec/xml/item_spec.rb
89
+ - spec/xml/scan_details_spec.rb
90
+ - spec/xml/statistics_spec.rb
91
+ - spec/xml_spec.rb
92
+ homepage: http://github.com/sophsec/ruby-nikto
93
+ licenses:
94
+ - MIT
95
+ metadata:
96
+ documentation_uri: https://rubydoc.info/gems/ruby-nikto
97
+ source_code_uri: https://github.com/postmodern/ruby-nikto
98
+ bug_tracker_uri: https://github.com/postmodern/ruby-nikto/issues
99
+ changelog_uri: https://github.com/postmodern/ruby-nikto/blob/master/ChangeLog.md
100
+ rubygems_mfa_required: 'true'
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements:
116
+ - nikto >= 2.1.0
117
+ rubygems_version: 3.2.22
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: A Ruby interface to Nikto.
121
+ test_files: []