pwn 0.5.398 → 0.5.399

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39074d56f83a8de876485919dc9e9e84e1bef64d200c2400d47de8a6bb992b95
4
- data.tar.gz: 473823371595e3f73f9f96d89bfc692fa8511e4b48f5c26680ed66573de0acf5
3
+ metadata.gz: e10ec68e7ef2ebf6cce111bacbb8c9fbe95a5f5db4f775f845f1d1829d30f89a
4
+ data.tar.gz: 0fec666835b27fae7f193a6468d78c5351eec13cffd6293d3e175fec7dcc3891
5
5
  SHA512:
6
- metadata.gz: f36ab7c999280bdc5d02c18d0aab8ab1246700eac42abb720e31880c1edd2601b19b87c1ae6748fb054e72b4e7ef472a588c70fa6ff5ef49be81653ae74162e2
7
- data.tar.gz: c962fc165790548b427b439b47c554e0326ec0b1e14aaf0f7881057cddb12c03a5163ef2df4a095ad8b3910aad42de14d677bb83acb3be8c66b21106f6333a3f
6
+ metadata.gz: 69b64372dbe837e9320ad98a1064956b12581f154c1d14e1e77d1f4ba4e2de0530fa5b8ba13c31320fd4f8cbbcaf7db81c62b44f5612ef576355e7c997d685ae
7
+ data.tar.gz: 0b2fbf6d6c83e491ec54a30e114adddae1a211b063ca66d4aca07388df80da8b8fd2d455cb884523d3bedb31740de4f0a79986ccb5bfd496430087c81a427dd6
data/README.md CHANGED
@@ -37,7 +37,7 @@ $ cd /opt/pwn
37
37
  $ ./install.sh
38
38
  $ ./install.sh ruby-gem
39
39
  $ pwn
40
- pwn[v0.5.398]:001 >>> PWN.help
40
+ pwn[v0.5.399]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](https://youtu.be/G7iLUY4FzsI)
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.4@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.5.398]:001 >>> PWN.help
55
+ pwn[v0.5.399]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
  If you're using a multi-user install of RVM do:
