norad_cli 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 28931e6ce3f45712bbaa06b5a4c0cdd94964c4ec
4
- data.tar.gz: b41deb0cd1f576323d07d5a7a9ea16505d66abe9
3
+ metadata.gz: 39442f45d57eb7b0ad190c28b9016e917a0a9e02
4
+ data.tar.gz: d28a213caf79c18651dff57e11cc048ec8715e12
5
5
  SHA512:
6
- metadata.gz: 4415e34ab5e6f08caf44b87c520187f03de9c26ef6085e7d0022a97e95668b2511a53d68a6e4dfc24bd9127fc570f77f66200e55856446cdeea975fdcb01ef79
7
- data.tar.gz: bf21bf5af6c0268151d045bbd456f3dd0ff120ee26a99f93e40e18300749e8a2c423b60d138f291154eebb00d20b4302f1bc363eae1ce7a2e3e42230009a5715
6
+ metadata.gz: 041463bb0a524f04c605d1f64be1ce0431f98bb8e335236b4638d150bc7ff9ae7dca37a511fbe398873cccc7a0cb61a9648323fb2585ef7daac2965f1f9af32b
7
+ data.tar.gz: d3e5ca9f6c057d9f9829b05bc3e1093ea43f0a52508f034b8e714fd170db83d526c9e5a5c0d9286a2ce385b41847b93391540e6af4e7edb09e2227499c7f2b38
data/WALKTHROUGH.md ADDED
@@ -0,0 +1,336 @@
1
+ # Creating a Security Test
2
+
3
+ This document walks through the steps for creating a security test and integrating it into a Norad development box. It leverages the norad command line tool, which can be installed by doing:
4
+
5
+ ```
6
+ $ gem install norad_cli
7
+ ```
8
+
9
+ Other dependencies include a working [Norad Development Box](https://norad-dev-box-url) and [Docker](https://www.docker.com/community-edition).
10
+
11
+ # Security Test Development Steps
12
+
13
+ Assuming the dependencies described above are installed. Creating and testing a security test is straightforward. First, decided if you will be starting an entirely new repository to house security tests. If a new repository will be created, decided on a descriptive name, for instance asig-security, and use the norad repo create command:
14
+
15
+ ```
16
+ $ norad repo create asig-security
17
+ Initializing a new norad security test repository
18
+ create asig-security/base
19
+ create asig-security/spec
20
+ License the repo under Apache 2? y
21
+ Who is the copyright holder (Default: Cisco Systems, Inc.)?
22
+ create asig-security/LICENSE
23
+ create asig-security/.gitlab.ci.yml
24
+ create asig-security/.gitignore
25
+ create asig-security/CONTRIBUTING.md
26
+ create asig-security/README.md
27
+ ```
28
+ The command asks if the tests should be licensed under Apache 2 and for the copyright holder. When in doubt, answer no to the licensing question. The 'repo create' command creates a new git repository conforming to the Norad standards for layout and ci.
29
+
30
+ If you will not be creating a new repostiory simply clone an existing Norad security test repo.
31
+
32
+ ```
33
+ $ git clone git@norad-gitlab.cisco.com:norad/asig-hackathon-security-tests.git
34
+ ```
35
+
36
+ Once a repository is selected, either by creating a new one or cloning an existing one, change into the root of that repository before starting test development.
37
+
38
+ ```
39
+ $ cd asig-hackathon-security-tests
40
+ ```
41
+
42
+ Now, for this example, we will be creating a security test using the ping utility. The norad CLI tool includes a subcommand, sectest, to aid developers with creating, testing, validating, and integrating a security tool into Norad. Help for the sectest subcommand is available:
43
+
44
+ ```
45
+ $ norad help sectest
46
+ Commands:
47
+ norad sectest build # Build all sectest images and specs for the entire repository
48
+ norad sectest build:all SECTESTNAME # Build sectest images for SECTESTNAME and all testing images for SECTESTNAME
49
+ norad sectest build:image SECTESTNAME # Build the docker image for the security test SECTESTNAME
50
+ norad sectest build:specs SECTESTNAME # Build the spec images (test images) for the security test SECTESTNAME
51
+ norad sectest execute SECTESTNAME ARGUMENTS # Executes the specified security test SECTESTNAME w/ ARGUMENTS
52
+ norad sectest help [COMMAND] # Describe subcommands or one specific subcommand
53
+ norad sectest scaffold TESTNAME # Create a new security test with standard files + testing
54
+ norad sectest seed # Create the containers.rb seed to import into the api
55
+ norad sectest spec # Run all rspec tests for the entire repo (all sectests)
56
+ norad sectest spec:image SECTESTNAME # Run the rspec tests for SECTESTNAME
57
+ norad sectest validate # Validate all manifest.yml and readme.md
58
+ norad sectest validate:image SECTESTNAME # Validate SECTESTNAME manifest.yml and readme.md
59
+ ```
60
+
61
+ To start off, we use the scaffold command to create all of the required files to create a security test. The scaffold subcommand includes several options:
62
+
63
+ ```
64
+ $ norad sectest scaffold --help
65
+ Usage:
66
+ norad scaffold TESTNAME
67
+
68
+ Options:
69
+ -t, [--test-type=TEST_TYPE] # The security test type, Options: [authenticated|web_application|brute_force|ssl_crypto|ssh_crypto|whole_host]
70
+ # Default: whole_host
71
+ -r, [--registry=REGISTRY] # The Docker registry to store docker images
72
+ # Default: norad-registry.cisco.com:5000
73
+ -v, [--version=VERSION] # The version of the security test
74
+ # Default: latest
75
+ -b, [--base-image=BASE_IMAGE] # Base Docker image to use (i.e. FROM field in the Dockerfile)
76
+ # Default: norad-registry.cisco.com:5000/norad:0.0.1
77
+ -c, [--configurable], [--no-configurable] # Is the security test configurable (e.g. Qualys username and password)
78
+
79
+ Create a new security test with standard files + testing
80
+ ```
81
+ First, the TESTNAME will be whatever name you would like to assign to the security test. For this example, we will use pinger. The TESTNAME should not collide with any folder names under the sectests folder. Next, you must decide on the security test's test-type, registry, version, base-image, and if it will be configurable options. The test-type defines ......., available test tests are:
82
+
83
+ * authenticated:
84
+ * web_application:
85
+ * brute_force:
86
+ * ssl_crypto:
87
+ * ssh_crypto:
88
+ * whole_host:
89
+
90
+ For the pinger security test, we are simply checking the host, so the test-type be the default value, whole_host. The registry option permits the user to change where the security test will be stored, our test can use the default value (and most tests will). The version and base-image options allow you to set the initial version of the security test and a Docker image to start from. The default options are safe to use, unless, for the base image, you know of a different Docker image to use for a base. The configurable option sets whether the sectest will have additional command line options w/ defaults set in its manifest.yml. This new utility will not have any additional options, so there is no need to use the -c flag.
91
+
92
+ Therefore, for the new pinger sectest, the scaffold command is:
93
+
94
+ ```
95
+ $ norad sectest scaffold pinger
96
+
97
+ create sectests/pinger/Dockerfile
98
+ create sectests/pinger/README.md
99
+ create sectests/pinger/manifest.yml
100
+ create sectests/pinger/pinger-wrapper.rb
101
+ create spec/pinger/pinger_spec.rb
102
+ create spec/pinger/targets/Dockerfile.secure
103
+ create spec/pinger/targets/Dockerfile.vulnerable
104
+ ```
105
+
106
+ The scaffolding creates a new directory in sectests, pinger, housing the files necessary to create a new test. These files are:
107
+
108
+ * pinger/Dockerfile: alter this file to install new software packages
109
+ * pinger/README.md: describes the new security test and any options. This file is used to generate user facing documentation
110
+ * pinger/manifest.yml: YAML file to describe the security test. This file is used for importing information into a Norad instance
111
+ * pinger/pinger-wrapper.rb: A ruby script where execution begins when the security test is executed.
112
+
113
+ Scaffolding also creates tests and test targets for the new security test. The test targets, a secure and a vulnerable target, are defined by the Dockerfiles in spec/pinger/targets/. The [rspec](http://rspec.info/) tests to run for the new security test (to check if it is working properly) are defined in the file spec/pinger/pinger_spec.rb.
114
+
115
+ After a new security test is scaffolded, a developer alters the corresponding Dockerfile, (e.g. sectests/pinger/Dockerfile) to install any required dependencies. For instance, maybe you need to install a new tool (e.g. nmap) to develop the security test. In this case, the developer would add a new RUN command into the Dockerfile (sectests/pinger/Dockerfile):
116
+
117
+ ```
118
+ RUN apt-get -y install nmap
119
+ ```
120
+
121
+ Please refer to the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/#parser-directives) for all the available commands.
122
+ Once you have added all of the necessary commands to the new Dockerfile (sectests/pinger/Dockerfile), then you can try building the new sectest container with the norad sectest build command from the repo's root directory. For example, to build our test security tool:
123
+
124
+ ```
125
+ $ norad sectest build:image pinger
126
+ Building image pinger...
127
+ {"stream":"Step 1/5 : FROM norad-registry.cisco.com:5000/norad:0.0.1\n"}
128
+ {"stream":" ---\u003e e01961118951\n"}
129
+ {"stream":"Step 2/5 : COPY pinger-wrapper.rb /pinger-wrapper.rb\n"}
130
+ {"stream":" ---\u003e fde55e5e2b8a\n"}
131
+ {"stream":"Removing intermediate container 6ab5c3c7f4c1\n"}
132
+ {"stream":"Step 3/5 : RUN chmod 755 /pinger-wrapper.rb\n"}
133
+ {"stream":" ---\u003e Running in 2431f94971e2\n"}
134
+ {"stream":" ---\u003e 3294126d1b23\n"}
135
+ {"stream":"Removing intermediate container 2431f94971e2\n"}
136
+ {"stream":"Step 4/5 : WORKDIR /\n"}
137
+ {"stream":" ---\u003e 92ef3e0a4eb9\n"}
138
+ {"stream":"Removing intermediate container c83183b4a0f7\n"}
139
+ {"stream":"Step 5/5 : ENTRYPOINT /pinger-wrapper.rb\n"}
140
+ {"stream":" ---\u003e Running in 8b83ca556636\n"}
141
+ {"stream":" ---\u003e 53b3a4bfbbf9\n"}
142
+ {"stream":"Removing intermediate container 8b83ca556636\n"}
143
+ {"stream":"Successfully built 53b3a4bfbbf9\n"}
144
+ ```
145
+
146
+ The resulting image is stored on your machine and can be viewed by using docker image list command:
147
+
148
+ ```
149
+ $ docker image list
150
+ REPOSITORY TAG IMAGE ID CREATED SIZE
151
+ norad-registry.cisco.com:5000/pinger latest 53b3a4bfbbf9 About a minute ago 496 MB
152
+ ```
153
+
154
+ After that, update the manifest.yml (e.g. sectests/pinger/manifest.yml) and README.md (e.g. sectests/pinger/README.md) files. Updates to these files can be validated using the sectest validate commands:
155
+
156
+ ```
157
+ $ norad sectest validate:image pinger
158
+ Looking for README.md in: sectests/pinger...
159
+ OK
160
+ Testing for variant READMEs...
161
+ No variants for this tool
162
+ OK
163
+ .
164
+
165
+ Finished in 0.00142 seconds (files took 0.14096 seconds to load)
166
+ 1 example, 0 failures
167
+
168
+ Looking for README.md in: sectests/pinger...
169
+ OK
170
+ Testing for variant READMEs...
171
+ No variants for this tool
172
+ OK
173
+ .Looking for valid manifest in: ...
174
+ OK
175
+ Testing for valid name...
176
+ OK
177
+ Testing for existence of version...
178
+ OK
179
+ Testing for existence of registry...
180
+ OK
181
+ Testing for valid prog args...
182
+ OK
183
+ Testing for test types...
184
+ OK
185
+ Testing for configurability...
186
+ OK
187
+ Testing for variants...
188
+ No variants for this repo
189
+ OK
190
+
191
+ .
192
+
193
+ Finished in 0.00587 seconds (files took 0.1604 seconds to load)
194
+ 3 examples, 0 failures
195
+ ```
196
+
197
+ Next, the security tools wrapper script should be updated to perform the actual security checks (e.g. sectests/pinger/pinger-wrapper.rb). The wrapper script is responsible for spawning any tools (e.g. ping, nmap, etc.), parsing the results, and posting them back to Norad. For the pinger example, we can use an already prepared wrapper script:
198
+
199
+ ```ruby
200
+ #!/usr/bin/env ruby
201
+ require 'norad_beacon'
202
+
203
+ def run(args)
204
+ timeout = 3600 # set timeout for runner to 1 hour
205
+
206
+ # Allocate a runner
207
+ runner = NoradBeacon::Runner.new('ping', [ '-c', '1', args].flatten, timeout)
208
+
209
+ # Execute the runner
210
+ runner.execute(true)
211
+
212
+ # Ensure the tool created results
213
+ runner.parse_results do |fh|
214
+ id = '1'
215
+ title = 'Ping Test'
216
+ description = 'This test will ping a host to determine if it is alive.'
217
+ cvss = 'no_impact'
218
+ raw_output = fh.read() + "Exit Code: #{runner.exit_code}"
219
+ status = raw_output =~ /100% packet loss/ ? 'fail' : 'pass'
220
+
221
+ # Add the result to the runner's result set
222
+ # Note: Multiple results can be added, they will show up individually
223
+ runner.result_set.add(NoradBeacon::Result.new(id, status, raw_output, title, description, cvss))
224
+ end
225
+ rescue Exception => e
226
+ puts "An exception occurred: #{e.inspect}"
227
+ puts e.backtrace
228
+
229
+ status = 'error'
230
+ raw_output = 'Internal error occurred'
231
+ title = 'Failed to run the tests'
232
+ description = 'Internal error occurred'
233
+ runner.result_set.add(NoradBeacon::Result.new('0', status, raw_output, title, description))
234
+ ensure
235
+ # Save the results to Norad
236
+ NoradBeacon::NoradAPI.post_results(runner.result_set)
237
+ end
238
+
239
+ run(ARGV)
240
+ ```
241
+
242
+ For this walkthrough, copy the above code to sectests/pinger/pinger-wrapper.rb. The pinger docker image will need to rebuilt to incorporate the changes to the wrapper script. Simply rerun the norad sectest build:image pinger command.
243
+
244
+ After the build succeeds, it is time to test the new security tests. There are two methods for testing. The first method is to run the security test container against a target, and the second is to use Norad's rspec testing system. To run against a target, use the command:
245
+
246
+ FIXME: norad sectest execute SECTESTNAME ARGUMENTS
247
+
248
+
249
+ The second method is more involved but necessary for the image to be merged into Norad's approved images. Norad's CI system runs validation tests against security tests to ensure the test performs as expected. The CI system automatically spins up a vulnerable image (defined in spec/SECTESTNAME/targets/Dockerfile.vulnerable) and a secure image (defined in spec/SECTESTNAME/targets/Dockerfile.secure) where SECTESTNAME is the name of the security test (e.g. pinger). The secure and vulnerable images are defined by the developer. For your testing, please define a vulnerable and a secure container by altering their respective Dockerfiles. When you are ready to build these two images, norad sectest build:specs command can be used:
250
+
251
+ ```
252
+ $ norad sectest build:specs pinger
253
+ .....
254
+ Building image spec/pinger/targets/Dockerfile.secure...
255
+ {"stream":"Step 1/5 : FROM ubuntu:14.04\n"}
256
+ {"stream":" ---\u003e 7c09e61e9035\n"}
257
+ {"stream":"Step 2/5 : RUN apt-get -y update\n"}
258
+ {"stream":" ---\u003e Using cache\n"}
259
+ {"stream":" ---\u003e b2bc3253c8c3\n"}
260
+ {"stream":"Step 3/5 : RUN apt-get -y install openssh-server\n"}
261
+ {"stream":" ---\u003e Using cache\n"}
262
+ {"stream":" ---\u003e b23b83d7dc9c\n"}
263
+ {"stream":"Step 4/5 : RUN mkdir /var/run/sshd \u0026\u0026 chmod 0755 /var/run/sshd\n"}
264
+ {"stream":" ---\u003e Using cache\n"}
265
+ {"stream":" ---\u003e 3f7fe39c33ec\n"}
266
+ {"stream":"Step 5/5 : CMD /usr/sbin/sshd -D\n"}
267
+ {"stream":" ---\u003e Using cache\n"}
268
+ {"stream":" ---\u003e 28da9b415f86\n"}
269
+ {"stream":"Successfully built 28da9b415f86\n"}
270
+ ....
271
+ ```
272
+
273
+ The tests to run against the secure and vulnerable images are defined by the file spec/SECTESTNAME/SECTESTNAME_spec.rb (e.g. spec/pinger/pinger_spec.rb). These tests are written in (rspec)[http://rspec.info/], and the scaffolding command created some example tests for reference. For this example, the default rspec tests will work. For now, run the nroad cli testing command to view the results:
274
+
275
+ ```
276
+ $ norad sectest spec:image pinger
277
+ ```
278
+
279
+ At the end of the run, you will see:
280
+
281
+ ```
282
+ Finished in 33.22 seconds (files took 0.14089 seconds to load)
283
+ 6 examples, 1 failure
284
+
285
+ Failed examples:
286
+
287
+ rspec ./spec/pinger/pinger_spec.rb:24 # Pinger for vulnerable machine should report a failure
288
+ ```
289
+
290
+ Digging into the reason why the test "Pinger for vulnerable machine should report a failure" failed, the console output shows:
291
+
292
+ ```
293
+ expected: "fail"
294
+ got: "pass"
295
+ ```
296
+
297
+ Since this test is merely running a ping to check connectivity, the vulnerable host is up during the test, so the parsing logic in sectests/pinger/pinger-wrapper.rb, specifically:
298
+
299
+ ```ruby
300
+ raw_output = fh.read() + "Exit Code: #{runner.exit_code}"
301
+ status = raw_output =~ /100% packet loss/ ? 'fail' : 'pass'
302
+ ```
303
+
304
+ is marking the status incorrectly for the vulnerable machine. If you would like to see verbose logging from tests (includes stdout/stderr from the containers as wrapper scripts), run use the spec:image verbose flag:
305
+
306
+ ```
307
+ $ norad sectest spec:image -v pinger
308
+ ```
309
+
310
+ Once all of the tests have passed, it is time to generate a seed file to import into a development machine. A seed file can be generated by running:
311
+
312
+ ```
313
+ $ norad sectest seed
314
+ ```
315
+
316
+ The seed command generates a file, `containers.rb`, which can be used to import the tests into the Norad Web Application (e.g. [Norad Dev-Box](https://gitlab.com/norad/dev-box) or
317
+ production machine). Follow the instructions below to import the file:
318
+
319
+ * Upload `containers.rb` to your dev-box or production machine.
320
+ * From the directory containing the `api` code run the following:
321
+
322
+ $ rails runner path/to/your/containers.rb
323
+
324
+
325
+ # Helpful Docker Commands
326
+
327
+ * `docker images` - Determine the images available
328
+ * `docker ps` - Show containers currently running
329
+ * `docker kill 8b83ca556636` - Remove a currently running container
330
+
331
+ # References
332
+
333
+ * [Docker Command Line Reference](https://docs.docker.com/engine/reference/commandline/docker/)
334
+ * [Dockerfile Reference](https://docs.docker.com/engine/reference/builder/)
335
+ * [RSpec](http://rspec.info/)
336
+
@@ -175,7 +175,12 @@ class Sectest < Thor
175
175
  ENV['UBUNTU_SSH_SERVER_IMAGE'] = 'docker-images-test-ubuntu-ssh-server'
176
176
 
177
177
  # Run the tests
178
- RSpec::Core::Runner.run(["spec/#{name}/#{name}_spec.rb"], $stderr, $stdout)
178
+ if File.exist?("spec/#{name}/#{name}_spec.rb")
179
+ RSpec::Core::Runner.run(["spec/#{name}/#{name}_spec.rb"], $stderr, $stdout)
180
+ else
181
+ say("Warning: spec/#{name}/#{name}_spec.rb does not exist!\n", :yellow)
182
+ say("Warning: No tests will be run for #{name}\n", :yellow)
183
+ end
179
184
  end
180
185
 
181
186
  desc 'spec', 'Run all rspec tests for the entire repo (all sectests)'
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module NoradCli
3
- VERSION = '0.1.9'
3
+ VERSION = '0.1.10'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: norad_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Hitchcock
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-03-09 00:00:00.000000000 Z
13
+ date: 2017-03-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: git
@@ -188,6 +188,7 @@ files:
188
188
  - LICENSE
189
189
  - README.md
190
190
  - Rakefile
191
+ - WALKTHROUGH.md
191
192
  - bin/norad
192
193
  - lib/norad_cli.rb
193
194
  - lib/norad_cli/cli/main.rb