nexpose_sccm 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +14 -0
- data/MIT-LICENSE +21 -0
- data/README.md +212 -0
- data/bin/encrypt_settings.rb +135 -0
- data/bin/nexpose_sccm +69 -0
- data/bin/vuln_ids.csv +7 -0
- data/conf/logging.yml +8 -0
- data/conf/nexpose.yml +8 -0
- data/conf/postgres.yml +8 -0
- data/conf/queries.yml +87 -0
- data/conf/sccm.yml +30 -0
- data/conf/secret.yml +4 -0
- data/lib/nexpose_sccm.rb +294 -0
- data/lib/nexpose_sccm/collection.rb +42 -0
- data/lib/nexpose_sccm/connection.rb +165 -0
- data/lib/nexpose_sccm/data_source.rb +67 -0
- data/lib/nexpose_sccm/deployment_package.rb +37 -0
- data/lib/nexpose_sccm/device.rb +11 -0
- data/lib/nexpose_sccm/helpers/nexpose_helper.rb +65 -0
- data/lib/nexpose_sccm/helpers/pg_helper.rb +26 -0
- data/lib/nexpose_sccm/powershell.rb +111 -0
- data/lib/nexpose_sccm/remediation_item.rb +5 -0
- data/lib/nexpose_sccm/software_update_group.rb +54 -0
- data/lib/nexpose_sccm/utilities/nx_logger.rb +171 -0
- data/lib/nexpose_sccm/utilities/utility_config.rb +59 -0
- data/lib/nexpose_sccm/version.rb +5 -0
- data/lib/nexpose_sccm/wql.rb +35 -0
- data/nexpose_sccm.gemspec +35 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 05d535cae6251874a19e668e8f19fead29309377
|
4
|
+
data.tar.gz: fd671a1b752549f983b6c3e85d47e8f57920a15f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d833ae2f1444db55e6daae56a5b4bccc10feeb2d93ced13a1e4d8a8a3de1ad67d1210f142257559555b63f0fbe9bf0958aac4cb838208fa152fe60a94074e382
|
7
|
+
data.tar.gz: 1bb2ee97958b404fbad16459389c966046cd241675c487e877e381e36b84ddb01f1ed3c1c88d80190bdfe8246c469fffd3476f83655a230968af191896f27eb1
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'winrm'
|
4
|
+
|
5
|
+
group :nexpose, optional: true do
|
6
|
+
gem 'nexpose'
|
7
|
+
end
|
8
|
+
|
9
|
+
group :dwh, optional: true do
|
10
|
+
## May need to install postgres drivers before the gem
|
11
|
+
gem 'pg'
|
12
|
+
end
|
13
|
+
|
14
|
+
# Specify your gem's dependencies in nexpose_servicenow.gemspec
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Adam Robinson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
# Nexpose SCCM Integration
|
2
|
+
|
3
|
+
This is the offical gem package for the Ruby Nexpose SCCM integration.
|
4
|
+
|
5
|
+
For assistance with using the gem, please contact the Rapid7 Integrations support team using the [Rapid7 Support Portal](https://rapid7support.force.com/customers/login)
|
6
|
+
|
7
|
+
## About
|
8
|
+
|
9
|
+
The `nexpose_sccm` integration is designed to pull vulnerability and solution data from Nexpose scan results, to then generate SCCM Software Update Groups and Collections based upon the data. These groups can then be used to deploy software updates to assets, enabling partial automation of the process.
|
10
|
+
|
11
|
+
Example queries to retrieve data from Nexpose have been provided, with the option for the user to supply different variations instead.
|
12
|
+
The integration supports retrieving data from the Nexpose Console or via a separate DataWarehouse installation.
|
13
|
+
|
14
|
+
The integration provides options to create Deployment Packages on the SCCM server, as well as generate a CSV report of assets found in Nexpose, but currently unknown or not managed by SCCM.
|
15
|
+
|
16
|
+
NOTE: Requires SCCM 1702 or later for Deployment Package functionality. It is possible to gather the version of SCCM by
|
17
|
+
running the following command in Powershell:
|
18
|
+
|
19
|
+
```powershell
|
20
|
+
Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\SMS\\Setup
|
21
|
+
```
|
22
|
+
|
23
|
+
`Ruby Version [>= 2.3.1, < 2.5.0]`
|
24
|
+
|
25
|
+
For more information please refer to the integration documentation which can be requested from the Rapid7 support team.
|
26
|
+
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
### RubyGems (preferred)
|
30
|
+
With the correct Ruby version available, run the following command from the command line:
|
31
|
+
|
32
|
+
```bash
|
33
|
+
gem install nexpose_sccm
|
34
|
+
```
|
35
|
+
This will also download and install the required dependencies.
|
36
|
+
|
37
|
+
|
38
|
+
### Bundler
|
39
|
+
Using the Bundler gem, the integration can be installed or packaged to be installed on a system with no Internet access.
|
40
|
+
|
41
|
+
Choose between using the Nexpose Console or a Data Warehouse for data export.
|
42
|
+
|
43
|
+
##### Online
|
44
|
+
```bash
|
45
|
+
bundle install --with nexpose dwh
|
46
|
+
```
|
47
|
+
|
48
|
+
##### Offline
|
49
|
+
On a system with internet access and a similar setup to the final install location, run the following command from within the gem folder:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
bundle package
|
53
|
+
```
|
54
|
+
Then copy the directory to the offline system and install dependencies followed by bundle install:
|
55
|
+
|
56
|
+
```bash
|
57
|
+
apt install ruby ruby-dev ruby-bundler libpq-dev build-essential
|
58
|
+
bundle install --local --with nexpose dwh
|
59
|
+
```
|
60
|
+
The required gems are located under `nexpose_sccm/vendor/cache`
|
61
|
+
|
62
|
+
### <Pending Windows Instructions>
|
63
|
+
|
64
|
+
## Configuration
|
65
|
+
Configuration files for the nexpose\_sccm integration can be found under `nexpose_sccm/conf/`
|
66
|
+
|
67
|
+
There are several files located here that need populated:
|
68
|
+
|
69
|
+
- `logging.yml`
|
70
|
+
This file contains logging settings for the integration
|
71
|
+
- `nexpose.yml`
|
72
|
+
This file contains the Nexpose connection settings
|
73
|
+
- `postgres.yml`
|
74
|
+
This file contains the Data Warehouse connection settings
|
75
|
+
- `queries.yml`
|
76
|
+
This file contains the queries used by the integration. Please see below for more information
|
77
|
+
- `sccm.yml`
|
78
|
+
This file contains settings for the operation of the integration, as well as the SCCM connection settings
|
79
|
+
- `secret.yml`
|
80
|
+
This file contains settings for the in-built encryption functionality (optional)
|
81
|
+
|
82
|
+
|
83
|
+
#### Windows and SCCM Permissions
|
84
|
+
The user account running the integration should preferably be a Windows Domain account.
|
85
|
+
It needs to be added to the Remote Management Users group on the SCCM server.
|
86
|
+
It also needs to be added as an "Administrative User" in the SCCM Console.
|
87
|
+
The Security role for this user should be a custom role based on the pre-existing "Read-Only Analyst", with the following additional permissions:
|
88
|
+
|
89
|
+
|Permission Group |Permissions |
|
90
|
+
|-----------------------|--------------------|
|
91
|
+
|Collection |Create, Delete Resource, Modify, Modify Resource, Read, Read Resource, Remote Control, View Collected File|
|
92
|
+
|Software Update Group |Create, Modify, Read|
|
93
|
+
|Software Update Package|Create, Modify, Read|
|
94
|
+
|
95
|
+
This user may also need to log into the SCCM Console to activate the account.
|
96
|
+
|
97
|
+
For WinRM access from the host machine to the SCCM server, ports 5985 (HTTP) or 5986 (HTTPS) will need to be opened in the Firewall.
|
98
|
+
For HTTPS communication between the host machine and the SCCM server, a HTTPS listener will need to be created. The SSL Peer Fingerprint can then be retrieved by running the command in the `sccm.yaml` file.
|
99
|
+
|
100
|
+
|
101
|
+
#### Nexpose SCCM settings
|
102
|
+
These settings are found at the bottom of the `sccm.yml` file. A brief explanation of each can be found below:
|
103
|
+
|
104
|
+
|Setting |Description|
|
105
|
+
|---------------------------|-----------|
|
106
|
+
|create\_deployment_package | Set to _true_ to create Deployment Packages based on the generated Software Update Groups. This leverages staging configuration for where software updates are downloaded |
|
107
|
+
|download_updates | Set to _true_ to have SCCM download updates for the deployment package in scope. This setting will not be used if create\_deployment_package is false |
|
108
|
+
|integration_prefix | The prefix used for all Software Update Groups, Collections and Deployment Package names |
|
109
|
+
|generate\_unknown\_device_report| Set to true to generate a CSV report of devices found in Nexpose, but unknown to SCCM |
|
110
|
+
|report_location | Absolute or relative location of directory where reports should be saved |
|
111
|
+
|scope | The query to run from `queries.yml` - must match the name in the file |
|
112
|
+
|action | Can be set to either _update_ or _create_ for generating objects in SCCM. Recommended to leave as update to avoid creating large numbers of objects |
|
113
|
+
|data_source | Defines where vulnerability and solution data is pulled from - set _nsc_ for the Nexpose Console, _dwh_ for a Data Warehouse |
|
114
|
+
|software\_update\_group_key| The name of the SQL query column used for grouping and generating Software Update Groups |
|
115
|
+
|collection_key | The name of the SQL query column used for grouping and generating Collections |
|
116
|
+
|
117
|
+
|
118
|
+
#### Nexpose Queries
|
119
|
+
The `queries.yml` file can be modified to include customised queries. These should be tested in the Reports section of the Nexpose Console or against the Data Warehouse before use.
|
120
|
+
The query should be named following the convention shown for existing queries. It should also be under `:nsc:` or `:dwh:` depending on which Data Source it is to run against, following the YAML indentation rules.
|
121
|
+
|
122
|
+
Values can be inserted into queries at runtime - either from a file or a user prompt. The `asset_best_solution_by_site` query shows an example of this for a single value, whereas the `vuln_by_id` query demonstrates this for two lists. See the vuln_ids.csv file for an example of passing values in by file.
|
123
|
+
|
124
|
+
Any column can be used in the query as the key for either Software Update Groups or Collections - they do not need to be the same column, nor marked with the "key" identifier.
|
125
|
+
Below is a list of required or recommended columns for creating a query:
|
126
|
+
|
127
|
+
|Column|Required|Description|
|
128
|
+
|------|--------|-----------|
|
129
|
+
|key |Yes| This column makes an easy identifier for creating Software Update Groups or Collections. It is the default value listed in the `sccm.yml` file. This can be any column the user wishes to group on e.g. when running the integration, you could group Collections by site_id, combining all assets in a site into the same Collection. However, they could then use a different column to group the Software Update Groups e.g. IP Address |
|
130
|
+
|ip_address|Yes| The IP address is used for finding matching SCCM managed devices by IP Address |
|
131
|
+
|host_name|Yes| The host name is used for finding matching SCCM managed devices by HostName |
|
132
|
+
|nexpose_id|Yes| The solution's nexpose_id is used for extracting the solution, for each vulnerability, per asset in scope. This is required for retrieving the software patches from SCCM |
|
133
|
+
|
134
|
+
|
135
|
+
#### Encryption Settings
|
136
|
+
In order to asymmetrically encrypt sensitive data in the configuration files, perform the following:
|
137
|
+
- Identify the values to be encrypted and prefix them with `(enc)` e.g. `:user: '(enc)nxuser'`
|
138
|
+
- Ensure the `:secret` section is also defined in `secret.yml` with the location to store the encrypted key directory and encrypted settings file. It is important these values do not change as the integration will use them to identify how to decrypt the encrypted settings.
|
139
|
+
|
140
|
+
Once all fields expected to be encrypted have been updated, then the encrypt_settings.rb script can be used for the encryption process. Once run, the configuration files will be updated. This informs the integration to retrieve the credentials from the encrypted file:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
ruby encrypt_settings.rb
|
144
|
+
```
|
145
|
+
It is important to remember to re-encrypt **ALL** configuration files if any encrypted values are updated.
|
146
|
+
To disable the use of encrypted settings, either remove or comment out the entire `:secret` section within `secret.yml`
|
147
|
+
|
148
|
+
Like the main integration, the configuration file location can be passed using the `-s` flag.
|
149
|
+
|
150
|
+
|
151
|
+
## Usage
|
152
|
+
The executable used for initiating the integration can be found in the `bin/` directory of the installed nexpose_sccm gem.
|
153
|
+
With the gem installed, the integration can be called using the following command:
|
154
|
+
|
155
|
+
```bash
|
156
|
+
nexpose_sccm [options]
|
157
|
+
```
|
158
|
+
The following options can be used with the integration:
|
159
|
+
|
160
|
+
|Option |Description|
|
161
|
+
|--------------|-----------|
|
162
|
+
|--version | Shows version information about the nexpose\_sccm gem |
|
163
|
+
|-h | Displays the information listed here |
|
164
|
+
|-s SETTINGS | The path to the settings directory containing the necessary yml files. Only needed if files are stored in a chosen location |
|
165
|
+
|-i INPUT\_FILE| The path to the input file leveraged by the query. This should be in CSV format with a column for each set of input data and the headers should match the required field names. See vuln_ids.csv for an example |
|
166
|
+
|
167
|
+
## Validation
|
168
|
+
There are two ways to validate the successful completion of the integration.
|
169
|
+
First, verify the output of the log file or STDOUT if configured. During normal usage, the log level should be set to INFO which means only informational or error messages will be populated within the log. If any error messages are found, please review them to identify the reason for the error. A successful run should only contain INFO and/or DEBUG messages.
|
170
|
+
The log file can be found under `<gem_install_location>/nexpose_sccm/lib/nexpose_sccm/logs/`
|
171
|
+
|
172
|
+
In addition, once the integration has run it is possible to check the Software Update Groups, Collections, and Deployment Packages that are generated within SCCM. Once logged into the SCCM console, view each section to ensure everything is properly generated.
|
173
|
+
If `download_updates` is set to _true_ then downloaded updates will also be found at the `staging` location set in the `sccm.yml` file.
|
174
|
+
|
175
|
+
## Troubleshooting
|
176
|
+
### Logs
|
177
|
+
Please check the log files located at `<gem_install_location>/nexpose_sccm/lib/nexpose_sccm/logs/`
|
178
|
+
These will output errors occurring during the normal run of the integration. Log messages will also appear here if there is an issue connecting to the SCCM server via WinRM.
|
179
|
+
|
180
|
+
### Windows Issues
|
181
|
+
The integration uses WinRM and WMI to communicate with the SCCM Console, as well as to run WQL and Powershell commands. If an error occurs with this process it will be when doing the following:
|
182
|
+
|
183
|
+
- Getting Device, Collection, Software Update Group, Software Update or Deployment Package information
|
184
|
+
- Creating Collections, Software Update Groups or Deployment Packages
|
185
|
+
|
186
|
+
Please ensure your user has the correct permissions for these tasks.
|
187
|
+
Please ensure any local users have the correct permissions for running tasks on the SCCM console.
|
188
|
+
|
189
|
+
Information on these issues can be found on the [Microsoft Technet Website](https://blogs.technet.microsoft.com)
|
190
|
+
|
191
|
+
Useful logs can be found in the "Event Viewer" application on the SCCM server:
|
192
|
+
|
193
|
+
- `Windows Logs -> System`
|
194
|
+
- `Application and Services -> Microsoft -> Windows Remote Management`
|
195
|
+
|
196
|
+
### Support
|
197
|
+
For further issues, please contact the Rapid7 support team at support@rapid7.com
|
198
|
+
|
199
|
+
## Contribution
|
200
|
+
|
201
|
+
## Changelog
|
202
|
+
|
203
|
+
#### 0.4.0
|
204
|
+
- Adaptation from existing script into a Ruby gem
|
205
|
+
- Restructuring file hierarcy
|
206
|
+
- Implementing internal logger
|
207
|
+
- Adding licensing
|
208
|
+
- Adding a gemspec
|
209
|
+
- Removing Bundler
|
210
|
+
- Adding extra example queries
|
211
|
+
- Updating README
|
212
|
+
- Published to the RubyGems repository
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'openssl'
|
5
|
+
require 'io/console'
|
6
|
+
require 'base64'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'yaml'
|
9
|
+
require 'nexpose_sccm/utilities/utility_config'
|
10
|
+
|
11
|
+
SETTINGS_LOCATIONS = [File.join(File.dirname(__FILE__), '../conf/'),
|
12
|
+
File.join(File.dirname(__FILE__), '/'),
|
13
|
+
'/opt/rapid7/nexpose/scripts/',
|
14
|
+
'C:\\program files\\rapid7\\nexpose\\scripts\\']
|
15
|
+
|
16
|
+
options = {}
|
17
|
+
ops = OptionParser.new do |opts|
|
18
|
+
opts.banner = "Usage: #{$0} [options]\n"
|
19
|
+
|
20
|
+
opts.on('-s SETTINGS', '--settings SETTINGS', 'Path to settings directory with yml files') do |config|
|
21
|
+
options[:config_location] = config
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-h', '--help', 'Show this message') do
|
25
|
+
puts opts.help
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prompt function
|
31
|
+
def prompt(pwd, default, *args)
|
32
|
+
begin
|
33
|
+
print(*args)
|
34
|
+
result = ""
|
35
|
+
if pwd
|
36
|
+
result = STDIN.noecho(&:gets).strip
|
37
|
+
print("\n")
|
38
|
+
else
|
39
|
+
result = gets.strip
|
40
|
+
end
|
41
|
+
if (result.empty? || result.nil?) && (default.nil? || default.empty?)
|
42
|
+
raise
|
43
|
+
end
|
44
|
+
rescue
|
45
|
+
retry
|
46
|
+
end
|
47
|
+
return result.empty? ? default : result
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create directory function - careful as this will attempt to create
|
51
|
+
# parent directories that do not exist as well.
|
52
|
+
def create_dir(path, mode=nil)
|
53
|
+
FileUtils.mkdir_p(path) unless File.exist?(path)
|
54
|
+
FileUtils.chmod(mode, path) unless mode.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
begin
|
58
|
+
ops.parse! ARGV
|
59
|
+
rescue OptionParser::InvalidOption => error
|
60
|
+
puts "Error encountered. Details: #{error}\n\n#{ops}"
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
|
64
|
+
settings = UtilityConfig.load_config(SETTINGS_LOCATIONS,
|
65
|
+
options[:config_location])
|
66
|
+
|
67
|
+
unless settings.key?(:secret)
|
68
|
+
puts "The secret.yml file in the chosen / default location must be populated."
|
69
|
+
exit 0
|
70
|
+
end
|
71
|
+
|
72
|
+
to_encrypt = {}
|
73
|
+
|
74
|
+
# Read in settings.yml to identify what to encrypt; will begin with (enc)
|
75
|
+
settings.each do |key, value|
|
76
|
+
to_encrypt[key] = {} # unless key.to_s.eql?('secret')
|
77
|
+
value.each do |k, v|
|
78
|
+
if v.to_s.start_with?('(enc)')
|
79
|
+
to_encrypt[key][k] = v.sub('(enc)', '')
|
80
|
+
settings[key][k] = 'secret'
|
81
|
+
elsif v.class == Hash
|
82
|
+
v.each do |k2, v2|
|
83
|
+
if v2.to_s.start_with?('(enc)')
|
84
|
+
to_encrypt[key][k] = {} if to_encrypt[key][k].nil?
|
85
|
+
settings[key][k] = {} if settings[key][k].nil?
|
86
|
+
|
87
|
+
to_encrypt[key][k][k2] = v2.sub('(enc)', '')
|
88
|
+
settings[key][k][k2] = 'secret'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
if settings.key?(:secret)
|
96
|
+
if File.exist?(settings[:secret][:encrypt_key_dir]) && File.exist?(settings[:secret][:encrypt_cred_file])
|
97
|
+
priv_key = OpenSSL::PKey::RSA.new(File.read(File.join(settings[:secret][:encrypt_key_dir], 'rsa_key')))
|
98
|
+
dec_buf = priv_key.private_decrypt(Base64.decode64(File.read(settings[:secret][:encrypt_cred_file])))
|
99
|
+
current_settings = YAML::load(dec_buf)
|
100
|
+
current_settings.each do |k, v|
|
101
|
+
if to_encrypt.key?(k)
|
102
|
+
if to_encrypt[k].nil? || to_encrypt[k].empty?
|
103
|
+
to_encrypt[k] = v
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Assign directories. Make sure nxkeys is 700 permissions
|
111
|
+
# and the tree is owned by either root or the owner of the key file.
|
112
|
+
priv_dir = prompt(false, settings[:secret][:encrypt_key_dir], "Keys directory (default - #{settings[:secret][:encrypt_key_dir]}): ")
|
113
|
+
secret_file = prompt(false, settings[:secret][:encrypt_cred_file], "Encrypted settings file (default - #{settings[:secret][:encrypt_cred_file]}): ")
|
114
|
+
|
115
|
+
create_dir(priv_dir, 0700)
|
116
|
+
|
117
|
+
# Update and save settings.yml
|
118
|
+
UtilityConfig.save_encrypt(SETTINGS_LOCATIONS, options[:config_location])
|
119
|
+
|
120
|
+
# Protected private key file
|
121
|
+
priv_file = File.join(priv_dir, 'rsa_key')
|
122
|
+
|
123
|
+
# Generate private key and write to file.
|
124
|
+
rsa_key = OpenSSL::PKey::RSA.new(4096)
|
125
|
+
File.open(priv_file, 'w') {|file| file.write(rsa_key)}
|
126
|
+
FileUtils.chmod(0600, priv_file)
|
127
|
+
puts "Private key created."
|
128
|
+
# Generate public key from private key used to encrypt the credential YAML.
|
129
|
+
pub_key = rsa_key.public_key
|
130
|
+
|
131
|
+
# Encrypt then encode necessary settings
|
132
|
+
enc_creds = Base64.encode64(pub_key.public_encrypt(to_encrypt.to_yaml))
|
133
|
+
File.open(secret_file, 'w') {|file| file.write(enc_creds)}
|
134
|
+
FileUtils.chmod(0750, secret_file)
|
135
|
+
puts "Created encrypted credentials at #{secret_file}"
|
data/bin/nexpose_sccm
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'csv'
|
3
|
+
require 'base64'
|
4
|
+
require 'openssl'
|
5
|
+
require 'optparse'
|
6
|
+
require 'yaml'
|
7
|
+
require 'nexpose_sccm'
|
8
|
+
|
9
|
+
# module WinRM
|
10
|
+
# module HTTP
|
11
|
+
# # A generic HTTP transport that utilized HTTPClient to send messages back and forth.
|
12
|
+
# # This backend will maintain state for every WinRMWebService instance that is instantiated so it
|
13
|
+
# # is possible to use GSSAPI with Keep-Alive.
|
14
|
+
# class HttpTransport
|
15
|
+
# def verify_ssl_fingerprint(cert)
|
16
|
+
# return unless @ssl_peer_fingerprint
|
17
|
+
# conn_fingerprint = OpenSSL::Digest::SHA1.new(cert.to_der).to_s
|
18
|
+
# puts @ssl_peer_fingerprint
|
19
|
+
# puts conn_fingerprint
|
20
|
+
# return unless @ssl_peer_fingerprint.casecmp(conn_fingerprint) != 0
|
21
|
+
# raise "ssl fingerprint mismatch!!!!\n"
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
|
27
|
+
# Allow for override of options; -s leverage for settings directory location
|
28
|
+
@options = {}
|
29
|
+
|
30
|
+
ops = OptionParser.new do |opts|
|
31
|
+
opts.banner = 'Usage: nexpose_sccm [options]'
|
32
|
+
opts.on('-s SETTINGS', '--settings SETTINGS', 'Path to settings directory with yml files') do |config|
|
33
|
+
@options[:config_location] = config
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on('-i INPUT_FILE', '--input INPUT_FILE', 'Path to input file leveraged by query') do |config|
|
37
|
+
@options[:input_file_location] = config
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-h", "--help", "Show this message") do
|
41
|
+
puts opts
|
42
|
+
exit 0
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on_tail("--version", "Show version") do
|
46
|
+
puts "\nnexpose_sccm v#{NexposeSCCM::VERSION}"
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
ops.parse! ARGV
|
53
|
+
rescue OptionParser::InvalidOption => error
|
54
|
+
puts "Error encountered. Details: #{error}\n\n#{ops}"
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
|
58
|
+
SETTINGS_LOCATIONS = [File.join(File.dirname(__FILE__), '../conf/'),
|
59
|
+
File.join(File.dirname(__FILE__), '/'),
|
60
|
+
'/opt/rapid7/nexpose/scripts/',
|
61
|
+
'C:\\program files\\rapid7\\nexpose\\scripts\\']
|
62
|
+
|
63
|
+
# Load settings from -s option or parse known locations for configuration file
|
64
|
+
settings = UtilityConfig.load_config(SETTINGS_LOCATIONS,
|
65
|
+
@options[:config_location])
|
66
|
+
settings = UtilityConfig.load_encrypt(settings)
|
67
|
+
|
68
|
+
NexposeSCCM.setup(settings)
|
69
|
+
NexposeSCCM.generate_updates(settings, @options[:input_file_location])
|