@@ -62,7 +62,7 @@ $ rvm use ruby-3.4.4@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.5.398]:001 >>> PWN.help
65
+ pwn[v0.5.399]:001 >>> PWN.help
66
66
  ```
67
67
 
68
68
  PWN periodically upgrades to the latest version of Ruby which is reflected in `/opt/pwn/.ruby-version`. The easiest way to upgrade to the latest version of Ruby from a previous PWN installation is to run the following script:
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'fileutils'
5
4
  require 'pwn'
6
5
  require 'optparse'
7
6
  require 'uri'
@@ -16,14 +15,22 @@ OptionParser.new do |options|
16
15
  opts[:target_url] = t
17
16
  end
18
17
 
19
- options.on('-oPATH', '--report_output_path=PATH', '<Required - Output Path for Active Scan Issues>') do |o|
20
- opts[:output_path] = o
18
+ options.on('-oDIR', '--report_output_dir=DIR', '<Required - Output Directory for Active Scan Report>') do |o|
19
+ opts[:output_dir] = o
21
20
  end
22
21
 
23
22
  options.on('-dSWAGGER', '--swagger_definitions=SWAGGER', '<Required - Comma-delimited list of Swagger JSON/YAML files to import>') do |s|
24
23
  opts[:swagger_definitions] = s
25
24
  end
26
25
 
26
+ options.on('-bBPATH', '--burp_path=BPATH', '<Optional - Path to Burp Suite Pro Jar File (Defaults to /opt/burpsuite/burpsuite-pro.jar)>') do |b|
27
+ opts[:burp_jar_path] = b
28
+ end
29
+
30
+ options.on('-h', '--[no-]headless', '<Optional - Run Burp and Browser Headless>') do |h|
31
+ opts[:headless] = h
32
+ end
33
+
27
34
  options.on('-D', '--[no-]debug', '<Optional - Enable Debug Output and Do Not Delete Temporary OpenAPI Spec>') do |d|
28
35
  opts[:debug] = d
29
36
  end
@@ -48,14 +55,6 @@ OptionParser.new do |options|
48
55
  opts[:exclude_paths] = e
49
56
  end
50
57
 
51
- options.on('-bBPATH', '--burp_path=BPATH', '<Optional - Path to Burp Suite Pro Jar File (Defaults to /opt/burpsuite/burpsuite-pro.jar)>') do |b|
52
- opts[:burp_jar_path] = b
53
- end
54
-
55
- options.on('-h', '--[no-]headless', '<Optional - Run Burp and Browser Headless>') do |h|
56
- opts[:headless] = h
57
- end
58
-
59
58
  options.on('-iURL', '--in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
60
59
  opts[:in_scope] = s
61
60
  end
@@ -70,17 +69,17 @@ begin
70
69
  timestamp = Time.now.strftime('%Y-%m-%d_%H-%M-%S%Z')
71
70
  logger = PWN::Plugins::PWNLogger.create
72
71
 
73
- burp_jar_path = opts[:burp_jar_path]
74
- headless = opts[:headless] || false
75
72
  target_url = opts[:target_url]
76
73
  raise 'ERROR: --target_url is required.' if target_url.nil?
77
74
 
78
- output_path = opts[:output_path]
79
- raise 'ERROR: --report_output_path is required.' if output_path.nil?
75
+ output_dir = opts[:output_dir]
76
+ raise 'ERROR: --report_output_dir is required.' if output_dir.nil?
80
77
 
81
78
  swagger_definitions = opts[:swagger_definitions]
82
79
  raise 'ERROR: --swagger_definitions is required.' if swagger_definitions.nil?
83
80
 
81
+ burp_jar_path = opts[:burp_jar_path]
82
+ headless = opts[:headless] || false
84
83
  debug = opts[:debug] || false
85
84
 
86
85
  swagger_defs_arr = swagger_definitions.split(',').map(&:strip)
@@ -146,7 +145,7 @@ begin
146
145
 
147
146
  raise "ERROR: Failed to import OpenAPI/Swagger spec #{openapi_spec} into Burp Suite Pro's Sitemap." if json_sitemap.nil? || json_sitemap.empty?
148
147
 
149
- PWN::Plugins::BurpSuite.invoke_active_scan(
148
+ PWN::Plugins::BurpSuite.active_scan(
150
149
  burp_obj: burp_obj,
151
150
  target_url: in_scope,
152
151
  exclude_paths: exlude_paths
@@ -159,17 +158,11 @@ begin
159
158
  # Once DefectDojo begins to support XML report results
160
159
  report_types = %i[html xml]
161
160
  report_types.each do |report_type|
162
- this_output_path = "#{output_path}.html"
163
- # this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.html"
164
-
165
- this_output_path = "#{output_path}.xml" if report_type == :xml
166
- # this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.xml" if report_type == :xml
167
-
168
161
  PWN::Plugins::BurpSuite.generate_scan_report(
169
162
  burp_obj: burp_obj,
170
163
  target_url: in_scope,
171
164
  report_type: report_type,
172
- output_path: this_output_path
165
+ output_dir: output_dir
173
166
  )
174
167
  end
175
168
 
@@ -177,6 +170,5 @@ begin
177
170
  rescue StandardError => e
178
171
  raise e
179
172
  ensure
180
- FileUtils.rm_f(openapi_spec) unless debug
181
173
  burp_obj = PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj) unless burp_obj.nil?
182
174
  end
@@ -14,8 +14,8 @@ OptionParser.new do |options|
14
14
  opts[:target_url] = t
15
15
  end
16
16
 
17
- options.on('-oPATH', '--report_output_path=PATH', '<Required - Output Path for Active Scan Issues>') do |o|
18
- opts[:output_path] = o
17
+ options.on('-oDIR', '--report_output_dir=DIR', '<Required - Output Directory for Active Scan Report>') do |o|
18
+ opts[:output_dir] = o
19
19
  end
20
20
 
21
21
  options.on('-eLIST', '--exclude_paths=LIST', '<Optional - Comma-delimited list of paths to exlude from scanning (e.g. "/api/login, /api/logout, /api/etc")>') do |e|
@@ -30,6 +30,10 @@ OptionParser.new do |options|
30
30
  opts[:headless] = h
31
31
  end
32
32
 
33
+ options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to chrome)>') do |b|
34
+ opts[:browser_type] = b
35
+ end
36
+
33
37
  options.on('-s', '--[no-]spider', '<Optional - Crawl / Spider Target Prior to Scanning (Defaults to false)>') do |s|
34
38
  opts[:spider] = s
35
39
  end
@@ -51,20 +55,19 @@ end
51
55
  begin
52
56
  logger = PWN::Plugins::PWNLogger.create
53
57
 
54
- burp_jar_path = opts[:burp_jar_path]
55
- headless = opts[:headless] || false
56
- spider = opts[:spider] || false
57
58
  target_url = opts[:target_url]
58
59
  raise 'ERROR: --target_url is required.' if target_url.nil?
59
60
 
60
- output_path = opts[:output_path]
61
- raise 'ERROR: --report_output_path is required.' if output_path.nil?
61
+ output_dir = opts[:output_dir]
62
+ raise 'ERROR: --report_output_dir is required.' if output_dir.nil?
62
63
 
63
64
  exlude_paths = opts[:exclude_paths]
64
65
  exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
65
-
66
+ burp_jar_path = opts[:burp_jar_path]
67
+ headless = opts[:headless] || false
68
+ browser_type = opts[:browser_type] ||= :chrome
69
+ spider = opts[:spider] || false
66
70
  navigation_instruct = opts[:navigation_instruct]
67
-
68
71
  in_scope = opts[:in_scope] ||= target_url
69
72
 
70
73
  # ------
@@ -77,7 +80,7 @@ begin
77
80
  else
78
81
  burp_obj = PWN::Plugins::BurpSuite.start(
79
82
  burp_jar_path: burp_jar_path,
80
- browser_type: :chrome
83
+ browser_type: browser_type
81
84
  )
82
85
  end
83
86
 
@@ -101,7 +104,7 @@ begin
101
104
  browser = browser_obj[:browser]
102
105
  browser.goto(target_url)
103
106
 
104
- unless navigation_instruct.nil?
107
+ if navigation_instruct
105
108
  File.read(navigation_instruct).each_line do |instruction|
106
109
  # Look for any set method in this instruction and replace its value w/ asterisks
107
110
  redact_regex = /\.set\(['"]([^'"]*)['"]\)/
@@ -112,13 +115,7 @@ begin
112
115
  end
113
116
 
114
117
  PWN::Plugins::BurpSuite.spider(burp_obj: burp_obj, target_url: in_scope) if spider
115
-
116
- duration = 9
117
- print "Waiting #{duration} seconds prior to kicking off active scan..."
118
- sleep duration # Sleep for now so everything loads the way we expect - blech.
119
- print "\n"
120
-
121
- PWN::Plugins::BurpSuite.invoke_active_scan(
118
+ PWN::Plugins::BurpSuite.active_scan(
122
119
  burp_obj: burp_obj,
123
120
  target_url: in_scope,
124
121
  exclude_paths: exlude_paths
@@ -131,17 +128,11 @@ begin
131
128
  # Once DefectDojo begins to support XML report results
132
129
  report_types = %i[html xml]
133
130
  report_types.each do |report_type|
134
- this_output_path = "#{output_path}.html"
135
- # this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.html"
136
-
137
- this_output_path = "#{output_path}.xml" if report_type == :xml
138
- # this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.xml" if report_type == :xml
139
-
140
131
  PWN::Plugins::BurpSuite.generate_scan_report(
141
132
  burp_obj: burp_obj,
142
133
  target_url: in_scope,
143
134
  report_type: report_type,
144
- output_path: this_output_path
135
+ output_dir: output_dir
145
136
  )
146
137
  end
147
138
 
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+ require 'pwn'
6
+ require 'optparse'
7
+ require 'uri'
8
+
9
+ opts = {}
10
+ OptionParser.new do |options|
11
+ options.banner = "USAGE:
12
+ #{File.basename($PROGRAM_NAME)} [opts]
13
+ "
14
+
15
+ options.on('-aAPIKEY', '--api_key=APIKEY', '<Required - OWASP Zap API Key (Tools>Options>API)>') do |a|
16
+ opts[:api_key] = a
17
+ end
18
+
19
+ options.on('-tTARGET', '--target_url=TARGET', '<Required - Target URI to Scan>') do |t|
20
+ opts[:target_url] = t
21
+ end
22
+
23
+ options.on('-oPATH', '--report_output_path=PATH', '<Required - Output Path for Active Scan Issues>') do |o|
24
+ opts[:output_path] = o
25
+ end
26
+
27
+ options.on('-dSWAGGER', '--swagger_definitions=SWAGGER', '<Required - Comma-delimited list of Swagger JSON/YAML files to import>') do |s|
28
+ opts[:swagger_definitions] = s
29
+ end
30
+
31
+ options.on('-zZPATH', '--zap_bin_path=ZPATH', '<Optional - Path to zap.sh>') do |z|
32
+ opts[:zap_bin_path] = z
33
+ end
34
+
35
+ options.on('-h', '--[no-]headless', '<Optional - Run ZAP and Browser Headless>') do |h|
36
+ opts[:headless] = h
37
+ end
38
+
39
+ options.on('-D', '--[no-]debug', '<Optional - Enable Debug Output and Do Not Delete Temporary OpenAPI Spec>') do |d|
40
+ opts[:debug] = d
41
+ end
42
+
43
+ options.on('-vVERSION', '--openapi_spec_version=VERSION', '<Optional - OpenAPI/Swagger Specification Version (Defaults to 3.0.3)>') do |o|
44
+ opts[:openapi_spec_version] = o
45
+ end
46
+
47
+ options.on('-HJSON', '--additional_http_headers=JSON', '<Optional - JSON string of additional HTTP headers to include in requests (e.g. \'{"Header1":"Value1","Header2":"Value2"}\')>') do |h|
48
+ opts[:additional_http_headers] = h
49
+ end
50
+
51
+ options.on('-eLIST', '--exclude_paths=LIST', '<Optional - Comma-delimited list of paths to exlude from scanning (e.g. "/api/login, /api/logout, /api/etc")>') do |e|
52
+ opts[:exclude_paths] = e
53
+ end
54
+
55
+ options.on('-iURL', '--in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
56
+ opts[:in_scope] = s
57
+ end
58
+ end.parse!
59
+
60
+ if opts.empty?
61
+ puts `#{File.basename($PROGRAM_NAME)} --help`
62
+ exit 1
63
+ end
64
+
65
+ begin
66
+ timestamp = Time.now.strftime('%Y-%m-%d_%H-%M-%S%Z')
67
+ logger = PWN::Plugins::PWNLogger.create
68
+
69
+ api_key = opts[:api_key]
70
+ raise 'ERROR: --api_key is required.' if api_key.nil?
71
+
72
+ target_url = opts[:target_url]
73
+ raise 'ERROR: --target_url is required.' if target_url.nil?
74
+
75
+ output_path = opts[:output_path]
76
+ raise 'ERROR: --report_output_path is required.' if output_path.nil?
77
+
78
+ swagger_definitions = opts[:swagger_definitions]
79
+ raise 'ERROR: --swagger_definitions is required.' if swagger_definitions.nil?
80
+
81
+ zap_bin_path = opts[:zap_bin_path]
82
+ headless = opts[:headless] || false
83
+ debug = opts[:debug] || false
84
+
85
+ swagger_defs_arr = swagger_definitions.split(',').map(&:strip)
86
+ scheme = URI.parse(target_url).scheme
87
+ target_host = URI.parse(target_url).host
88
+ base_url = "#{scheme}://#{target_host}"
89
+
90
+ openapi_spec_version = opts[:openapi_spec_version]
91
+ openapi_spec_root = File.dirname(swagger_defs_arr.first)
92
+ openapi_spec = "#{openapi_spec_root}/openapi_spec-#{target_host}-#{timestamp}.json"
93
+
94
+ PWN::Plugins::OpenAPI.generate_spec(
95
+ spec_paths: swagger_defs_arr,
96
+ base_url: base_url,
97
+ output_json_path: openapi_spec,
98
+ target_version: openapi_spec_version,
99
+ debug: debug
100
+ )
101
+
102
+ additional_http_headers = opts[:additional_http_headers]
103
+ additional_http_headers = JSON.parse(additional_http_headers, symbolize_names: true) if additional_http_headers.is_a?(String)
104
+
105
+ exlude_paths = opts[:exclude_paths]
106
+ exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
107
+
108
+ in_scope = opts[:in_scope] ||= target_url
109
+
110
+ # ------
111
+ # Open ZAP
112
+ if headless
113
+ zap_obj = PWN::Plugins::Zaproxy.start(
114
+ zap_bin_path: zap_bin_path,
115
+ headless: headless
116
+ )
117
+ else
118
+ zap_obj = PWN::Plugins::Zaproxy.start(
119
+ zap_bin_path: zap_bin_path,
120
+ browser_type: :chrome
121
+ )
122
+ end
123
+
124
+ logger.info(zap_obj)
125
+
126
+ json_sitemap = PWN::Plugins::Zaproxy.import_openapi_to_sitemap(
127
+ zap_obj: zap_obj,
128
+ openapi_spec: openapi_spec
129
+ )
130
+
131
+ raise "ERROR: Failed to import OpenAPI/Swagger spec #{openapi_spec} into ZAP's Sitemap." if json_sitemap.nil? || json_sitemap.empty?
132
+
133
+ PWN::Plugins::Zaproxy.active_scan(
134
+ zap_obj: zap_obj,
135
+ target_url: target_url,
136
+ exclude_paths: exlude_paths
137
+ )
138
+
139
+ # Dump a list of scan issues from Active Scan result
140
+ # scan_issues = PWN::Plugins::Zaproxy.get_scan_issues(zap_obj: zap_obj)
141
+ # puts scan_issues
142
+
143
+ # Once DefectDojo begins to support XML report results
144
+ report_types = %i[html xml]
145
+ report_types.each do |report_type|
146
+ this_output_path = "#{output_path}.html"
147
+ # this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.html"
148
+
149
+ this_output_path = "#{output_path}.xml" if report_type == :xml
150
+ # this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.xml" if report_type == :xml
151
+
152
+ PWN::Plugins::Zaproxy.generate_scan_report(
153
+ zap_obj: zap_obj,
154
+ target_url: in_scope,
155
+ report_type: report_type,
156
+ output_path: this_output_path
157
+ )
158
+ end
159
+
160
+ zap_obj = PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj)
161
+ rescue StandardError => e
162
+ raise e
163
+ ensure
164
+ FileUtils.rm_f(openapi_spec) unless debug
165
+ zap_obj = PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj) unless zap_obj.nil?
166
+ end
@@ -22,12 +22,8 @@ OptionParser.new do |options|
22
22
  opts[:output_dir] = o
