pwn 0.4.430 → 0.4.433
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 +4 -4
- data/Gemfile +4 -4
- data/README.md +2 -2
- data/bin/pwn_nessus_cloud_create_scan +171 -25
- data/etc/userland/aws/nessus/vagrant.yaml.EXAMPLE +13 -0
- data/etc/userland/docker/nessus/vagrant.yaml.EXAMPLE +13 -0
- data/etc/userland/qemu/nessus/vagrant.yaml.EXAMPLE +13 -0
- data/etc/userland/ruby-gem/nessus/vagrant.yaml.EXAMPLE +13 -0
- data/etc/userland/virtualbox/nessus/vagrant.yaml.EXAMPLE +13 -0
- data/etc/userland/vmware/nessus/vagrant.yaml.EXAMPLE +13 -0
- data/lib/pwn/plugins/nessus_cloud.rb +182 -21
- data/lib/pwn/version.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0a46e9457e6865983d6c0c7fe5c80bdef0daf3a89145cf5c4d8209eff0b36ad0
|
|
4
|
+
data.tar.gz: 27dc83bbbad652c62eca8b27dddda5696c995bc4f129fcbf7678e50b4aeae6b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d7e7119ff10f046fbd3963135e26536385edc6cefc8d83b2c92b0bb11f5c2845df0dc2891e73eb8b5ec55c2af9cb94cd3ad4ae4fc3b45bd6fb06d9f95ab93a6
|
|
7
|
+
data.tar.gz: 668308f6e0c04786f522a28feea4a9758f1e423aaea1610011665d9e1329d093547f40dbf508d8b70d3544a2f76f50711926ed23fc04086cefc816fc2feb298d
|
data/Gemfile
CHANGED
|
@@ -18,8 +18,8 @@ gem 'aws-sdk', '3.1.0'
|
|
|
18
18
|
gem 'bettercap', '1.6.2'
|
|
19
19
|
gem 'brakeman', '5.2.3'
|
|
20
20
|
gem 'bson', '4.15.0'
|
|
21
|
-
gem 'bundler', '>=2.3.
|
|
22
|
-
gem 'bundler-audit', '0.9.
|
|
21
|
+
gem 'bundler', '>=2.3.14'
|
|
22
|
+
gem 'bundler-audit', '0.9.1'
|
|
23
23
|
gem 'bunny', '2.19.0'
|
|
24
24
|
gem 'colorize', '0.8.1'
|
|
25
25
|
gem 'credit_card_validations', '5.0.0'
|
|
@@ -61,7 +61,7 @@ gem 'rspec', '3.11.0'
|
|
|
61
61
|
gem 'rtesseract', '3.1.2'
|
|
62
62
|
gem 'rubocop', '1.29.1'
|
|
63
63
|
gem 'rubocop-rake', '0.6.0'
|
|
64
|
-
gem 'rubocop-rspec', '2.11.
|
|
64
|
+
gem 'rubocop-rspec', '2.11.1'
|
|
65
65
|
gem 'ruby-audio', '1.6.1'
|
|
66
66
|
gem 'ruby-nmap', '0.10.0'
|
|
67
67
|
gem 'ruby-saml', '1.14.0'
|
|
@@ -79,5 +79,5 @@ gem 'tty-prompt', '0.23.1'
|
|
|
79
79
|
gem 'watir', '7.1.0'
|
|
80
80
|
gem 'waveform', '0.1.2'
|
|
81
81
|
gem 'webrick', '1.7.0'
|
|
82
|
-
gem 'wicked_pdf', '2.6.
|
|
82
|
+
gem 'wicked_pdf', '2.6.3'
|
|
83
83
|
gem 'yard', '0.9.27'
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ $ rvm use ruby-3.1.2@pwn
|
|
|
37
37
|
$ rvm list gemsets
|
|
38
38
|
$ gem install --verbose pwn
|
|
39
39
|
$ pwn
|
|
40
|
-
pwn[v0.4.
|
|
40
|
+
pwn[v0.4.433]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.1.2@pwn
|
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
|
53
53
|
$ gem install --verbose pwn
|
|
54
54
|
$ pwn
|
|
55
|
-
pwn[v0.4.
|
|
55
|
+
pwn[v0.4.433]:001 >>> PWN.help
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
|
|
@@ -11,7 +11,7 @@ OptionParser.new do |options|
|
|
|
11
11
|
#{$PROGRAM_NAME} [opts]
|
|
12
12
|
"
|
|
13
13
|
|
|
14
|
-
options.on('-cYPATH', '--yaml-config=YPATH', '<Required - YAML Config Containing Access & Secret Keys for Authentication>') do |c|
|
|
14
|
+
options.on('-cYPATH', '--yaml-config=YPATH', '<Required - YAML Config Containing Access & Secret Keys for Authentication, Including Credential Information for Scan Creation (https://developer.tenable.com/docs/determine-settings-for-credential-type)>') do |c|
|
|
15
15
|
opts[:yaml_config] = c
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -19,15 +19,23 @@ OptionParser.new do |options|
|
|
|
19
19
|
opts[:scan_name] = n
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
options.on('-TTARGETS', '--text-targets=TARGETS', '<Required - Comma-delimited list of targets to scan>') do |t|
|
|
23
|
+
opts[:text_targets] = t
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
options.on('-dDESC', '--scan-description=DESC', '<Optional - Scan Description (Defaults to nil)>') do |d|
|
|
27
|
+
opts[:scan_desc] = d
|
|
28
|
+
end
|
|
29
|
+
|
|
22
30
|
options.on('-tVALUE', '--scan-template=VALUE', '<Optional - Canned Scan Template to Use for Scan Creation (Defaults to "Basic Network Scan">') do |t|
|
|
23
31
|
opts[:scan_template] = t
|
|
24
32
|
end
|
|
25
33
|
|
|
26
|
-
options.on('-pPOLICY', '--policy-name=POLICY', '<Optional - Policy to Use to Create the Scan
|
|
34
|
+
options.on('-pPOLICY', '--policy-name=POLICY', '<Optional - Policy to Use to Create the Scan>') do |p|
|
|
27
35
|
opts[:policy_name] = p
|
|
28
36
|
end
|
|
29
37
|
|
|
30
|
-
options.on('-fFOLDER', '--folder-name=FOLDER', '<Optional - Where to Store the Scan (Defaults to "
|
|
38
|
+
options.on('-fFOLDER', '--folder-name=FOLDER', '<Optional - Where to Store the Scan (Defaults to "My Scans")>') do |f|
|
|
31
39
|
opts[:folder_name] = f
|
|
32
40
|
end
|
|
33
41
|
|
|
@@ -35,17 +43,33 @@ OptionParser.new do |options|
|
|
|
35
43
|
opts[:scanner_name] = s
|
|
36
44
|
end
|
|
37
45
|
|
|
38
|
-
options.on('-
|
|
39
|
-
opts[:
|
|
46
|
+
options.on('-D', '--disable-scan', '<Optional - If true, the schedule for the scan is disabled (Defaults to false)>') do |d|
|
|
47
|
+
opts[:disabled] = d
|
|
40
48
|
end
|
|
41
49
|
|
|
42
|
-
options.on('-
|
|
43
|
-
opts[:
|
|
50
|
+
options.on('-NTARGET', '--target-network-name=TARGET', '<Optional - If --scanner other than AUTO-ROUTED, Otherwise Required - Network to Scan (Defaults to "Default")>') do |n|
|
|
51
|
+
opts[:target_network_name] = n
|
|
44
52
|
end
|
|
45
53
|
|
|
46
|
-
options.on('-
|
|
54
|
+
options.on('-lWHEN', '--launch=WHEN', '<Optional - When to Launch Scan - ON_DEMAND || DAILY || WEEKLY || MONTHLY || YEARLY (Defaults to "ON_DEMAND")>') do |l|
|
|
47
55
|
opts[:launch] = l
|
|
48
56
|
end
|
|
57
|
+
|
|
58
|
+
options.on('-wTIMEWINDOW', '--scan-time-window=TIMEWINDOW', '<Optional - Scan Time Window in Minutes - (Defaults to 0)>') do |t|
|
|
59
|
+
opts[:scan_time_window] = t
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
options.on('-STIME', '--start-time=TIME', '<Optional - For One-Time Scans, the Starting Time and Date for the Scan - (Defaults to Time.now.strftime("%Y%m%dT%H%M%S")>') do |t|
|
|
63
|
+
opts[:starttime] = t
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
options.on('-rRRULES', '--rrules=RRULES', '<Optional - For One-Time Scans, the Starting Time and Date for the Scan - (Defaults to "FREQ=ONETIME;INTERVAL=0;BYDAY=null")>') do |r|
|
|
67
|
+
opts[:rrules] = r
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
options.on('-zTIMEZONE', '--timezone=TIMEZONE', '<Optional - Timezone of the scheduled start time for the scan - (Defaults to "UTC")>') do |t|
|
|
71
|
+
opts[:timezone] = t
|
|
72
|
+
end
|
|
49
73
|
end.parse!
|
|
50
74
|
|
|
51
75
|
if opts.empty?
|
|
@@ -54,6 +78,7 @@ if opts.empty?
|
|
|
54
78
|
end
|
|
55
79
|
|
|
56
80
|
begin
|
|
81
|
+
# Get Options Passed to pwn_nessus_cloud_create_scan
|
|
57
82
|
yaml_config = opts[:yaml_config]
|
|
58
83
|
|
|
59
84
|
raise "YAML Config Not Found: #{yaml_config}" unless File.exist?(yaml_config)
|
|
@@ -66,7 +91,10 @@ begin
|
|
|
66
91
|
access_key = yaml[:access_key]
|
|
67
92
|
secret_key = yaml[:secret_key]
|
|
68
93
|
|
|
94
|
+
credentials = yaml[:create_scan][:credentials]
|
|
95
|
+
|
|
69
96
|
scan_name = opts[:scan_name]
|
|
97
|
+
scan_desc = opts[:scan_desc]
|
|
70
98
|
|
|
71
99
|
scan_template = opts[:scan_template]
|
|
72
100
|
scan_template ||= 'Basic Network Scan'
|
|
@@ -75,57 +103,175 @@ begin
|
|
|
75
103
|
policy_name ||= ''
|
|
76
104
|
|
|
77
105
|
folder_name = opts[:folder_name]
|
|
78
|
-
folder_name ||= '
|
|
106
|
+
folder_name ||= 'My Scans'
|
|
79
107
|
|
|
80
108
|
scanner_name = opts[:scanner_name]
|
|
81
109
|
scanner_name ||= 'AUTO-ROUTED'
|
|
82
110
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
target_network_name = opts[:target_network_name]
|
|
112
|
+
target_network_name ||= 'Default'
|
|
113
|
+
|
|
114
|
+
disabled = true if opts[:disabled]
|
|
115
|
+
disabled ||= false
|
|
116
|
+
|
|
117
|
+
enabled = true
|
|
118
|
+
enabled = false if disabled
|
|
86
119
|
|
|
87
120
|
launch = opts[:launch]
|
|
88
121
|
launch ||= 'ON_DEMAND'
|
|
89
122
|
|
|
90
|
-
scan_time_window = opts[:scan_time_window]
|
|
123
|
+
scan_time_window = opts[:scan_time_window].to_i
|
|
124
|
+
scan_time_window ||= 0
|
|
125
|
+
|
|
126
|
+
starttime = opts[:starttime]
|
|
127
|
+
starttime ||= Time.now.strftime('%Y%m%dT%H%M%S')
|
|
128
|
+
|
|
129
|
+
rrules = opts[:rrules]
|
|
130
|
+
rrules ||= 'FREQ=ONETIME;INTERVAL=0;BYDAY=null'
|
|
131
|
+
|
|
132
|
+
timezone = opts[:timezone]
|
|
133
|
+
timezone ||= 'UTC'
|
|
134
|
+
|
|
135
|
+
text_targets = opts[:text_targets]
|
|
136
|
+
raise 'ERROR: --text-targets (i.e. List of targets to scan) is required.' unless text_targets
|
|
137
|
+
|
|
138
|
+
target_groups = opts[:target_groups]
|
|
139
|
+
|
|
140
|
+
file_targets = opts[:file_targets]
|
|
141
|
+
|
|
142
|
+
tag_targets = opts[:tag_targets]
|
|
143
|
+
tag_targets_arr = tag_targets.split(',')
|
|
144
|
+
|
|
145
|
+
agent_group_name = opts[:agent_group_name]
|
|
146
|
+
agent_group_id_arr = []
|
|
147
|
+
|
|
148
|
+
agent_scan_launch_type = opts[:agent_scan_launch_type]
|
|
149
|
+
agent_scan_launch_type ||= 'triggered'
|
|
150
|
+
|
|
151
|
+
triggers_arr = []
|
|
152
|
+
triggers = {}
|
|
153
|
+
triggers[:type] = agent_scan_launch_type
|
|
154
|
+
triggers[:type] ||= 'periodic'
|
|
155
|
+
|
|
156
|
+
triggers[:options] = {}
|
|
157
|
+
case agent_scan_launch_type
|
|
158
|
+
when 'periodic'
|
|
159
|
+
triggers[:options][:periodic_hourly_interval] = opts[:periodic_hourly_interval]
|
|
160
|
+
triggers[:options][:periodic_hourly_interval] ||= 0
|
|
161
|
+
when 'file-exists'
|
|
162
|
+
triggers[:options][:filename] = opts[:filename]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
triggers_arr.push(triggers)
|
|
166
|
+
|
|
167
|
+
emails = opts[:emails]
|
|
168
|
+
|
|
169
|
+
acls = {}
|
|
170
|
+
acls[:permissions] = opts[:acl_permissions]
|
|
171
|
+
acls[:owner] = opts[:acl_owner]
|
|
172
|
+
acls[:display_name] = opts[:acl_display_name]
|
|
173
|
+
acls[:name] = opts[:acl_name]
|
|
174
|
+
acls[:id] = opts[:acl_id]
|
|
175
|
+
acls[:type] = opts[:acl_type]
|
|
176
|
+
|
|
177
|
+
credential_category = opts[:credential_category]
|
|
178
|
+
credential_type = opts[:credential_type]
|
|
91
179
|
|
|
180
|
+
# Begin Here
|
|
92
181
|
nessus_obj = PWN::Plugins::NessusCloud.login(
|
|
93
182
|
access_key: access_key,
|
|
94
183
|
secret_key: secret_key
|
|
95
184
|
)
|
|
96
185
|
|
|
186
|
+
# Requirements to create a scan:
|
|
187
|
+
# Part 1: Populate uuid
|
|
188
|
+
# Part 2: Populate settings object from options passed to driver
|
|
189
|
+
# Part 3: Populate credentials object from YAML config (optional)
|
|
190
|
+
# Part 4: Populate plugins object from YAML config (optional)
|
|
191
|
+
|
|
192
|
+
# Part 1: Populate uuid
|
|
193
|
+
# TODO: add --list-canned-scan-templates option
|
|
97
194
|
scan_template = PWN::Plugins::NessusCloud.get_canned_scan_templates(
|
|
98
195
|
nessus_obj: nessus_obj,
|
|
99
|
-
|
|
196
|
+
name: scan_template
|
|
100
197
|
)
|
|
101
|
-
|
|
102
|
-
puts
|
|
198
|
+
scan_template_uuid = scan_template[:uuid]
|
|
199
|
+
puts scan_template_uuid
|
|
200
|
+
|
|
201
|
+
# Part 2: Populate settings object from options passed to driver
|
|
202
|
+
settings = {}
|
|
203
|
+
settings[:name] = scan_name
|
|
204
|
+
settings[:description] = scan_desc
|
|
103
205
|
|
|
104
206
|
policy = PWN::Plugins::NessusCloud.get_policies(
|
|
105
207
|
nessus_obj: nessus_obj,
|
|
106
208
|
name: policy_name
|
|
107
209
|
)
|
|
108
|
-
policy_id = policy[:id]
|
|
109
|
-
puts policy_id
|
|
210
|
+
settings[:policy_id] = policy[:id]
|
|
110
211
|
|
|
111
212
|
folder = PWN::Plugins::NessusCloud.get_folders(
|
|
112
213
|
nessus_obj: nessus_obj,
|
|
113
214
|
name: folder_name
|
|
114
215
|
)
|
|
115
|
-
folder_id = folder[:id]
|
|
116
|
-
puts folder_id
|
|
216
|
+
settings[:folder_id] = folder[:id]
|
|
117
217
|
|
|
118
218
|
scanner = PWN::Plugins::NessusCloud.get_scanners(
|
|
119
219
|
nessus_obj: nessus_obj,
|
|
120
220
|
name: scanner_name
|
|
121
221
|
)
|
|
122
|
-
scanner_id = scanner[:id]
|
|
123
|
-
|
|
222
|
+
settings[:scanner_id] = scanner[:id]
|
|
223
|
+
|
|
224
|
+
target_network = PWN::Plugins::NessusCloud.get_target_networks(
|
|
225
|
+
nessus_obj: nessus_obj,
|
|
226
|
+
name: target_network_name
|
|
227
|
+
)
|
|
228
|
+
settings[:target_network_uuid] = target_network[:uuid]
|
|
229
|
+
|
|
230
|
+
settings[:enabled] = enabled
|
|
231
|
+
|
|
232
|
+
settings[:launch] = launch
|
|
233
|
+
|
|
234
|
+
settings[:scan_time_window] = scan_time_window
|
|
235
|
+
|
|
236
|
+
settings[:starttime] = starttime
|
|
237
|
+
|
|
238
|
+
settings[:rrules] = rrules
|
|
124
239
|
|
|
125
|
-
|
|
126
|
-
|
|
240
|
+
settings[:timezone] = timezone
|
|
241
|
+
|
|
242
|
+
settings[:text_targets] = text_targets
|
|
243
|
+
|
|
244
|
+
settings[:target_groups] = target_groups
|
|
245
|
+
|
|
246
|
+
settings[:file_targets] = file_targets
|
|
247
|
+
|
|
248
|
+
settings[:tag_targets] = tag_targets_arr
|
|
249
|
+
|
|
250
|
+
settings[:agent_group_id] = agent_group_id_arr
|
|
251
|
+
|
|
252
|
+
settings[:agent_scan_launch_type] = agent_scan_launch_type
|
|
253
|
+
|
|
254
|
+
settings[:triggers] = triggers_arr
|
|
255
|
+
|
|
256
|
+
settings[:emails] = emails
|
|
257
|
+
|
|
258
|
+
settings[:acls] = acls
|
|
259
|
+
|
|
260
|
+
# Part 3: Populate credentials object from YAML config (optional)
|
|
261
|
+
credentials = yaml[:credentials]
|
|
262
|
+
|
|
263
|
+
# Part 4: Populate plugins object from YAML config (optional)
|
|
264
|
+
plugins = yaml[:plugins]
|
|
265
|
+
|
|
266
|
+
create_scan_resp = PWN::Plugins::NessusCloud.create_scan(
|
|
267
|
+
nessus_obj: nessus_obj,
|
|
268
|
+
scan_template_uuid: scan_template_uuid,
|
|
269
|
+
settings: settings,
|
|
270
|
+
credentials: credentials,
|
|
271
|
+
plugins: plugins
|
|
127
272
|
)
|
|
128
|
-
|
|
273
|
+
|
|
274
|
+
puts create_scan_resp.inspect
|
|
129
275
|
rescue Interrupt
|
|
130
276
|
puts 'CTRL+C detected...goodbye.'
|
|
131
277
|
rescue StandardError => e
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
access_key: 'ACCESS_KEY'
|
|
2
2
|
secret_key: 'SECRET_KEY'
|
|
3
|
+
credentials:
|
|
4
|
+
add:
|
|
5
|
+
Host:
|
|
6
|
+
Windows:
|
|
7
|
+
- domain: 'dc.local'
|
|
8
|
+
username: 'USERNAME'
|
|
9
|
+
auth_method: 'Password'
|
|
10
|
+
password: 'PASSWORD'
|
|
11
|
+
plugins:
|
|
12
|
+
Web Servers:
|
|
13
|
+
individual:
|
|
14
|
+
'11213': enabled
|
|
15
|
+
'18261': enabled
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
access_key: 'ACCESS_KEY'
|
|
2
2
|
secret_key: 'SECRET_KEY'
|
|
3
|
+
credentials:
|
|
4
|
+
add:
|
|
5
|
+
Host:
|
|
6
|
+
Windows:
|
|
7
|
+
- domain: 'dc.local'
|
|
8
|
+
username: 'USERNAME'
|
|
9
|
+
auth_method: 'Password'
|
|
10
|
+
password: 'PASSWORD'
|
|
11
|
+
plugins:
|
|
12
|
+
Web Servers:
|
|
13
|
+
individual:
|
|
14
|
+
'11213': enabled
|
|
15
|
+
'18261': enabled
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
access_key: 'ACCESS_KEY'
|
|
2
2
|
secret_key: 'SECRET_KEY'
|
|
3
|
+
credentials:
|
|
4
|
+
add:
|
|
5
|
+
Host:
|
|
6
|
+
Windows:
|
|
7
|
+
- domain: 'dc.local'
|
|
8
|
+
username: 'USERNAME'
|
|
9
|
+
auth_method: 'Password'
|
|
10
|
+
password: 'PASSWORD'
|
|
11
|
+
plugins:
|
|
12
|
+
Web Servers:
|
|
13
|
+
individual:
|
|
14
|
+
'11213': enabled
|
|
15
|
+
'18261': enabled
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
access_key: 'ACCESS_KEY'
|
|
2
2
|
secret_key: 'SECRET_KEY'
|
|
3
|
+
credentials:
|
|
4
|
+
add:
|
|
5
|
+
Host:
|
|
6
|
+
Windows:
|
|
7
|
+
- domain: 'dc.local'
|
|
8
|
+
username: 'USERNAME'
|
|
9
|
+
auth_method: 'Password'
|
|
10
|
+
password: 'PASSWORD'
|
|
11
|
+
plugins:
|
|
12
|
+
Web Servers:
|
|
13
|
+
individual:
|
|
14
|
+
'11213': enabled
|
|
15
|
+
'18261': enabled
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
access_key: 'ACCESS_KEY'
|
|
2
2
|
secret_key: 'SECRET_KEY'
|
|
3
|
+
credentials:
|
|
4
|
+
add:
|
|
5
|
+
Host:
|
|
6
|
+
Windows:
|
|
7
|
+
- domain: 'dc.local'
|
|
8
|
+
username: 'USERNAME'
|
|
9
|
+
auth_method: 'Password'
|
|
10
|
+
password: 'PASSWORD'
|
|
11
|
+
plugins:
|
|
12
|
+
Web Servers:
|
|
13
|
+
individual:
|
|
14
|
+
'11213': enabled
|
|
15
|
+
'18261': enabled
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
access_key: 'ACCESS_KEY'
|
|
2
2
|
secret_key: 'SECRET_KEY'
|
|
3
|
+
credentials:
|
|
4
|
+
add:
|
|
5
|
+
Host:
|
|
6
|
+
Windows:
|
|
7
|
+
- domain: 'dc.local'
|
|
8
|
+
username: 'USERNAME'
|
|
9
|
+
auth_method: 'Password'
|
|
10
|
+
password: 'PASSWORD'
|
|
11
|
+
plugins:
|
|
12
|
+
Web Servers:
|
|
13
|
+
individual:
|
|
14
|
+
'11213': enabled
|
|
15
|
+
'18261': enabled
|
|
@@ -94,12 +94,13 @@ module PWN
|
|
|
94
94
|
|
|
95
95
|
# Supported Method Parameters::
|
|
96
96
|
# PWN::Plugins::NessusCloud.get_canned_scan_templates(
|
|
97
|
-
# nessus_obj: 'required - nessus_obj returned from #login method'
|
|
97
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
98
|
+
# name: 'optional - name of scan template'
|
|
98
99
|
# )
|
|
99
100
|
|
|
100
101
|
public_class_method def self.get_canned_scan_templates(opts = {})
|
|
101
102
|
nessus_obj = opts[:nessus_obj]
|
|
102
|
-
|
|
103
|
+
name = opts[:name]
|
|
103
104
|
|
|
104
105
|
scan_templates_resp = nessus_cloud_rest_call(
|
|
105
106
|
nessus_obj: nessus_obj,
|
|
@@ -108,9 +109,9 @@ module PWN
|
|
|
108
109
|
|
|
109
110
|
scan_templates = JSON.parse(scan_templates_resp, symbolize_names: true)
|
|
110
111
|
|
|
111
|
-
if
|
|
112
|
+
if name
|
|
112
113
|
selected_scan_template = scan_templates[:templates].select do |sc|
|
|
113
|
-
sc[:title] ==
|
|
114
|
+
sc[:title] == name
|
|
114
115
|
end
|
|
115
116
|
scan_templates = selected_scan_template.first if selected_scan_template.any?
|
|
116
117
|
scan_templates ||= {}
|
|
@@ -123,19 +124,20 @@ module PWN
|
|
|
123
124
|
|
|
124
125
|
# Supported Method Parameters::
|
|
125
126
|
# PWN::Plugins::NessusCloud.get_policies(
|
|
126
|
-
# nessus_obj: 'required - nessus_obj returned from #login method'
|
|
127
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
128
|
+
# name: 'optional - name of policy (i.e. user-defined template)'
|
|
127
129
|
# )
|
|
128
130
|
|
|
129
131
|
public_class_method def self.get_policies(opts = {})
|
|
130
132
|
nessus_obj = opts[:nessus_obj]
|
|
131
133
|
name = opts[:name]
|
|
132
134
|
|
|
133
|
-
|
|
135
|
+
policies_resp = nessus_cloud_rest_call(
|
|
134
136
|
nessus_obj: nessus_obj,
|
|
135
137
|
rest_call: 'policies'
|
|
136
138
|
).body
|
|
137
139
|
|
|
138
|
-
policies = JSON.parse(
|
|
140
|
+
policies = JSON.parse(policies_resp, symbolize_names: true)
|
|
139
141
|
|
|
140
142
|
if name
|
|
141
143
|
selected_policy = policies[:policies].select do |p|
|
|
@@ -152,19 +154,20 @@ module PWN
|
|
|
152
154
|
|
|
153
155
|
# Supported Method Parameters::
|
|
154
156
|
# PWN::Plugins::NessusCloud.get_folders(
|
|
155
|
-
# nessus_obj: 'required - nessus_obj returned from #login method'
|
|
157
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
158
|
+
# name: 'optional - name of folder'
|
|
156
159
|
# )
|
|
157
160
|
|
|
158
161
|
public_class_method def self.get_folders(opts = {})
|
|
159
162
|
nessus_obj = opts[:nessus_obj]
|
|
160
163
|
name = opts[:name]
|
|
161
164
|
|
|
162
|
-
|
|
165
|
+
folders_resp = nessus_cloud_rest_call(
|
|
163
166
|
nessus_obj: nessus_obj,
|
|
164
167
|
rest_call: 'folders'
|
|
165
168
|
).body
|
|
166
169
|
|
|
167
|
-
folders = JSON.parse(
|
|
170
|
+
folders = JSON.parse(folders_resp, symbolize_names: true)
|
|
168
171
|
|
|
169
172
|
if name
|
|
170
173
|
selected_folder = folders[:folders].select do |f|
|
|
@@ -181,19 +184,20 @@ module PWN
|
|
|
181
184
|
|
|
182
185
|
# Supported Method Parameters::
|
|
183
186
|
# PWN::Plugins::NessusCloud.get_scanners(
|
|
184
|
-
# nessus_obj: 'required - nessus_obj returned from #login method'
|
|
187
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
188
|
+
# name: 'optional - name of scanner'
|
|
185
189
|
# )
|
|
186
190
|
|
|
187
191
|
public_class_method def self.get_scanners(opts = {})
|
|
188
192
|
nessus_obj = opts[:nessus_obj]
|
|
189
193
|
name = opts[:name]
|
|
190
194
|
|
|
191
|
-
|
|
195
|
+
scanners_resp = nessus_cloud_rest_call(
|
|
192
196
|
nessus_obj: nessus_obj,
|
|
193
197
|
rest_call: 'scanners'
|
|
194
198
|
).body
|
|
195
199
|
|
|
196
|
-
scanners = JSON.parse(
|
|
200
|
+
scanners = JSON.parse(scanners_resp, symbolize_names: true)
|
|
197
201
|
|
|
198
202
|
if name
|
|
199
203
|
selected_scanner = scanners[:scanners].select do |s|
|
|
@@ -210,18 +214,165 @@ module PWN
|
|
|
210
214
|
|
|
211
215
|
# Supported Method Parameters::
|
|
212
216
|
# PWN::Plugins::NessusCloud.get_target_networks(
|
|
213
|
-
# nessus_obj: 'required - nessus_obj returned from #login method'
|
|
217
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
218
|
+
# name: 'optional - name of target network'
|
|
214
219
|
# )
|
|
215
220
|
|
|
216
221
|
public_class_method def self.get_target_networks(opts = {})
|
|
217
222
|
nessus_obj = opts[:nessus_obj]
|
|
223
|
+
name = opts[:name]
|
|
218
224
|
|
|
219
|
-
|
|
225
|
+
target_networks_resp = nessus_cloud_rest_call(
|
|
220
226
|
nessus_obj: nessus_obj,
|
|
221
227
|
rest_call: 'networks'
|
|
222
228
|
).body
|
|
223
229
|
|
|
224
|
-
JSON.parse(
|
|
230
|
+
target_networks = JSON.parse(target_networks_resp, symbolize_names: true)
|
|
231
|
+
|
|
232
|
+
if name
|
|
233
|
+
selected_network = target_networks[:networks].select do |tn|
|
|
234
|
+
tn[:name] == name
|
|
235
|
+
end
|
|
236
|
+
target_networks = selected_network.first if selected_network.any?
|
|
237
|
+
target_networks ||= {}
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
target_networks
|
|
241
|
+
rescue StandardError, SystemExit, Interrupt => e
|
|
242
|
+
raise e
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Supported Method Parameters::
|
|
246
|
+
# PWN::Plugins::NessusCloud.get_timezones(
|
|
247
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
248
|
+
# name: 'optional - name of timezone'
|
|
249
|
+
# )
|
|
250
|
+
|
|
251
|
+
public_class_method def self.get_timezones(opts = {})
|
|
252
|
+
nessus_obj = opts[:nessus_obj]
|
|
253
|
+
name = opts[:name]
|
|
254
|
+
|
|
255
|
+
timezones_resp = nessus_cloud_rest_call(
|
|
256
|
+
nessus_obj: nessus_obj,
|
|
257
|
+
rest_call: 'scans/timezones'
|
|
258
|
+
).body
|
|
259
|
+
|
|
260
|
+
timezones = JSON.parse(timezones_resp, symbolize_names: true)
|
|
261
|
+
|
|
262
|
+
if name
|
|
263
|
+
selected_timezone = timezones[:networks].select do |tz|
|
|
264
|
+
tz[:name] == name
|
|
265
|
+
end
|
|
266
|
+
timezones = selected_timezone.first if selected_timezone.any?
|
|
267
|
+
timezones ||= {}
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
timezones
|
|
271
|
+
rescue StandardError, SystemExit, Interrupt => e
|
|
272
|
+
raise e
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Supported Method Parameters::
|
|
276
|
+
# PWN::Plugins::NessusCloud.get_target_groups(
|
|
277
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
278
|
+
# name: 'optional - name of timezone'
|
|
279
|
+
# )
|
|
280
|
+
# )
|
|
281
|
+
|
|
282
|
+
public_class_method def self.get_target_groups(opts = {})
|
|
283
|
+
nessus_obj = opts[:nessus_obj]
|
|
284
|
+
name = opts[:name]
|
|
285
|
+
|
|
286
|
+
target_groups_resp = nessus_cloud_rest_call(
|
|
287
|
+
nessus_obj: nessus_obj,
|
|
288
|
+
rest_call: 'target-groups'
|
|
289
|
+
).body
|
|
290
|
+
|
|
291
|
+
timezones = JSON.parse(target_groups_resp, symbolize_names: true)
|
|
292
|
+
|
|
293
|
+
if name
|
|
294
|
+
selected_timezone = timezones[:networks].select do |tz|
|
|
295
|
+
tz[:name] == name
|
|
296
|
+
end
|
|
297
|
+
timezones = selected_timezone.first if selected_timezone.any?
|
|
298
|
+
timezones ||= {}
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
timezones
|
|
302
|
+
rescue StandardError, SystemExit, Interrupt => e
|
|
303
|
+
raise e
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Supported Method Parameters::
|
|
307
|
+
# PWN::Plugins::NessusCloud.get_credential_types(
|
|
308
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
309
|
+
# category: 'optional - category of credential type (Defaults to "Host")',
|
|
310
|
+
# name: 'optional - name of credential type (Defaults to "SSH")'
|
|
311
|
+
# )
|
|
312
|
+
# )
|
|
313
|
+
|
|
314
|
+
public_class_method def self.get_credential_types(opts = {})
|
|
315
|
+
nessus_obj = opts[:nessus_obj]
|
|
316
|
+
category = opts[:category].to_s.downcase
|
|
317
|
+
name = opts[:name].to_s.downcase
|
|
318
|
+
|
|
319
|
+
raise 'ERROR: name parameter requires category parameter.' if category.empty? && !name.empty?
|
|
320
|
+
|
|
321
|
+
credential_types_resp = nessus_cloud_rest_call(
|
|
322
|
+
nessus_obj: nessus_obj,
|
|
323
|
+
rest_call: 'credentials/types'
|
|
324
|
+
).body
|
|
325
|
+
|
|
326
|
+
credential_types = JSON.parse(credential_types_resp, symbolize_names: true)
|
|
327
|
+
|
|
328
|
+
if category
|
|
329
|
+
selected_credential_category = credential_types[:credentials].select do |cc|
|
|
330
|
+
cc[:category].downcase == category
|
|
331
|
+
end
|
|
332
|
+
credential_types = selected_credential_category.first if selected_credential_category.any?
|
|
333
|
+
credential_types ||= {}
|
|
334
|
+
|
|
335
|
+
if name
|
|
336
|
+
selected_credential_type = credential_types[:types].select do |ct|
|
|
337
|
+
ct[:name].downcase == name
|
|
338
|
+
end
|
|
339
|
+
credential_types = selected_credential_type.first if selected_credential_type.any?
|
|
340
|
+
credential_types ||= {}
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
credential_types
|
|
346
|
+
rescue StandardError, SystemExit, Interrupt => e
|
|
347
|
+
raise e
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Supported Method Parameters::
|
|
351
|
+
# PWN::Plugins::NessusCloud.create_scan(
|
|
352
|
+
# nessus_obj: 'required - nessus_obj returned from #login method',
|
|
353
|
+
# scan_template_uuid: 'required - the UUID for the Tenable-provided scan template to use. Run #get_canned_scan_templates for a list of UUIDs',
|
|
354
|
+
# settings: 'required - settings object as defined by https://developer.tenable.com/reference/scans-create',
|
|
355
|
+
# credentials: 'required - credentials object as defined by https://developer.tenable.com/reference/scans-create',
|
|
356
|
+
# plugins: 'optional - plugins object as defined by https://developer.tenable.com/reference/scans-create (Defaults to {})'
|
|
357
|
+
# )
|
|
358
|
+
|
|
359
|
+
public_class_method def self.create_scan(opts = {})
|
|
360
|
+
nessus_obj = opts[:nessus_obj]
|
|
361
|
+
|
|
362
|
+
http_body = {}
|
|
363
|
+
http_body[:uuid] = opts[:scan_template_uuid]
|
|
364
|
+
http_body[:settings] = opts[:settings]
|
|
365
|
+
http_body[:credentials] = opts[:credentials]
|
|
366
|
+
http_body[:plugins] = opts[:plugins]
|
|
367
|
+
|
|
368
|
+
create_scan_resp = nessus_cloud_rest_call(
|
|
369
|
+
http_method: :post,
|
|
370
|
+
nessus_obj: nessus_obj,
|
|
371
|
+
rest_call: 'scans',
|
|
372
|
+
http_body: http_body
|
|
373
|
+
).body
|
|
374
|
+
|
|
375
|
+
JSON.parse(create_scan_resp, symbolize_names: true)
|
|
225
376
|
rescue StandardError, SystemExit, Interrupt => e
|
|
226
377
|
raise e
|
|
227
378
|
end
|
|
@@ -429,23 +580,33 @@ module PWN
|
|
|
429
580
|
)
|
|
430
581
|
|
|
431
582
|
#{self}.get_canned_scan_templates(
|
|
432
|
-
nessus_obj: 'required - nessus_obj returned from #login method'
|
|
583
|
+
nessus_obj: 'required - nessus_obj returned from #login method',
|
|
584
|
+
name: 'optional - name of scan template'
|
|
433
585
|
)
|
|
434
586
|
|
|
435
587
|
#{self}.get_policies(
|
|
436
|
-
nessus_obj: 'required - nessus_obj returned from #login method'
|
|
588
|
+
nessus_obj: 'required - nessus_obj returned from #login method',
|
|
589
|
+
name: 'optional - name of policy (i.e. user-defined template)'
|
|
437
590
|
)
|
|
438
591
|
|
|
439
592
|
#{self}.get_folders(
|
|
440
|
-
nessus_obj: 'required - nessus_obj returned from #login method'
|
|
593
|
+
nessus_obj: 'required - nessus_obj returned from #login method',
|
|
594
|
+
name: 'optional - name of folder'
|
|
441
595
|
)
|
|
442
596
|
|
|
443
597
|
#{self}.get_scanners(
|
|
444
|
-
nessus_obj: 'required - nessus_obj returned from #login method'
|
|
598
|
+
nessus_obj: 'required - nessus_obj returned from #login method',
|
|
599
|
+
name: 'optional - name of scanner'
|
|
445
600
|
)
|
|
446
601
|
|
|
447
602
|
#{self}.get_target_networks(
|
|
448
|
-
nessus_obj: 'required - nessus_obj returned from #login method'
|
|
603
|
+
nessus_obj: 'required - nessus_obj returned from #login method',
|
|
604
|
+
name: 'optional - name of target network'
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
#{self}.get_timezones(
|
|
608
|
+
nessus_obj: 'required - nessus_obj returned from #login method',
|
|
609
|
+
name: 'optional - name of timezone'
|
|
449
610
|
)
|
|
450
611
|
|
|
451
612
|
#{self}.get_scans(
|
data/lib/pwn/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pwn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.433
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-05-
|
|
11
|
+
date: 2022-05-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -114,28 +114,28 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - ">="
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 2.3.
|
|
117
|
+
version: 2.3.14
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 2.3.
|
|
124
|
+
version: 2.3.14
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: bundler-audit
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
129
|
- - '='
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: 0.9.
|
|
131
|
+
version: 0.9.1
|
|
132
132
|
type: :runtime
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - '='
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: 0.9.
|
|
138
|
+
version: 0.9.1
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: bunny
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -702,14 +702,14 @@ dependencies:
|
|
|
702
702
|
requirements:
|
|
703
703
|
- - '='
|
|
704
704
|
- !ruby/object:Gem::Version
|
|
705
|
-
version: 2.11.
|
|
705
|
+
version: 2.11.1
|
|
706
706
|
type: :runtime
|
|
707
707
|
prerelease: false
|
|
708
708
|
version_requirements: !ruby/object:Gem::Requirement
|
|
709
709
|
requirements:
|
|
710
710
|
- - '='
|
|
711
711
|
- !ruby/object:Gem::Version
|
|
712
|
-
version: 2.11.
|
|
712
|
+
version: 2.11.1
|
|
713
713
|
- !ruby/object:Gem::Dependency
|
|
714
714
|
name: ruby-audio
|
|
715
715
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -954,14 +954,14 @@ dependencies:
|
|
|
954
954
|
requirements:
|
|
955
955
|
- - '='
|
|
956
956
|
- !ruby/object:Gem::Version
|
|
957
|
-
version: 2.6.
|
|
957
|
+
version: 2.6.3
|
|
958
958
|
type: :runtime
|
|
959
959
|
prerelease: false
|
|
960
960
|
version_requirements: !ruby/object:Gem::Requirement
|
|
961
961
|
requirements:
|
|
962
962
|
- - '='
|
|
963
963
|
- !ruby/object:Gem::Version
|
|
964
|
-
version: 2.6.
|
|
964
|
+
version: 2.6.3
|
|
965
965
|
- !ruby/object:Gem::Dependency
|
|
966
966
|
name: yard
|
|
967
967
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -1968,7 +1968,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1968
1968
|
- !ruby/object:Gem::Version
|
|
1969
1969
|
version: '0'
|
|
1970
1970
|
requirements: []
|
|
1971
|
-
rubygems_version: 3.3.
|
|
1971
|
+
rubygems_version: 3.3.14
|
|
1972
1972
|
signing_key:
|
|
1973
1973
|
specification_version: 4
|
|
1974
1974
|
summary: Automated Security Testing for CI/CD Pipelines & Beyond
|