23
23
  end
24
24
 
25
- options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to chrome)>') do |b|
26
- opts[:browser_type] = b
27
- end
28
-
29
- options.on('-IINST', '--navigation_instruct=INST', '<Optional - Path to Navigation Instructions (e.g. Auth w/ Target - see /pwn/etc/owasp_zap/navigation.instruct.EXAMPLE)>') do |i|
30
- opts[:navigation_instruct] = i
25
+ options.on('-eLIST', '--exclude_paths=LIST', '<Optional - Comma-delimited list of paths to exlude from scanning (e.g. "/api/login, /api/logout, /api/etc")>') do |e|
26
+ opts[:exclude_paths] = e
31
27
  end
32
28
 
33
29
  options.on('-zZPATH', '--zap_bin_path=ZPATH', '<Optional - Path to zap.sh>') do |z|
@@ -38,8 +34,20 @@ OptionParser.new do |options|
38
34
  opts[:headless] = h
39
35
  end
40
36
 
41
- options.on('-pPROXY', '--proxy=PROXY', '<Optional - Change Local Zap Proxy Listener (Default http://127.0.0.1:<Random 1024-65535>)>') do |p|
42
- opts[:proxy] = p
37
+ options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to chrome)>') do |b|
38
+ opts[:browser_type] = b
39
+ end
40
+
41
+ options.on('-s', '--[no-]spider', '<Optional - Crawl / Spider Target Prior to Scanning (Defaults to false)>') do |s|
42
+ opts[:spider] = s
43
+ end
44
+
45
+ options.on('-IINST', '--navigation_instruct=INST', '<Optional - Path to Navigation Instructions (e.g. Auth w/ Target - see /pwn/etc/owasp_zap/navigation.instruct.EXAMPLE)>') do |i|
46
+ opts[:navigation_instruct] = i
47
+ end
48
+
49
+ options.on('-iURL', '--in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
50
+ opts[:in_scope] = s
43
51
  end
44
52
  end.parse!
45
53
 
@@ -59,64 +67,64 @@ begin
59
67
  browser_type = opts[:browser_type].to_s.strip.chomp.scrub.to_sym
60
68
  end
61
69
 
62
- target_url = opts[:target_url].to_s.strip.chomp.scrub
63
- output_dir = opts[:output_dir].to_s.strip.chomp.scrub
64
- navigation_instruct = opts[:navigation_instruct].to_s.strip.chomp.scrub if File.exist?(opts[:navigation_instruct].to_s.strip.chomp.scrub)
70
+ target_url = opts[:target_url]
71
+ raise 'ERROR: --target_url is required.' if target_url.nil?
72
+
73
+ output_dir = opts[:output_dir]
74
+ raise 'ERROR: --report_output_dir is required.' if output_dir.nil?
75
+
76
+ exlude_paths = opts[:exclude_paths]
77
+ exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
65
78
  zap_bin_path = opts[:zap_bin_path].to_s.strip.chomp.scrub if File.exist?(opts[:zap_bin_path].to_s.strip.chomp.scrub)
66
- headless = opts[:headless]
67
- proxy = opts[:proxy]
79
+ headless = opts[:headless] || false
80
+ browser_type = opts[:browser_type] ||= :chrome
81
+ spider = opts[:spider] || false
82
+ navigation_instruct = opts[:navigation_instruct]
83
+ in_scope = opts[:in_scope] ||= target_url
68
84
 
69
85
  # ------
70
86
  # Dynamically build arguments hash based on flags passed and Open Zap
71
- start_args = {}
72
- start_args[:api_key] = api_key
73
- start_args[:zap_bin_path] = zap_bin_path if zap_bin_path != ''
74
- start_args[:headless] = true if headless
75
- start_args[:proxy] = proxy
76
- zap_obj = PWN::Plugins::OwaspZap.start(start_args)
87
+ if headless
88
+ zap_obj = PWN::Plugins::Zaproxy.start(
89
+ zap_bin_path: zap_bin_path,
90
+ api_key: api_key,
91
+ headless: headless,
92
+ browser_type: :headless
93
+ )
94
+ else
95
+ zap_obj = PWN::Plugins::Zaproxy.start(
96
+ zap_bin_path: zap_bin_path,
97
+ api_key: api_key,
98
+ browser_type: browser_type
99
+ )
100
+ end
77
101
 
78
102
  logger.info(zap_obj)
79
103
 
80
- browser_obj = PWN::Plugins::TransparentBrowser.open(
81
- browser_type: browser_type,
82
- proxy: proxy
83
- )
104
+ browser_obj = zap_obj[:zap_browser]
84
105
  browser = browser_obj[:browser]
85
-
86
- if browser_type == :rest
87
- browser.get(target_url)
88
- else
89
- browser.goto(target_url)
90
- end
106
+ browser.goto(target_url)
91
107
 
92
108
  if navigation_instruct
93
109
  File.read(navigation_instruct).each_line do |instruction|
110
+ # Look for any set method in this instruction and replace its value w/ asterisks
111
+ redact_regex = /\.set\(['"]([^'"]*)['"]\)/
112
+ redacted_instruction = instruction.gsub(redact_regex, ".set('********')")
113
+ print "\nExecuting Instruction: #{redacted_instruction}"
94
114
  browser.instance_eval(instruction.to_s.scrub.strip.chomp)
95
115
  end
96
116
  end
97
117
 
98
- PWN::Plugins::OwaspZap.spider(
118
+ PWN::Plugins::Zaproxy.spider(zap_obj: zap_obj, target_url: target_url) if spider
119
+ PWN::Plugins::Zaproxy.active_scan(
99
120
  zap_obj: zap_obj,
100
- target: target_url
101
- )
102
-
103
- PWN::Plugins::OwaspZap.active_scan(
104
- zap_obj: zap_obj,
105
- target: target_url
121
+ target_url: target_url
106
122
  )
107
123
 
108
124
  # Generate all Report Types
109
- (1..3).each do |report_iteration|
110
- case report_iteration
111
- when 1
112
- report_type = 'html'
113
- when 2
114
- report_type = 'markdown'
115
- when 3
116
- report_type = 'xml'
117
- end
118
-
119
- report_path = PWN::Plugins::OwaspZap.generate_report(
125
+ report_types = %i[html markdown xml]
126
+ report_types.each do |report_type|
127
+ report_path = PWN::Plugins::Zaproxy.generate_scan_report(
120
128
  zap_obj: zap_obj,
121
129
  output_dir: output_dir,
122
130
  report_type: report_type
@@ -125,10 +133,10 @@ begin
125
133
  logger.info("Report can be found here: #{report_path}")
126
134
  end
127
135
 
128
- PWN::Plugins::OwaspZap.stop(zap_obj: zap_obj)
136
+ PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj)
129
137
  rescue StandardError => e
130
138
  raise e
131
139
  ensure
132
- PWN::Plugins::OwaspZap.stop(zap_obj: zap_obj) unless zap_obj.nil?
140
+ PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj) unless zap_obj.nil?
133
141
  browser_obj = PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj) unless browser_obj.nil?
134
142
  end
@@ -879,13 +879,13 @@ module PWN
879
879
  end
880
880
 
881
881
  # Supported Method Parameters::
882
- # active_scan_url_arr = PWN::Plugins::BurpSuite.invoke_active_scan(
882
+ # active_scan_url_arr = PWN::Plugins::BurpSuite.active_scan(
883
883
  # burp_obj: 'required - burp_obj returned by #start method',
884
884
  # target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:burp_browser])',
885
885
  # exclude_paths: 'optional - array of paths to exclude from active scan (default: [])'
886
886
  # )
887
887
 
888
- public_class_method def self.invoke_active_scan(opts = {})
888
+ public_class_method def self.active_scan(opts = {})
889
889
  burp_obj = opts[:burp_obj]
890
890
  rest_browser = burp_obj[:rest_browser]
891
891
  pwn_burp_api = burp_obj[:pwn_burp_api]
@@ -1016,9 +1016,9 @@ module PWN
1016
1016
  # Supported Method Parameters::
1017
1017
  # PWN::Plugins::BurpSuite.generate_scan_report(
1018
1018
  # burp_obj: 'required - burp_obj returned by #start method',
1019
- # target_url: 'required - target_url passed to #invoke_active_scan method',
1020
- # report_type: :html|:xml|:both,
1021
- # output_path: 'required - path to save report results'
1019
+ # target_url: 'required - target_url passed to #active_scan method',
1020
+ # output_dir: 'required - directory to save the report',
1021
+ # report_type: required - <:html|:xml>'
1022
1022
  # )
1023
1023
 
1024
1024
  public_class_method def self.generate_scan_report(opts = {})
@@ -1026,16 +1026,20 @@ module PWN
1026
1026
  target_url = opts[:target_url]
1027
1027
  rest_browser = burp_obj[:rest_browser]
1028
1028
  pwn_burp_api = burp_obj[:pwn_burp_api]
1029
+ output_dir = opts[:output_dir]
1030
+ raise "ERROR: #{output_dir} does not exist." unless Dir.exist?(output_dir)
1031
+
1029
1032
  report_type = opts[:report_type]
1030
- # When pwn_burp begins to support XML report generation
1031
- valid_report_types_arr = %i[
1032
- html
1033
- xml
1034
- ]
1035
1033
 
1036
- raise 'INVALID Report Type' unless valid_report_types_arr.include?(report_type)
1034
+ valid_report_types_arr = %i[html xml]
1035
+ raise "ERROR: INVALID Report Type => #{report_type}" unless valid_report_types_arr.include?(report_type)
1037
1036
 
1038
- output_path = opts[:output_path].to_s.scrub
1037
+ case report_type
1038
+ when :html
1039
+ report_path = "#{output_dir}/burp_active_scan_results.html"
1040
+ when :xml
1041
+ report_path = "#{output_dir}/burp_active_scan_results.xml"
1042
+ end
1039
1043
 
1040
1044
  scheme = URI.parse(target_url).scheme
1041
1045
  host = URI.parse(target_url).host
@@ -1058,7 +1062,7 @@ module PWN
1058
1062
  "http://#{pwn_burp_api}/scanreport/#{report_type.to_s.upcase}/#{report_url}"
1059
1063
  )
1060
1064
 
1061
- File.open(output_path, 'w') do |f|
1065
+ File.open(report_path, 'w') do |f|
1062
1066
  f.puts(report_resp.body.gsub("\r\n", "\n"))
1063
1067
  end
1064
1068
  rescue RestClient::BadRequest => e
@@ -1198,7 +1202,7 @@ module PWN
1198
1202
  comment: 'optional - comment for the sitemap entry (default: \"\")',
1199
1203
  )
1200
1204
 
1201
- active_scan_url_arr = #{self}.invoke_active_scan(
1205
+ active_scan_url_arr = #{self}.active_scan(
1202
1206
  burp_obj: 'required - burp_obj returned by #start method',
1203
1207
  target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:burp_browser])',
1204
1208
  exclude_paths: 'optional - array of paths to exclude from active scan (default: [])'
@@ -1210,9 +1214,9 @@ module PWN
1210
1214
 
1211
1215
  #{self}.generate_scan_report(
1212
1216
  burp_obj: 'required - burp_obj returned by #start method',
1213
- target_url: 'required - target_url passed to #invoke_active_scan method',
1214
- report_type: :html|:xml,
1215
- output_path: 'required - path to save report results'
1217
+ target_url: 'required - target_url passed to #active_scan method',
1218
+ output_dir: 'required - directory to save the report',
1219
+ report_type: 'required - <:html|:xml>'
1216
1220
  )
1217
1221
 
1218
1222
  #{self}.stop(
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'cgi'
3
4
  require 'pty'
4
5
  require 'securerandom'
5
6
  require 'json'
@@ -9,7 +10,7 @@ module PWN
9
10
  module Plugins
10
11
  # This plugin converts images to readable text
11
12
  # TODO: Convert all rest requests to POST instead of GET
12
- module OwaspZap
13
+ module Zaproxy
13
14
  @@logger = PWN::Plugins::PWNLogger.create
14
15
 
15
16
  # Supported Method Parameters::
@@ -30,12 +31,10 @@ module PWN
30
31
  end
31
32
  params = opts[:params]
32
33
  http_body = opts[:http_body].to_s.scrub
33
- host = zap_obj[:host]
34
- port = zap_obj[:port]
35
- base_zap_api_uri = "http://#{host}:#{port}"
34
+ zap_rest_api = zap_obj[:zap_rest_api]
35
+ base_zap_api_uri = "http://#{zap_rest_api}"
36
36
 
37
- browser_obj = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
38
- rest_client = browser_obj[:browser]::Request
37
+ rest_client = zap_obj[:rest_browser]::Request
39
38
 
40
39
  case http_method
41
40
  when :get
@@ -72,10 +71,11 @@ module PWN
72
71
  end
73
72
 
74
73
  # Supported Method Parameters::
75
- # zap_obj = PWN::Plugins::OwaspZap.start(
74
+ # zap_obj = PWN::Plugins::Zaproxy.start(
76
75
  # api_key: 'required - api key for API authorization',
77
76
  # zap_bin_path: 'optional - path to zap.sh file'
78
77
  # headless: 'optional - run zap headless if set to true',
78
+ # browser_type: 'optional - defaults to :firefox. See PWN::Plugins::TransparentBrowser.help for a list of types',
79
79
  # proxy: 'optional - change local zap proxy listener (defaults to http://127.0.0.1:<Random 1024-65535>)',
80
80
  # )
81
81
 
@@ -84,14 +84,9 @@ module PWN
84
84
  api_key = opts[:api_key].to_s.scrub.strip.chomp
85
85
  zap_obj[:api_key] = api_key
86
86
 
87
- headless = if opts[:headless]
88
- true
89
- else
90
- false
91
- end
92
-
93
87
  if opts[:zap_bin_path]
94
- zap_bin_path = opts[:zap_bin_path].to_s.scrub.strip.chomp if File.exist?(opts[:zap_bin_path].to_s.scrub.strip.chomp)
88
+ zap_bin_path = opts[:zap_bin_path]
89
+ raise "ERROR: zap.sh not found at #{zap_bin_path}" unless File.exist?(zap_bin_path)
95
90
  else
96
91
  underlying_os = PWN::Plugins::DetectOS.type
97
92
 
@@ -108,21 +103,36 @@ module PWN
108
103
  zap_bin = File.basename(zap_bin_path)
109
104
  zap_dir = File.dirname(zap_bin_path)
110
105
 
106
+ headless = opts[:headless] || false
107
+ browser_type = opts[:browser_type] ||= :firefox
108
+ zap_ip = opts[:zap_ip] ||= '127.0.0.1'
109
+ zap_port = opts[:zap_port] ||= PWN::Plugins::Sock.get_random_unused_port
110
+
111
+ zap_rest_ip = opts[:pwn_zap_ip] ||= '127.0.0.1'
112
+ zap_rest_port = opts[:pwn_zap_port] ||= PWN::Plugins::Sock.get_random_unused_port
113
+
111
114
  if headless
112
- owasp_zap_cmd = "cd #{zap_dir} && ./#{zap_bin} -daemon"
115
+ zaproxy_cmd = "cd #{zap_dir} && ./#{zap_bin} -daemon"
113
116
  else
114
- owasp_zap_cmd = "cd #{zap_dir} && ./#{zap_bin}"
117
+ zaproxy_cmd = "cd #{zap_dir} && ./#{zap_bin}"
115
118
  end
116
119
 
117
- random_port = PWN::Plugins::Sock.get_random_unused_port
120
+ browser_obj1 = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
121
+ rest_browser = browser_obj1[:browser]
118
122
 
119
- proxy = "http://127.0.0.1:#{random_port}"
120
- proxy = opts[:proxy].to_s.scrub.strip.chomp if opts[:proxy]
123
+ zap_obj[:mitm_proxy] = "#{zap_ip}:#{zap_port}"
124
+ zap_obj[:zap_rest_api] = zap_obj[:mitm_proxy]
125
+ zap_obj[:rest_browser] = rest_browser
121
126
 
122
- proxy_uri = URI.parse(proxy)
123
- owasp_zap_cmd = "#{owasp_zap_cmd} -host #{proxy_uri.host} -port #{proxy_uri.port}"
124
- zap_obj[:host] = proxy_uri.host.to_s.scrub
125
- zap_obj[:port] = proxy_uri.port.to_i
127
+ zaproxy_cmd = "#{zaproxy_cmd} -host #{zap_ip} -port #{zap_port}"
128
+
129
+ browser_obj2 = PWN::Plugins::TransparentBrowser.open(
130
+ browser_type: browser_type,
131
+ proxy: "http://#{zap_obj[:mitm_proxy]}",
132
+ devtools: true
133
+ )
134
+
135
+ zap_obj[:zap_browser] = browser_obj2
126
136
 
127
137
  pwn_stdout_log_path = "/tmp/pwn_plugins_owasp-#{SecureRandom.hex}.log"
128
138
  pwn_stdout_log = File.new(pwn_stdout_log_path, 'w')
@@ -131,7 +141,7 @@ module PWN
131
141
  pwn_stdout_log.fsync
132
142
 
133
143
  fork_pid = Process.fork do
134
- PTY.spawn(owasp_zap_cmd) do |stdout, _stdin, _pid|
144
+ PTY.spawn(zaproxy_cmd) do |stdout, _stdin, _pid|
135
145
  stdout.each do |line|
136
146
  puts line
137
147
  pwn_stdout_log.puts line
@@ -176,25 +186,57 @@ module PWN
176
186
  end
177
187
 
178
188
  # Supported Method Parameters::
179
- # PWN::Plugins::OwaspZap.spider(
189
+ # PWN::Plugins::Zaproxy.import_openapi_to_sitemap(
190
+ # zap_obj: 'required - zap_obj returned from #open method',
191
+ # openapi_spec: 'required - path to OpenAPI JSON or YAML spec file'
192
+ # )
193
+
194
+ public_class_method def self.import_openapi_to_sitemap(opts = {})
195
+ zap_obj = opts[:zap_obj]
196
+ api_key = zap_obj[:api_key].to_s.scrub
197
+ openapi_spec = opts[:openapi_spec]
198
+ raise "ERROR: openapi_spec file #{openapi_spec} does not exist" unless File.exist?(openapi_spec)
199
+
200
+ openapi_spec_root = File.dirname(openapi_spec)
201
+ Dir.chdir(openapi_spec_root)
202
+
203
+ params = {
204
+ apikey: api_key,
205
+ file: openapi_spec
206
+ }
207
+
208
+ response = zap_rest_call(
209
+ zap_obj: zap_obj,
210
+ rest_call: 'JSON/openapi/action/importFile/',
211
+ params: params
212
+ )
213
+
214
+ JSON.parse(response.body, symbolize_names: true)
215
+ rescue StandardError, SystemExit, Interrupt => e
216
+ stop(zap_obj) unless zap_obj.nil?
217
+ raise e
218
+ end
219
+
220
+ # Supported Method Parameters::
221
+ # PWN::Plugins::Zaproxy.spider(
180
222
  # zap_obj: 'required - zap_obj returned from #open method',
181
- # target: 'required - url to spider'
223
+ # target_url: 'required - url to spider'
182
224
  # )
183
225
 
184
226
  public_class_method def self.spider(opts = {})
185
227
  zap_obj = opts[:zap_obj]
186
- target = opts[:target].to_s.scrub
228
+ target_url = opts[:target_url].to_s.scrub
187
229
  api_key = zap_obj[:api_key].to_s.scrub
188
230
 
189
- # target_domain_name = URI.parse(target).host
231
+ # target_domain_name = URI.parse(target_url).host
190
232
 
191
233
  params = {
192
234
  apikey: api_key,
193
- url: target,
235
+ url: target_url,
194
236
  maxChildren: 9,
195
237
  recurse: 3,
196
238
  contextName: '',
197
- subtreeOnly: target
239
+ subtreeOnly: target_url
198
240
  }
199
241
 
200
242
  response = zap_rest_call(
@@ -229,26 +271,26 @@ module PWN
229
271
  end
230
272
 
231
273
  # Supported Method Parameters::
232
- # PWN::Plugins::OwaspZap.active_scan(
274
+ # PWN::Plugins::Zaproxy.active_scan(
233
275
  # zap_obj: 'required - zap_obj returned from #open method',
234
- # target: 'required - url to scan',
276
+ # target_url: 'required - url to scan',
235
277
  # scan_policy: 'optional - scan policy to use (defaults to Default Policy)'
236
278
  # )
237
279
 
238
280
  public_class_method def self.active_scan(opts = {})
239
281
  zap_obj = opts[:zap_obj]
240
282
  api_key = zap_obj[:api_key].to_s.scrub
241
- target = opts[:target]
283
+ target_url = opts[:target_url]
242
284
  if opts[:scan_policy].nil?
243
285
  scan_policy = 'Default Policy'
244
286
  else
245
287
  scan_policy = opts[:scan_policy].to_s.scrub.strip.chomp
246
288
  end
247
289
 
248
- # TODO: Implement adding target to scope so that inScopeOnly can be changed to true
290
+ # TODO: Implement adding target_url to scope so that inScopeOnly can be changed to true
249
291
  params = {
250
292
  apikey: api_key,
251
- url: target,
293
+ url: target_url,
252
294
  recurse: true,
253
295
  inScopeOnly: true,
254
296
  scanPolicyName: scan_policy
@@ -286,19 +328,19 @@ module PWN
286
328
  end
287
329
 
288
330
  # Supported Method Parameters::
289
- # PWN::Plugins::OwaspZap.alerts(
331
+ # PWN::Plugins::Zaproxy.alerts(
290
332
  # zap_obj: 'required - zap_obj returned from #open method',
291
- # target: 'required - base url to return alerts'
333
+ # target_url: 'required - base url to return alerts'
292
334
  # )
293
335
 
294
336
  public_class_method def self.alerts(opts = {})
295
337
  zap_obj = opts[:zap_obj]
296
338
  api_key = zap_obj[:api_key].to_s.scrub
297
- target = opts[:target]
339
+ target_url = opts[:target_url]
298
340
 
299
341
  params = {
300
342
  apikey: api_key,
301
- url: target
343
+ url: target_url
302
344
  }
303
345
 
304
346
  response = zap_rest_call(
@@ -314,36 +356,39 @@ module PWN
314
356
  end
315
357
 
316
358
  # Supported Method Parameters::
317
- # report_path = PWN::Plugins::OwaspZap.generate_report(
359
+ # report_path = PWN::Plugins::Zaproxy.generate_scan_report(
318
360
  # zap_obj: 'required - zap_obj returned from #open method',
319
361
  # output_dir: 'required - directory to save report',
320
- # report_type: 'required - <html|markdown|xml>'
362
+ # report_type: 'required - <:html|:markdown|:xml>'
321
363
  # )
322
364
 
323
- public_class_method def self.generate_report(opts = {})
365
+ public_class_method def self.generate_scan_report(opts = {})
324
366
  zap_obj = opts[:zap_obj]
325
367
  api_key = zap_obj[:api_key].to_s.scrub
326
- output_dir = opts[:output_dir] if Dir.exist?(opts[:output_dir])
327
- report_type = opts[:report_type].to_s.strip.chomp.scrub.to_sym
368
+ output_dir = opts[:output_dir]
369
+ raise "ERROR: output_dir #{output_dir} does not exist." unless Dir.exist?(output_dir)
328
370
 
329
- params = {
330
- apikey: api_key
331
- }
371
+ report_type = opts[:report_type]
372
+
373
+ valid_report_types_arr = %i[html markdown xml]
374
+ raise "ERROR: Invalid report_type => #{report_type}" unless valid_report_types_arr.include?(report_type)
332
375
 
333
376
  case report_type
334
377
  when :html
335
- report_path = "#{output_dir}/OWASP_Zap_Results.html"
378
+ report_path = "#{output_dir}/zaproxy_active_scan_results.html"
336
379
  rest_call = 'OTHER/core/other/htmlreport/'
337
380
  when :markdown
338
- report_path = "#{output_dir}/OWASP_Zap_Results.md"
381
+ report_path = "#{output_dir}/zaproxy_active_scan_results.md"
339
382
  rest_call = 'OTHER/core/other/mdreport/'
340
383
  when :xml
341
- report_path = "#{output_dir}/OWASP_Zap_Results.xml"
384
+ report_path = "#{output_dir}/zaproxy_active_scan_results.xml"
342
385
  rest_call = 'OTHER/core/other/xmlreport/'
343
- else
344
- raise @@logger.error("ERROR: Unsupported report type: #{report_type}\nValid report types are <html|markdown|xml>")
345
386
  end
346
387
 
388
+ params = {
389
+ apikey: api_key
390
+ }
391
+
347
392
  response = zap_rest_call(
348
393
  zap_obj: zap_obj,
349
394
  rest_call: rest_call,
@@ -361,7 +406,7 @@ module PWN
361
406
  end
362
407
 
363
408
  # Supported Method Parameters::
364
- # PWN::Plugins::OwaspZap.breakpoint(
409
+ # PWN::Plugins::Zaproxy.breakpoint(
365
410
  # zap_obj: 'required - zap_obj returned from #open method',
366
411
  # regex_type: 'required - :url, :request_header, :request_body, :response_header or :response_body',
367
412
  # regex_pattern: 'required - regex pattern to search for respective regex_type',
@@ -395,7 +440,7 @@ module PWN
395
440
  end
396
441
 
397
442
  # Supported Method Parameters::
398
- # PWN::Plugins::OwaspZap.tamper(
443
+ # PWN::Plugins::Zaproxy.tamper(
399
444
  # zap_obj: 'required - zap_obj returned from #open method',
400
445
  # domain: 'required - FQDN to tamper (e.g. test.domain.local)',
401
446
  # enabled: 'optional - boolean (defaults to true)'
@@ -427,42 +472,7 @@ module PWN
427
472
  end
428
473
 
429
474
  # Supported Method Parameters::
430
- # PWN::Plugins::OwaspZap.import_openapi_spec_file(
431
- # zap_obj: 'required - zap_obj returned from #open method',
432
- # spec: 'required - path to OpenAPI spec file (e.g. /path/to/openapi.yaml)',
433
- # target: 'required - target URL to ovverride the service URL in the OpenAPI spec (e.g. https://fq.dn)',
434
- # context_id: 'optional - ID of the ZAP context (Defaults to first context, if any)',
435
- # user_id: 'optional - ID of the ZAP user (Defaults to first user, if any)'
436
- # )
437
-
438
- public_class_method def self.import_openapi_spec_file(opts = {})
439
- zap_obj = opts[:zap_obj]
440
- api_key = zap_obj[:api_key].to_s.scrub
441
- spec = opts[:spec]
442
- target = opts[:target]
443
- context_id = opts[:context_id]
444
- user_id = opts[:user_id]
445
-
446
- params = {
447
- apikey: api_key,
448
- file: spec,
449
- target: target,
450
- contextId: context_id,
451
- user_id: user_id
452
- }
453
-
454
- zap_rest_call(
455
- zap_obj: zap_obj,
456
- rest_call: "JSON/break/action/openapi/?zapapiformat=JSON&apikey=#{api_key}",
457
- params: params
458
- )
459
- rescue StandardError, SystemExit, Interrupt => e
460
- stop(zap_obj) unless zap_obj.nil?
461
- raise e
462
- end
463
-
464
- # Supported Method Parameters::
465
- # watir_resp = PWN::Plugins::OwaspZap.request(
475
+ # watir_resp = PWN::Plugins::Zaproxy.request(
466
476
  # zap_obj: 'required - zap_obj returned from #open method',
467
477
  # browser_obj: 'required - browser_obj w/ browser_type: :firefox||:headless returned from #open method',
468
478
  # instruction: 'required - watir instruction to make (e.g. button(text: "Google Search").click)'
@@ -502,14 +512,28 @@ module PWN
502
512
  end
503
513
 
504
514
  # Supported Method Parameters::
505
- # PWN::Plugins::OwaspZap.stop(
506
- # :zap_obj => 'required - zap_obj returned from #start method'
515
+ # PWN::Plugins::Zaproxy.stop(
516
+ # zap_obj: 'required - zap_obj returned from #open method'
507
517
  # )
508
518
 
509
519
  public_class_method def self.stop(opts = {})
510
520
  zap_obj = opts[:zap_obj]
511
- Process.kill('TERM', zap_obj[:pid]) unless zap_obj.nil?
512
- rescue StandardError => e
521
+ api_key = zap_obj[:api_key]
522
+ browser_obj = zap_obj[:zap_browser]
523
+ rest_browser = zap_obj[:rest_browser]
524
+
525
+ browser_obj = PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj)
526
+
527
+ params = { apikey: api_key }
528
+ zap_rest_call(
529
+ zap_obj: zap_obj,
530
+ rest_call: 'JSON/core/action/shutdown/',
531
+ params: params
532
+ )
533
+
534
+ zap_obj = nil
535
+ rescue StandardError, SystemExit, Interrupt => e
536
+ stop(zap_obj) unless zap_obj.nil?
513
537
  raise e
514
538
  end
515
539
 
@@ -531,28 +555,32 @@ module PWN
531
555
  headless: 'optional - run zap headless if set to true',
532
556
  proxy: 'optional - change local zap proxy listener (defaults to http://127.0.0.1:<Random 1024-65535>)'
533
557
  )
534
- puts zap_obj.public_methods
535
558
 
536
559
  #{self}.spider(
537
560
  zap_obj: 'required - zap_obj returned from #open method',
538
- target: 'required - url to spider'
561
+ target_url: 'required - url to spider'
562
+ )
563
+
564
+ #{self}.import_openapi_to_sitemap(
565
+ zap_obj: 'required - zap_obj returned from #open method',
566
+ openapi_spec: 'required - path to OpenAPI JSON or YAML spec file'
539
567
  )
540
568
 
541
569
  #{self}.active_scan(
542
570
  zap_obj: 'required - zap_obj returned from #open method'
543
- target: 'required - url to scan',
571
+ target_url: 'required - url to scan',
544
572
  scan_policy: 'optional - scan policy to use (defaults to Default Policy)'
545
573
  )
546
574
 
547
575
  json_alerts = #{self}.alerts(
548
576
  zap_obj: 'required - zap_obj returned from #open method'
549
- target: 'required - base url to return alerts'
577
+ target_url: 'required - base url to return alerts'
550
578
  )
551
579
 
552
- report_path = #{self}.generate_report(
580
+ report_path = #{self}.generate_scan_report(
553
581
  zap_obj: 'required - zap_obj returned from #open method',
554
582
  output_dir: 'required - directory to save report',
555
- report_type: 'required - <html|markdown|xml>'
583
+ report_type: 'required - <:html|:markdown|:xml>'
556
584
  )
557
585
 
558
586
  #{self}.breakpoint(
data/lib/pwn/plugins.rb CHANGED
@@ -51,7 +51,6 @@ module PWN
51
51
  autoload :OpenAI, 'pwn/plugins/open_ai'
52
52
  autoload :OpenAPI, 'pwn/plugins/open_api'
53
53
  autoload :OpenVAS, 'pwn/plugins/openvas'
54
- autoload :OwaspZap, 'pwn/plugins/owasp_zap'
55
54
  autoload :Packet, 'pwn/plugins/packet'
56
55
  autoload :PDFParse, 'pwn/plugins/pdf_parse'
57
56
  autoload :Pony, 'pwn/plugins/pony'
@@ -77,6 +76,7 @@ module PWN
77
76
  autoload :Voice, 'pwn/plugins/voice'
78
77
  autoload :Vsphere, 'pwn/plugins/vsphere'
79
78
  autoload :XXD, 'pwn/plugins/xxd'
79
+ autoload :Zaproxy, 'pwn/plugins/zaproxy'
80
80
 
81
81
  # Display a List of Every PWN::Plugins Module
82
82
 
data/lib/pwn/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.5.398'
4
+ VERSION = '0.5.399'
5
5
  end
@@ -2,14 +2,14 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe PWN::Plugins::OwaspZap do
5
+ describe PWN::Plugins::Zaproxy do
6
6
  it 'should display information for authors' do
7
- authors_response = PWN::Plugins::OwaspZap
7
+ authors_response = PWN::Plugins::Zaproxy
8
8
  expect(authors_response).to respond_to :authors
9
9
  end
10
10
 
11
11
  it 'should display information for existing help method' do
12
- help_response = PWN::Plugins::OwaspZap
12
+ help_response = PWN::Plugins::Zaproxy
13
13
  expect(help_response).to respond_to :help
14
14
  end
15
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.398
4
+ version: 0.5.399
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
@@ -1308,7 +1308,6 @@ executables:
1308
1308
  - pwn_nexpose
1309
1309
  - pwn_nmap_discover_tcp_udp
1310
1310
  - pwn_openvas_vulnscan
1311
- - pwn_owasp_zap_active_scan
1312
1311
  - pwn_pastebin_sample_filter
1313
1312
  - pwn_phone
1314
1313
  - pwn_rdoc_to_jsonl
@@ -1324,6 +1323,8 @@ executables:
1324
1323
  - pwn_www_checkip
1325
1324
  - pwn_www_uri_buster
1326
1325
  - pwn_xss_dom_vectors
1326
+ - pwn_zaproxy_active_rest_api_scan
1327
+ - pwn_zaproxy_active_scan
1327
1328
  extensions: []
1328
1329
  extra_rdoc_files: []
1329
1330
  files:
@@ -1378,7 +1379,6 @@ files:
1378
1379
  - bin/pwn_nexpose
1379
1380
  - bin/pwn_nmap_discover_tcp_udp
1380
1381
  - bin/pwn_openvas_vulnscan
1381
- - bin/pwn_owasp_zap_active_scan
1382
1382
  - bin/pwn_pastebin_sample_filter
1383
1383
  - bin/pwn_phone
1384
1384
  - bin/pwn_rdoc_to_jsonl
@@ -1394,6 +1394,8 @@ files:
1394
1394
  - bin/pwn_www_checkip
1395
1395
  - bin/pwn_www_uri_buster
1396
1396
  - bin/pwn_xss_dom_vectors
1397
+ - bin/pwn_zaproxy_active_rest_api_scan
1398
+ - bin/pwn_zaproxy_active_scan
1397
1399
  - build_pwn_gem.sh
1398
1400
  - documentation/PWN.png
1399
1401
  - documentation/PWN_Contributors_and_Users.png
@@ -1873,7 +1875,6 @@ files:
1873
1875
  - lib/pwn/plugins/ocr.rb
1874
1876
  - lib/pwn/plugins/open_api.rb
1875
1877
  - lib/pwn/plugins/openvas.rb
1876
- - lib/pwn/plugins/owasp_zap.rb
1877
1878
  - lib/pwn/plugins/packet.rb
1878
1879
  - lib/pwn/plugins/pdf_parse.rb
1879
1880
  - lib/pwn/plugins/pony.rb
@@ -1900,6 +1901,7 @@ files:
1900
1901
  - lib/pwn/plugins/voice.rb
1901
1902
  - lib/pwn/plugins/vsphere.rb
1902
1903
  - lib/pwn/plugins/xxd.rb
1904
+ - lib/pwn/plugins/zaproxy.rb
1903
1905
  - lib/pwn/reports.rb
1904
1906
  - lib/pwn/reports/fuzz.rb
1905
1907
  - lib/pwn/reports/html_footer.rb
@@ -2217,7 +2219,6 @@ files:
2217
2219
  - spec/lib/pwn/plugins/ocr_spec.rb
2218
2220
  - spec/lib/pwn/plugins/open_api_spec.rb
2219
2221
  - spec/lib/pwn/plugins/openvas_spec.rb
2220
- - spec/lib/pwn/plugins/owasp_zap_spec.rb
2221
2222
  - spec/lib/pwn/plugins/packet_spec.rb
2222
2223
  - spec/lib/pwn/plugins/pdf_parse_spec.rb
2223
2224
  - spec/lib/pwn/plugins/pony_spec.rb
@@ -2244,6 +2245,7 @@ files:
2244
2245
  - spec/lib/pwn/plugins/voice_spec.rb
2245
2246
  - spec/lib/pwn/plugins/vsphere_spec.rb
2246
2247
  - spec/lib/pwn/plugins/xxd_spec.rb
2248
+ - spec/lib/pwn/plugins/zaproxy_spec.rb
2247
2249
  - spec/lib/pwn/plugins_spec.rb
2248
2250
  - spec/lib/pwn/reports/fuzz_spec.rb
2249
2251
  - spec/lib/pwn/reports/html_footer_spec.rb