pwn 0.5.388 → 0.5.391
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/.rubocop.yml +2 -2
- data/Gemfile +2 -2
- data/README.md +3 -3
- data/bin/pwn_burp_suite_pro_active_rest_api_scan +181 -0
- data/bin/pwn_burp_suite_pro_active_scan +5 -2
- data/lib/pwn/plugins/open_api.rb +1 -1
- data/lib/pwn/reports/html_header.rb +255 -0
- data/lib/pwn/reports/sast.rb +58 -179
- data/lib/pwn/reports.rb +1 -0
- data/lib/pwn/version.rb +1 -1
- data/pwn.gemspec +3 -0
- data/spec/lib/pwn/reports/html_header_spec.rb +15 -0
- data/third_party/pwn_rdoc.jsonl +4 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbd0402cd8475fd231d37a5face9831c7f6e12151e76422201968eebf6f39180
|
4
|
+
data.tar.gz: 50f372071410a7a0e741b3e938ef7f8e498f5e609b8074ec35d0d2fc8f5d03d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 033d363e5ff734f1f0c404a73d4f777acc529b3631e082be3fe5f6e33b76429199b2deef835d4c5ddc1b24b60a8477ebbdbe66278898ad33db8110ae94c9fc54
|
7
|
+
data.tar.gz: b0d3d7c16af3a0d39441c639de42b9c09eeb492962a6289a967f7f8ce489a3bf519dc97e109ba0bb756655a7d88ff539998cc7f0d6dd5b6ce47603efac5bcda0
|
data/.rubocop.yml
CHANGED
@@ -2,7 +2,7 @@ AllCops:
|
|
2
2
|
UseCache: false
|
3
3
|
NewCops: enable
|
4
4
|
Layout/LineLength:
|
5
|
-
Max:
|
5
|
+
Max: 1620
|
6
6
|
Lint/UselessRescue:
|
7
7
|
Enabled: false
|
8
8
|
Metrics/AbcSize:
|
@@ -16,7 +16,7 @@ Metrics/ClassLength:
|
|
16
16
|
Metrics/CyclomaticComplexity:
|
17
17
|
Max: 157
|
18
18
|
Metrics/MethodLength:
|
19
|
-
Max:
|
19
|
+
Max: 564
|
20
20
|
Metrics/ModuleLength:
|
21
21
|
Max: 1000
|
22
22
|
Metrics/PerceivedComplexity:
|
data/Gemfile
CHANGED
@@ -69,7 +69,7 @@ gem 'ostruct', '0.6.3'
|
|
69
69
|
gem 'packetfu', '2.0.0'
|
70
70
|
gem 'packetgen', '4.1.1'
|
71
71
|
gem 'pdf-reader', '2.15.0'
|
72
|
-
gem 'pg', '1.6.
|
72
|
+
gem 'pg', '1.6.2'
|
73
73
|
gem 'pry', '0.15.2'
|
74
74
|
gem 'pry-doc', '1.6.0'
|
75
75
|
gem 'rake', '13.3.0'
|
@@ -84,7 +84,7 @@ gem 'rspec', '3.13.1'
|
|
84
84
|
gem 'rtesseract', '3.1.4'
|
85
85
|
gem 'rubocop', '1.80.1'
|
86
86
|
gem 'rubocop-rake', '0.7.1'
|
87
|
-
gem 'rubocop-rspec', '3.
|
87
|
+
gem 'rubocop-rspec', '3.7.0'
|
88
88
|
gem 'ruby-audio', '1.6.1'
|
89
89
|
gem 'ruby-nmap', '1.0.3'
|
90
90
|
gem 'ruby-saml', '1.18.1'
|
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.
|
40
|
+
pwn[v0.5.391]:001 >>> PWN.help
|
41
41
|
```
|
42
42
|
|
43
43
|
[](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.
|
55
|
+
pwn[v0.5.391]: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.
|
65
|
+
pwn[v0.5.391]: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:
|
@@ -0,0 +1,181 @@
|
|
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('-tTARGET', '--target_url=TARGET', '<Required - Target URI to Scan>') do |t|
|
16
|
+
opts[:target_url] = t
|
17
|
+
end
|
18
|
+
|
19
|
+
options.on('-oPATH', '--report_output_path=PATH', '<Required - Output Path for Active Scan Issues>') do |o|
|
20
|
+
opts[:output_path] = o
|
21
|
+
end
|
22
|
+
|
23
|
+
options.on('-dSWAGGER', '--swagger_definitions=SWAGGER', '<Required - Comma-delimited list of Swagger JSON/YAML files to import>') do |s|
|
24
|
+
opts[:swagger_definitions] = s
|
25
|
+
end
|
26
|
+
|
27
|
+
options.on('-D', '--[no-]debug', '<Optional - Enable Debug Output and Do Not Delete Temporary OpenAPI Spec>') do |d|
|
28
|
+
opts[:debug] = d
|
29
|
+
end
|
30
|
+
|
31
|
+
options.on('-vVERSION', '--openapi_spec_version=VERSION', '<Optional - OpenAPI/Swagger Specification Version (Defaults to 3.0.3)>') do |o|
|
32
|
+
opts[:openapi_spec_version] = o
|
33
|
+
end
|
34
|
+
|
35
|
+
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|
|
36
|
+
opts[:additional_http_headers] = h
|
37
|
+
end
|
38
|
+
|
39
|
+
options.on('-cCOLOR', '--highlight-color=COLOR', '<Optional - Highlight Color to use when importing OpenAPI/Swagger definitions NONE||RED||ORANGE||YELLOW||GREEN||CYAN||BLUE||PINK||MAGENTA||GRAY (Defaults to GREEN)>') do |h|
|
40
|
+
opts[:highlight_color] = h
|
41
|
+
end
|
42
|
+
|
43
|
+
options.on('-nCOMMENTS', '--notes=COMMENTS', '<Optional - Comments to add when importing OpenAPI/Swagger definitions (Defaults to "Imported via <openapi_spec> on <timestamp>")>') do |n|
|
44
|
+
opts[:notes] = n
|
45
|
+
end
|
46
|
+
|
47
|
+
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|
|
48
|
+
opts[:exclude_paths] = e
|
49
|
+
end
|
50
|
+
|
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
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
|
60
|
+
opts[:in_scope] = s
|
61
|
+
end
|
62
|
+
end.parse!
|
63
|
+
|
64
|
+
if opts.empty?
|
65
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
|
69
|
+
begin
|
70
|
+
timestamp = Time.now.strftime('%Y-%m-%d_%H-%M-%S%Z')
|
71
|
+
logger = PWN::Plugins::PWNLogger.create
|
72
|
+
|
73
|
+
burp_jar_path = opts[:burp_jar_path]
|
74
|
+
headless = opts[:headless] || false
|
75
|
+
target_url = opts[:target_url]
|
76
|
+
raise 'ERROR: --target_url is required.' if target_url.nil?
|
77
|
+
|
78
|
+
output_path = opts[:output_path]
|
79
|
+
raise 'ERROR: --report_output_path is required.' if output_path.nil?
|
80
|
+
|
81
|
+
swagger_definitions = opts[:swagger_definitions]
|
82
|
+
raise 'ERROR: --swagger_definitions is required.' if swagger_definitions.nil?
|
83
|
+
|
84
|
+
debug = opts[:debug] || false
|
85
|
+
|
86
|
+
swagger_defs_arr = swagger_definitions.split(',').map(&:strip)
|
87
|
+
scheme = URI.parse(target_url).scheme
|
88
|
+
target_host = URI.parse(target_url).host
|
89
|
+
base_url = "#{scheme}://#{target_host}"
|
90
|
+
|
91
|
+
openapi_spec_version = opts[:openapi_spec_version]
|
92
|
+
openapi_spec = "/tmp/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
|
+
highlight_color = opts[:highlight_color] ||= 'GREEN'
|
106
|
+
notes = opts[:notes] ||= "Imported via #{openapi_spec} on #{timestamp}"
|
107
|
+
|
108
|
+
exlude_paths = opts[:exclude_paths]
|
109
|
+
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
110
|
+
|
111
|
+
in_scope = opts[:in_scope] ||= target_url
|
112
|
+
|
113
|
+
# ------
|
114
|
+
# Open Burp
|
115
|
+
if headless
|
116
|
+
burp_obj = PWN::Plugins::BurpSuite.start(
|
117
|
+
burp_jar_path: burp_jar_path,
|
118
|
+
browser_type: :headless
|
119
|
+
)
|
120
|
+
else
|
121
|
+
burp_obj = PWN::Plugins::BurpSuite.start(
|
122
|
+
burp_jar_path: burp_jar_path,
|
123
|
+
browser_type: :chrome
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
logger.info(burp_obj)
|
128
|
+
# Disable Proxy Intercepting Capabilities for this Driver
|
129
|
+
PWN::Plugins::BurpSuite.disable_proxy(burp_obj: burp_obj)
|
130
|
+
|
131
|
+
# Add URL to Target >> Scope >> Inclue in scope
|
132
|
+
PWN::Plugins::BurpSuite.add_to_scope(
|
133
|
+
burp_obj: burp_obj,
|
134
|
+
target_url: in_scope
|
135
|
+
)
|
136
|
+
|
137
|
+
json_sitemap = PWN::Plugins::BurpSuite.import_openapi_to_sitemap(
|
138
|
+
burp_obj: burp_obj,
|
139
|
+
openapi_spec: openapi_spec,
|
140
|
+
additional_http_headers: additional_http_headers,
|
141
|
+
highlight: highlight_color,
|
142
|
+
comment: notes,
|
143
|
+
debug: debug
|
144
|
+
)
|
145
|
+
|
146
|
+
raise "ERROR: Failed to import OpenAPI/Swagger spec #{openapi_spec} into Burp Suite Pro's Sitemap." if json_sitemap.nil? || json_sitemap.empty?
|
147
|
+
|
148
|
+
PWN::Plugins::BurpSuite.invoke_active_scan(
|
149
|
+
burp_obj: burp_obj,
|
150
|
+
target_url: in_scope,
|
151
|
+
exclude_paths: exlude_paths
|
152
|
+
)
|
153
|
+
|
154
|
+
# Dump a list of scan issues from Active Scan result
|
155
|
+
# scan_issues = PWN::Plugins::BurpSuite.get_scan_issues(burp_obj: burp_obj)
|
156
|
+
# puts scan_issues
|
157
|
+
|
158
|
+
# Once DefectDojo begins to support XML report results
|
159
|
+
report_types = %i[html xml]
|
160
|
+
report_types.each do |report_type|
|
161
|
+
this_output_path = "#{output_path}.html"
|
162
|
+
# this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.html"
|
163
|
+
|
164
|
+
this_output_path = "#{output_path}.xml" if report_type == :xml
|
165
|
+
# this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.xml" if report_type == :xml
|
166
|
+
|
167
|
+
PWN::Plugins::BurpSuite.generate_scan_report(
|
168
|
+
burp_obj: burp_obj,
|
169
|
+
target_url: in_scope,
|
170
|
+
report_type: report_type,
|
171
|
+
output_path: this_output_path
|
172
|
+
)
|
173
|
+
end
|
174
|
+
|
175
|
+
burp_obj = PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj)
|
176
|
+
rescue StandardError => e
|
177
|
+
raise e
|
178
|
+
ensure
|
179
|
+
FileUtils.rm_f(openapi_spec) unless debug
|
180
|
+
burp_obj = PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj) unless burp_obj.nil?
|
181
|
+
end
|
@@ -72,7 +72,6 @@ begin
|
|
72
72
|
if headless
|
73
73
|
burp_obj = PWN::Plugins::BurpSuite.start(
|
74
74
|
burp_jar_path: burp_jar_path,
|
75
|
-
headless: true,
|
76
75
|
browser_type: :headless
|
77
76
|
)
|
78
77
|
else
|
@@ -119,7 +118,11 @@ begin
|
|
119
118
|
sleep duration # Sleep for now so everything loads the way we expect - blech.
|
120
119
|
print "\n"
|
121
120
|
|
122
|
-
PWN::Plugins::BurpSuite.invoke_active_scan(
|
121
|
+
PWN::Plugins::BurpSuite.invoke_active_scan(
|
122
|
+
burp_obj: burp_obj,
|
123
|
+
target_url: in_scope,
|
124
|
+
exclude_paths: exlude_paths
|
125
|
+
)
|
123
126
|
|
124
127
|
# Dump a list of scan issues from Active Scan result
|
125
128
|
# scan_issues = PWN::Plugins::BurpSuite.get_scan_issues(burp_obj: burp_obj)
|
data/lib/pwn/plugins/open_api.rb
CHANGED
@@ -27,7 +27,7 @@ module PWN
|
|
27
27
|
base_url = opts[:base_url]
|
28
28
|
raise ArgumentError, 'base_url is required' if base_url.nil? || base_url.empty?
|
29
29
|
|
30
|
-
target_version = opts[:target_version]
|
30
|
+
target_version = opts[:target_version] ||= '3.0.3'
|
31
31
|
raise ArgumentError, "Unsupported OpenAPI version: #{target_version}" unless %w[3.0.0 3.0.1 3.0.2 3.0.3 3.1.0].include?(target_version)
|
32
32
|
|
33
33
|
output_json_path = opts[:output_json_path]
|
@@ -0,0 +1,255 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
require 'json'
|
5
|
+
require 'tty-spinner'
|
6
|
+
|
7
|
+
module PWN
|
8
|
+
module Reports
|
9
|
+
# This plugin generates the HTML header and includes external JS/CSS libraries for PWN reports.
|
10
|
+
module HTMLHeader
|
11
|
+
# Supported Method Parameters::
|
12
|
+
# PWN::Reports::HTMLHeader.generate(
|
13
|
+
# column_names: 'required - array of column names to use in the report table',
|
14
|
+
# driver_src_uri: 'required - pwn driver source code uri',
|
15
|
+
# )
|
16
|
+
|
17
|
+
public_class_method def self.generate(opts = {})
|
18
|
+
column_names = opts[:column_names] || []
|
19
|
+
driver_src_uri = opts[:driver_src_uri]
|
20
|
+
raise 'ERROR: :driver_src_uri must be provided' if driver_src_uri.nil? || driver_src_uri.strip == ''
|
21
|
+
|
22
|
+
driver_src_name = "~ #{driver_src_uri.to_s.split('/').last.gsub('_', ' ')}"
|
23
|
+
|
24
|
+
external_css_libraries = [
|
25
|
+
{
|
26
|
+
src: 'https://cdn.datatables.net/plug-ins/2.3.3/features/searchHighlight/dataTables.searchHighlight.css',
|
27
|
+
integrity: 'sha384-3FGcHDS9wKlVV/Pu4y1kojpLsNxlE3jQjdm1N0p7RC9f6xPdRAj78js3ELGiGP/j'
|
28
|
+
},
|
29
|
+
{
|
30
|
+
src: 'https://cdn.datatables.net/v/dt/jszip-3.10.1/dt-2.3.3/b-3.2.4/b-colvis-3.2.4/b-html5-3.2.4/b-print-3.2.4/fc-5.0.4/fh-4.0.3/kt-2.12.1/r-3.0.6/rg-1.5.2/rr-1.5.0/sc-2.4.3/sb-1.8.3/sp-2.3.5/sl-3.1.0/datatables.min.css',
|
31
|
+
integrity: 'sha384-51NLFpi/9qR2x0LAjQHiFAjV765f0g9+05EmKQ/QWINR/y3qonty8mPy68vEbo0z'
|
32
|
+
}
|
33
|
+
]
|
34
|
+
|
35
|
+
external_js_libraries = [
|
36
|
+
{
|
37
|
+
src: 'https://code.jquery.com/jquery-3.7.1.min.js',
|
38
|
+
integrity: 'sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo='
|
39
|
+
},
|
40
|
+
{
|
41
|
+
src: 'https://cdn.jsdelivr.net/npm/datatables.mark.js@2.1.0/dist/datatables.mark.min.js',
|
42
|
+
integrity: 'sha384-1NNYvadWgPeE3tcSCdnI+3HB9iVqXwDBQsQUCUJTygTR3Whmz3HFkMn1kdevXe/F'
|
43
|
+
},
|
44
|
+
{
|
45
|
+
src: 'https://bartaz.github.io/sandbox.js/jquery.highlight.js',
|
46
|
+
integrity: 'sha384-COfjQfuLZw+Zvx+XMsYIVqsBHXPaUJnu/nwutbZvnI3zys8lUt3N3SUDsR6yu7ud'
|
47
|
+
},
|
48
|
+
{
|
49
|
+
src: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js',
|
50
|
+
integrity: 'sha384-VFQrHzqBh5qiJIU0uGU5CIW3+OWpdGGJM9LBnGbuIH2mkICcFZ7lPd/AAtI7SNf7'
|
51
|
+
},
|
52
|
+
{
|
53
|
+
src: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js',
|
54
|
+
integrity: 'sha384-/RlQG9uf0M2vcTw3CX7fbqgbj/h8wKxw7C3zu9/GxcBPRKOEcESxaxufwRXqzq6n'
|
55
|
+
},
|
56
|
+
{
|
57
|
+
src: 'https://cdn.datatables.net/v/dt/jszip-3.10.1/dt-2.3.3/b-3.2.4/b-colvis-3.2.4/b-html5-3.2.4/b-print-3.2.4/fc-5.0.4/fh-4.0.3/kt-2.12.1/r-3.0.6/rg-1.5.2/rr-1.5.0/sc-2.4.3/sb-1.8.3/sp-2.3.5/sl-3.1.0/datatables.min.js',
|
58
|
+
integrity: 'sha384-jvnxkXTB++rTO/pbg6w5nj0jm5HiSGtTcBW5vnoLGRfmSxw3eyqNA0bJ+m6Skjw/'
|
59
|
+
},
|
60
|
+
{
|
61
|
+
src: 'https://cdn.datatables.net/plug-ins/2.3.3/features/searchHighlight/dataTables.searchHighlight.min.js',
|
62
|
+
integrity: 'sha384-XDdmvsWg5e1/POTILjMFvB3KtrBqRk5W1CG9aoi1+K6bBMPHQAvlKEiekndU6CTp'
|
63
|
+
},
|
64
|
+
{
|
65
|
+
src: 'https://unpkg.com/exceljs@4.4.0/dist/exceljs.min.js',
|
66
|
+
integrity: 'sha384-Pqp51FUN2/qzfxZxBCtF0stpc9ONI6MYZpVqmo8m20SoaQCzf+arZvACkLkirlPz'
|
67
|
+
}
|
68
|
+
]
|
69
|
+
|
70
|
+
markup = %(<!DOCTYPE HTML>
|
71
|
+
<html>
|
72
|
+
<head>
|
73
|
+
<!-- favicon.ico from https://0dayinc.com -->
|
74
|
+
<link rel="icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABIXAAASFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIkAAACJAgAAiSYAAIlbAACJcAAAiX0AAIlmAACJLQAAiQQAAIkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIkAAACJAAAAiS0AAIluAACJdwAAiXgAAIl+AACJeAAAiXQAAIk5AACJAQAAiQAAAAAAAAAAAAAAAAAAAAAAAACJAAAAiRgAAIlvAACJbQAAiXcAAIl7AACJcwAAiXEAAIl1AACJZwAAiR4AAIkAAACJAAAAAAAAAAAAAACJAAAAiQAAAIlEAACJfAAAiXIAAIlyAACJewAAiX4AAIl5AACJdQAAiXcAAIlIAACJAAAAiQAAAAAAAAAAAAAAiQAAAIkJAACJWQAAiXUAAIl9AACJdAAAiYYAAImLAACJdAAAiXkAAImNAACJfQAAiQwAAIkAAAAAAAAAAAAAAIkAAACJFQAAiWsAAIl2AACJfAAAiYIAAImCAACJfwAAiXYAAIl5AACJiQAAiYYAAIkWAACJAAAAAAAAAAAAAACJAAAAiSAAAIl2AACJeQAAiXkAAIl1AACJfwAAiYEAAIl8AACJbwAAiXoAAImBAACJFgAAiQAAAAAAAAAAAAAAiQAAAIkpAACJeAAAiXMAAIl3AACJeQAAiXUAAImAAACJfwAAiWYAAIl4AACJfwAAiR4AAIkAAAAAAAAAAAAAAIkAAACJKAAAiXkAAIlyAACJdQAAiXQAAIluAACJfAAAiXwAAIl3AACJewAAiXwAAIkvAACJAAAAAAAAAAAAAACJAAAAiSMAAIl4AACJdgAAiXsAAIl1AACJcQAAiXcAAIl6AACJeQAAiXoAAIl0AACJKQAAiQAAAAAAAAAAAAAAiQAAAIkXAACJaAAAiXgAAIl3AACJfAAAiXkAAIl3AACJZwAAiXcAAIl0AACJagAAiSgAAIkAAAAAAAAAAAAAAIkAAACJDgAAiV4AAIl5AACJbwAAiW4AAIl9AACJewAAiXcAAIl6AACJfQAAiW8AAIkWAACJAAAAAAAAAAAAAACJAAAAiQ0AAIllAACJewAAiXYAAIl4AACJdQAAiXUAAIl4AACJbQAAiXkAAIlNAACJAwAAiQAAAAAAAAAAAAAAiQAAAIkCAACJPQAAiXMAAIl2AACJeAAAiWgAAIlsAACJfQAAiXsAAIlwAACJGQAAiQAAAIkAAAAAAAAAAAAAAAAAAACJAAAAiQcAAIk4AACJXAAAiXoAAIl7AACJfAAAiYAAAIlsAACJJwAAiQMAAIkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIkAAACJAQAAiSsAAIluAACJewAAiXwAAIluAACJKgAAiQAAAIkAAAAAAAAAAAAAAAAA8A8AAPAHAADgBwAA4AcAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAHAADgBwAA8B8AAA==" type="image/x-icon" />
|
75
|
+
<style>
|
76
|
+
body {
|
77
|
+
font-family: Verdana, Geneva, sans-serif;
|
78
|
+
font-size: 11px;
|
79
|
+
background-color: #FFFFFF;
|
80
|
+
color: #084B8A !important;
|
81
|
+
}
|
82
|
+
|
83
|
+
a:link {
|
84
|
+
color: #0174DF;
|
85
|
+
text-decoration: none;
|
86
|
+
}
|
87
|
+
|
88
|
+
a:visited {
|
89
|
+
color: #B40404;
|
90
|
+
text-decoration: none;
|
91
|
+
}
|
92
|
+
|
93
|
+
a:hover {
|
94
|
+
color: #01A9DB;
|
95
|
+
text-decoration: underline;
|
96
|
+
}
|
97
|
+
|
98
|
+
a:active {
|
99
|
+
color: #610B5E;
|
100
|
+
text-decoration: underline;
|
101
|
+
}
|
102
|
+
|
103
|
+
div.toggle_col_and_button_group {
|
104
|
+
display: flex; /* Makes the container a flex container */
|
105
|
+
justify-content: none; /* Aligns items along the main axis */
|
106
|
+
align-items: flex-start; /* Aligns items to the start of the cross-axis */
|
107
|
+
width: 1275px !important;
|
108
|
+
}}
|
109
|
+
|
110
|
+
div.cols_to_toggle {
|
111
|
+
width: 300px !important;
|
112
|
+
text-align: left !important;
|
113
|
+
vertical-align: middle !important;
|
114
|
+
}
|
115
|
+
|
116
|
+
div.dt-buttons {
|
117
|
+
width: 420px !important;
|
118
|
+
text-align: right !important;
|
119
|
+
}
|
120
|
+
|
121
|
+
div.dt-container {
|
122
|
+
width: 1275px !important;
|
123
|
+
}
|
124
|
+
|
125
|
+
div.dt-scroll-body {
|
126
|
+
width: 1275px !important;
|
127
|
+
}
|
128
|
+
|
129
|
+
span.highlight {
|
130
|
+
background-color: cyan !important;
|
131
|
+
}
|
132
|
+
table {
|
133
|
+
width: 100%;
|
134
|
+
border-spacing:0px;
|
135
|
+
}
|
136
|
+
|
137
|
+
table.squish {
|
138
|
+
table-layout: fixed;
|
139
|
+
}
|
140
|
+
|
141
|
+
td {
|
142
|
+
vertical-align: top;
|
143
|
+
word-wrap: break-word !important;
|
144
|
+
border: none !important;
|
145
|
+
}
|
146
|
+
|
147
|
+
table.multi_line_select tr.odd {
|
148
|
+
background-color: #dedede !important; /* Gray for odd rows */
|
149
|
+
}
|
150
|
+
|
151
|
+
table.multi_line_select tr.even {
|
152
|
+
background-color: #ffffff !important; /* White for even rows */
|
153
|
+
}
|
154
|
+
|
155
|
+
tr.highlighted td {
|
156
|
+
background-color: #FFF396 !important;
|
157
|
+
}
|
158
|
+
</style>
|
159
|
+
)
|
160
|
+
|
161
|
+
external_css_libraries.each do |css_lib_hash|
|
162
|
+
css_lib = css_lib_hash[:src]
|
163
|
+
css_integrity = css_lib_hash[:integrity]
|
164
|
+
markup += %(
|
165
|
+
<link href="#{css_lib}" rel="stylesheet" integrity="#{css_integrity}" crossorigin="anonymous">
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
external_js_libraries.each do |js_lib|
|
170
|
+
js_src = js_lib[:src]
|
171
|
+
js_integrity = js_lib[:integrity]
|
172
|
+
markup += %(
|
173
|
+
<script type="text/javascript" src="#{js_src}" integrity="#{js_integrity}" crossorigin="anonymous"></script>
|
174
|
+
)
|
175
|
+
end
|
176
|
+
|
177
|
+
markup += %(
|
178
|
+
</head>
|
179
|
+
<body id="pwn_body">
|
180
|
+
|
181
|
+
<h1 style="display:inline">
|
182
|
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIEAAACCCAQAAADLPWN1AAAAAXNSR0IB2cksfwAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAJiS0dEAIKpO8E+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADTElEQVR42u2dyY7jMBBDqxrz/7+sOTRycCKJpOwBBsjzrWO3F4Ks3XKPUV++/dTXb3+qqjr8p1/i9HLPa2uxZ0z+6s011HXPngMWAAEQvGzBXK+fW6b+uUJ7ebTWuL7+yXPAAiB4E8IdurV5XObs1rLQEZ37HLAACKZCcLcrIe8QXFF7wAKEAAT/sS2oSWbnuqUOz55dFxYAwQNCyKi1iwdbuEudOq0j0A6jUlgABLYQ+saJVP1vHB1X0XFnzwELgAAIXrbgLMLS3YS2LMdZoWO2b8AChPB0mjRLQ9okX9tSWcuiTUepos2dbGmoIYSLEDRxXYur+0Pne3bRYZv3OXtCWAAEQFBGyUSVPa52ZCydZ5lO1tXz7nwl7xYWAMGbD/ocumvTEenUpc0oci2sLM4zHndyNCwAgjchtJlyKOK6SUt8s5GkdAxLmoQQgOCeU8wyOzevHNFv6fkomSAEu2Qyo4xKk3QXOROWS/fZddOBf1gABDI67JC4KkrLxmt3tQv3v1qKAxYAARBcbUE6OZzZhzKjtCzeO7MSRXSIEM7SJOWiRljOUCR1644loz7teBECQrikSSUJqbtESg6usLKY0+9E9fIasAAIgKA2M8juaNXM3eiO8RN5IywAgn8aHaoE5XTZjJNoUzvo7FqUTBCCIYQsQXKjSHdk485c+lnNkjQJIQDBzha4M4ZnTjGr+9fyumddbjrLCGGTJqWlEHeecOaclHx091rf3/o3OssIwagXeHTzaazjzKySoGoSPZUPLAACIHiiZDJu6F5Flm6mmHavVXZLdIgQ7OjQXZVGL+2kSe+ObHREc7ejDQuA4G0VCzcNcY+bRXPKgj9RhchqErAACICgNivjP1fDc2dJynSe2vWt+xyz54AFQBAu7ZS2vLJFNmbnc1t86RvRsAAITI+gBXG2LLyb6gzhiTqscTQsQAhAIG3BmcPyoj3nfCOKIl3b4rp1WAAEt76Vso4En3gXWb39nA7yUzJBCKEQUnvuRXO741Qi41r8sxEQWAAEQHDPFqy/cjduaPzsrbX1ne3WY4QFQLARwtMvQWWLx6VncqPX9W+wAAge/FbK2p5nn6PU4x6uRNzCOiwAAiCozdwhLAACIPiq7S/uVkwm4fz8nQAAAABJRU5ErkJggg==" type="image/png" style="iheight:70px;width:70px;"/>
|
183
|
+
<a href="#{driver_src_uri}" target="_blank">#{driver_src_name}</a>
|
184
|
+
</h1>
|
185
|
+
<h2 id="report_name"></h2><br />
|
186
|
+
|
187
|
+
<div id="toggle_col_and_button_group" class="toggle_col_and_button_group">
|
188
|
+
<div class="cols_to_toggle">
|
189
|
+
<b>Toggle Column(s) Visibility:</b>
|
190
|
+
)
|
191
|
+
|
192
|
+
last_column_idx = column_names.length - 1
|
193
|
+
column_names.each_with_index do |col, idx|
|
194
|
+
dat_col = idx + 1
|
195
|
+
encoded_col = CGI.escape_html(col)
|
196
|
+
if idx < last_column_idx
|
197
|
+
markup += %(
|
198
|
+
<a class="toggle-vis" data-column="#{dat_col}" href="#">#{encoded_col}</a> |
|
199
|
+
)
|
200
|
+
else
|
201
|
+
markup += %(
|
202
|
+
<a class="toggle-vis" data-column="#{dat_col}" href="#">#{encoded_col}</a>
|
203
|
+
)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
markup += %(
|
208
|
+
</div>
|
209
|
+
</div>
|
210
|
+
<div class="dt-container">
|
211
|
+
<table id="pwn_results" class="display" cellspacing="0">
|
212
|
+
<thead>
|
213
|
+
<tr>
|
214
|
+
<th>#</th>
|
215
|
+
)
|
216
|
+
|
217
|
+
column_names.each do |col|
|
218
|
+
markup += %(
|
219
|
+
<th>#{col}</th>
|
220
|
+
)
|
221
|
+
end
|
222
|
+
|
223
|
+
markup += %(
|
224
|
+
</tr>
|
225
|
+
</thead>
|
226
|
+
<!-- DataTables <tbody> -->
|
227
|
+
</table>
|
228
|
+
</div>
|
229
|
+
)
|
230
|
+
rescue StandardError => e
|
231
|
+
raise e
|
232
|
+
end
|
233
|
+
|
234
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
235
|
+
|
236
|
+
public_class_method def self.authors
|
237
|
+
"AUTHOR(S):
|
238
|
+
0day Inc. <support@0dayinc.com>
|
239
|
+
"
|
240
|
+
end
|
241
|
+
|
242
|
+
# Display Usage for this Module
|
243
|
+
|
244
|
+
public_class_method def self.help
|
245
|
+
puts "USAGE:
|
246
|
+
#{self}.generate(
|
247
|
+
column_names: 'Array of Column Names to use in the report table',
|
248
|
+
driver_src_uri: 're
|
249
|
+
|
250
|
+
#{self}.authors
|
251
|
+
"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
data/lib/pwn/reports/sast.rb
CHANGED
@@ -127,133 +127,18 @@ module PWN
|
|
127
127
|
JSON.pretty_generate(results_hash)
|
128
128
|
)
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
a:link {
|
144
|
-
color: #0174DF;
|
145
|
-
text-decoration: none;
|
146
|
-
}
|
147
|
-
|
148
|
-
a:visited {
|
149
|
-
color: #B40404;
|
150
|
-
text-decoration: none;
|
151
|
-
}
|
152
|
-
|
153
|
-
a:hover {
|
154
|
-
color: #01A9DB;
|
155
|
-
text-decoration: underline;
|
156
|
-
}
|
157
|
-
|
158
|
-
a:active {
|
159
|
-
color: #610B5E;
|
160
|
-
text-decoration: underline;
|
161
|
-
}
|
162
|
-
|
163
|
-
div.dt-container {
|
164
|
-
width: 1275px !important;
|
165
|
-
}
|
166
|
-
|
167
|
-
div.dt-scroll-body {
|
168
|
-
width: 1275px !important;
|
169
|
-
}
|
170
|
-
|
171
|
-
table {
|
172
|
-
width: 100%;
|
173
|
-
border-spacing:0px;
|
174
|
-
}
|
175
|
-
|
176
|
-
table.squish {
|
177
|
-
table-layout: fixed;
|
178
|
-
}
|
179
|
-
|
180
|
-
td {
|
181
|
-
vertical-align: top;
|
182
|
-
word-wrap: break-word !important;
|
183
|
-
border: none !important;
|
184
|
-
}
|
185
|
-
|
186
|
-
table.multi_line_select tr.odd {
|
187
|
-
background-color: #dedede !important; /* Gray for odd rows */
|
188
|
-
}
|
189
|
-
|
190
|
-
table.multi_line_select tr.even {
|
191
|
-
background-color: #ffffff !important; /* White for even rows */
|
192
|
-
}
|
193
|
-
|
194
|
-
tr.highlighted td {
|
195
|
-
background-color: #FFF396 !important;
|
196
|
-
}
|
197
|
-
</style>
|
198
|
-
|
199
|
-
<!-- jQuery & DataTables -->
|
200
|
-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
201
|
-
|
202
|
-
<link href="https://cdn.datatables.net/v/dt/jszip-3.10.1/dt-2.3.3/b-3.2.4/b-colvis-3.2.4/b-html5-3.2.4/b-print-3.2.4/fc-5.0.4/fh-4.0.3/kt-2.12.1/r-3.0.6/rg-1.5.2/rr-1.5.0/sc-2.4.3/sb-1.8.3/sp-2.3.5/sl-3.1.0/datatables.min.css" rel="stylesheet" integrity="sha384-51NLFpi/9qR2x0LAjQHiFAjV765f0g9+05EmKQ/QWINR/y3qonty8mPy68vEbo0z" crossorigin="anonymous">
|
203
|
-
|
204
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js" integrity="sha384-VFQrHzqBh5qiJIU0uGU5CIW3+OWpdGGJM9LBnGbuIH2mkICcFZ7lPd/AAtI7SNf7" crossorigin="anonymous"></script>
|
205
|
-
|
206
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js" integrity="sha384-/RlQG9uf0M2vcTw3CX7fbqgbj/h8wKxw7C3zu9/GxcBPRKOEcESxaxufwRXqzq6n" crossorigin="anonymous"></script>
|
207
|
-
|
208
|
-
<script src="https://cdn.datatables.net/v/dt/jszip-3.10.1/dt-2.3.3/b-3.2.4/b-colvis-3.2.4/b-html5-3.2.4/b-print-3.2.4/fc-5.0.4/fh-4.0.3/kt-2.12.1/r-3.0.6/rg-1.5.2/rr-1.5.0/sc-2.4.3/sb-1.8.3/sp-2.3.5/sl-3.1.0/datatables.min.js" integrity="sha384-jvnxkXTB++rTO/pbg6w5nj0jm5HiSGtTcBW5vnoLGRfmSxw3eyqNA0bJ+m6Skjw/" crossorigin="anonymous"></script>
|
209
|
-
|
210
|
-
<script src="https://unpkg.com/exceljs@4.4.0/dist/exceljs.min.js"></script>
|
211
|
-
</head>
|
212
|
-
|
213
|
-
<body id="pwn_body">
|
214
|
-
|
215
|
-
<h1 style="display:inline">
|
216
|
-
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIEAAACCCAQAAADLPWN1AAAAAXNSR0IB2cksfwAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAJiS0dEAIKpO8E+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADTElEQVR42u2dyY7jMBBDqxrz/7+sOTRycCKJpOwBBsjzrWO3F4Ks3XKPUV++/dTXb3+qqjr8p1/i9HLPa2uxZ0z+6s011HXPngMWAAEQvGzBXK+fW6b+uUJ7ebTWuL7+yXPAAiB4E8IdurV5XObs1rLQEZ37HLAACKZCcLcrIe8QXFF7wAKEAAT/sS2oSWbnuqUOz55dFxYAwQNCyKi1iwdbuEudOq0j0A6jUlgABLYQ+saJVP1vHB1X0XFnzwELgAAIXrbgLMLS3YS2LMdZoWO2b8AChPB0mjRLQ9okX9tSWcuiTUepos2dbGmoIYSLEDRxXYur+0Pne3bRYZv3OXtCWAAEQFBGyUSVPa52ZCydZ5lO1tXz7nwl7xYWAMGbD/ocumvTEenUpc0oci2sLM4zHndyNCwAgjchtJlyKOK6SUt8s5GkdAxLmoQQgOCeU8wyOzevHNFv6fkomSAEu2Qyo4xKk3QXOROWS/fZddOBf1gABDI67JC4KkrLxmt3tQv3v1qKAxYAARBcbUE6OZzZhzKjtCzeO7MSRXSIEM7SJOWiRljOUCR1644loz7teBECQrikSSUJqbtESg6usLKY0+9E9fIasAAIgKA2M8juaNXM3eiO8RN5IywAgn8aHaoE5XTZjJNoUzvo7FqUTBCCIYQsQXKjSHdk485c+lnNkjQJIQDBzha4M4ZnTjGr+9fyumddbjrLCGGTJqWlEHeecOaclHx091rf3/o3OssIwagXeHTzaazjzKySoGoSPZUPLAACIHiiZDJu6F5Flm6mmHavVXZLdIgQ7OjQXZVGL+2kSe+ObHREc7ejDQuA4G0VCzcNcY+bRXPKgj9RhchqErAACICgNivjP1fDc2dJynSe2vWt+xyz54AFQBAu7ZS2vLJFNmbnc1t86RvRsAAITI+gBXG2LLyb6gzhiTqscTQsQAhAIG3BmcPyoj3nfCOKIl3b4rp1WAAEt76Vso4En3gXWb39nA7yUzJBCKEQUnvuRXO741Qi41r8sxEQWAAEQHDPFqy/cjduaPzsrbX1ne3WY4QFQLARwtMvQWWLx6VncqPX9W+wAAge/FbK2p5nn6PU4x6uRNzCOiwAAiCozdwhLAACIPiq7S/uVkwm4fz8nQAAAABJRU5ErkJggg==" type="image/png" style="iheight:100px;width:100px;"/>
|
217
|
-
<a href="https://github.com/0dayInc/pwn/blob/master/bin/pwn_sast" target="_blank">~ pwn sast</a>
|
218
|
-
</h1>
|
219
|
-
<h2 id="report_name"></h2><br />
|
220
|
-
|
221
|
-
<div class="dt-buttons" id="button_group">
|
222
|
-
<!--<button type="button" id="debug_rows_selected">Rows Selected</button>-->
|
223
|
-
</div>
|
224
|
-
|
225
|
-
<div>
|
226
|
-
<b>Toggle Column(s) Visibility:</b>
|
227
|
-
<a class="toggle-vis" data-column="1" href="#">Timestamp</a> |
|
228
|
-
<a class="toggle-vis" data-column="2" href="#">Test Case / Security References</a> |
|
229
|
-
<a class="toggle-vis" data-column="3" href="#">Path</a> |
|
230
|
-
<a class="toggle-vis" data-column="4" href="#">Line#, Formatted Content, AI Analysis, & Last Committed By</a> |
|
231
|
-
<a class="toggle-vis" data-column="5" href="#">Raw Content</a> |
|
232
|
-
<a class="toggle-vis" data-column="6" href="#">Test Case (Anti-Pattern) Filter</a>
|
233
|
-
</div>
|
234
|
-
<br /><br />
|
235
|
-
|
236
|
-
<div>
|
237
|
-
Search tips: Use space-separated keywords for AND search, prefix with - to exclude (e.g., "security -password"), or enclose in / / for regex (e.g., "/^important.*$/i").
|
238
|
-
</div><br />
|
239
|
-
|
240
|
-
<div>
|
241
|
-
<table id="pwn_scan_git_source_results" class="display" cellspacing="0">
|
242
|
-
<thead>
|
243
|
-
<tr>
|
244
|
-
<th>#</th>
|
245
|
-
<th>Timestamp</th>
|
246
|
-
<th>Test Case / Security References</th>
|
247
|
-
<th>Path</th>
|
248
|
-
<th>Line#, Formatted Content, AI Analysis, & Last Committed By</th>
|
249
|
-
<th>Raw Content</th>
|
250
|
-
<th>Test Case (Anti-Pattern) Filter</th>
|
251
|
-
</tr>
|
252
|
-
</thead>
|
253
|
-
<!-- DataTables <tbody> -->
|
254
|
-
</table>
|
255
|
-
</div>
|
256
|
-
|
130
|
+
column_names = [
|
131
|
+
'Timestamp',
|
132
|
+
'Test Case / Security References',
|
133
|
+
'Path',
|
134
|
+
'Line# | Source | AI Analysis | Author',
|
135
|
+
'Raw Content',
|
136
|
+
'Test Case'
|
137
|
+
]
|
138
|
+
|
139
|
+
driver_src_uri = 'https://github.com/0dayinc/pwn/blob/master/bin/pwn_sast'
|
140
|
+
|
141
|
+
html_report = %(#{PWN::Reports::HTMLHeader.generate(column_names: column_names, driver_src_uri: driver_src_uri)}
|
257
142
|
<script>
|
258
143
|
var htmlEntityEncode = $.fn.dataTable.render.text().display;
|
259
144
|
|
@@ -266,10 +151,11 @@ module PWN
|
|
266
151
|
var offset = 400;
|
267
152
|
var min_scroll_height = 100;
|
268
153
|
var scrollYHeight = Math.max(min_scroll_height, windowHeight - offset); // Ensure minimum of 600px
|
269
|
-
var table = $('#
|
154
|
+
var table = $('#pwn_results').DataTable( {
|
270
155
|
"order": [[2, 'asc']],
|
271
156
|
"scrollY": scrollYHeight + "px",
|
272
157
|
"scrollCollapse": true,
|
158
|
+
"searchHighlight": true,
|
273
159
|
"paging": true,
|
274
160
|
"lengthMenu": [25, 50, 100, 250, 500, 1000, 2500, 5000],
|
275
161
|
"drawCallback": function () {
|
@@ -442,61 +328,52 @@ module PWN
|
|
442
328
|
]
|
443
329
|
});
|
444
330
|
|
445
|
-
table.buttons().container().
|
331
|
+
table.buttons().container().appendTo('#toggle_col_and_button_group');
|
446
332
|
}
|
447
333
|
});
|
448
334
|
|
449
|
-
$('#
|
335
|
+
$('#pwn_results tbody').on('click', '.multi_line_select tr', function () {
|
450
336
|
$(this).toggleClass('highlighted');
|
451
337
|
});
|
452
338
|
|
339
|
+
// Dynamically create the smart toggle label and input
|
340
|
+
var smartLabel = $('<label for="smart-toggle">Smart Search (e.g., "security !password")</label>');
|
341
|
+
var smartInput = $('<input type="radio" id="smart-toggle" name="searchMode" value="" checked>');
|
342
|
+
smartLabel.prepend(smartInput); // Prepend input inside label for proper association
|
343
|
+
|
344
|
+
// Dynamically create the regex toggle label and input
|
345
|
+
var regexLabel = $('<label for="regex-toggle">Regex Search (e.g., "^important.*$")</label>');
|
346
|
+
var regexInput = $('<input type="radio" id="regex-toggle" name="searchMode" value="">');
|
347
|
+
regexLabel.prepend(regexInput); // Prepend input inside label
|
348
|
+
|
349
|
+
// Now relocate them as before (insert before the search input)
|
350
|
+
smartLabel.insertBefore('#dt-search-0');
|
351
|
+
regexLabel.insertBefore('#dt-search-0');
|
352
|
+
|
353
|
+
// Style for inline display and spacing
|
354
|
+
smartLabel.css({ display: 'inline-block', marginRight: '10px' });
|
355
|
+
regexLabel.css({ display: 'inline-block', marginRight: '10px' });
|
356
|
+
|
357
|
+
// Optional: Hide the default "Search:" label if not needed
|
358
|
+
$('.dt-search label:first-of-type').hide();
|
359
|
+
|
453
360
|
// Custom advanced search handling
|
454
|
-
$('
|
455
|
-
$('
|
456
|
-
var
|
457
|
-
|
458
|
-
var
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
filterFunc = function(settings, data, dataIndex) {
|
463
|
-
var rowData = data.join(' ');
|
464
|
-
return regex.test(rowData);
|
465
|
-
};
|
466
|
-
} catch (e) {
|
467
|
-
filterFunc = function(settings, data, dataIndex) {
|
468
|
-
return true;
|
469
|
-
};
|
470
|
-
}
|
471
|
-
} else {
|
472
|
-
var positives = [];
|
473
|
-
var negatives = [];
|
474
|
-
var terms = search.split(/\\s+/).filter(function(t) { return t.length > 0; });
|
475
|
-
for (var i = 0; i < terms.length; i++) {
|
476
|
-
var term = terms[i];
|
477
|
-
if (term.startsWith('-')) {
|
478
|
-
var cleanTerm = term.substring(1).toLowerCase();
|
479
|
-
if (cleanTerm) negatives.push(cleanTerm);
|
480
|
-
} else {
|
481
|
-
positives.push(term.toLowerCase());
|
482
|
-
}
|
483
|
-
}
|
484
|
-
filterFunc = function(settings, data, dataIndex) {
|
485
|
-
var rowData = data.join(' ').toLowerCase();
|
486
|
-
for (var j = 0; j < positives.length; j++) {
|
487
|
-
if (!rowData.includes(positives[j])) return false;
|
488
|
-
}
|
489
|
-
for (var k = 0; k < negatives.length; k++) {
|
490
|
-
if (rowData.includes(negatives[k])) return false;
|
491
|
-
}
|
492
|
-
return true;
|
493
|
-
};
|
494
|
-
}
|
361
|
+
$('#dt-search-0').unbind();
|
362
|
+
$('#dt-search-0').on('input', function() {
|
363
|
+
var table = $('#pwn_results').DataTable();
|
364
|
+
var searchTerm = this.value;
|
365
|
+
var isRegex = $('#regex-toggle').prop('checked');
|
366
|
+
var isSmart = $('#smart-toggle').prop('checked');
|
367
|
+
table.search(searchTerm, isRegex, isSmart).draw();
|
368
|
+
});
|
495
369
|
|
496
|
-
|
497
|
-
|
498
|
-
table
|
499
|
-
|
370
|
+
// Additionally, reapply search on toggle changes (assuming radios exist in HTML)
|
371
|
+
$('#regex-toggle, #smart-toggle').on('input', function() {
|
372
|
+
var table = $('#pwn_results').DataTable();
|
373
|
+
var searchTerm = this.value;
|
374
|
+
var isRegex = $('#regex-toggle').prop('checked');
|
375
|
+
var isSmart = $('#smart-toggle').prop('checked');
|
376
|
+
table.search(searchTerm, isRegex, isSmart).draw();
|
500
377
|
});
|
501
378
|
|
502
379
|
// Toggle Columns
|
@@ -516,10 +393,12 @@ module PWN
|
|
516
393
|
|
517
394
|
// Select All and Deselect All
|
518
395
|
function select_deselect_all() {
|
519
|
-
|
520
|
-
|
396
|
+
var visible_multi_line_trs = $('#pwn_results tbody tr:visible .multi_line_select tr');
|
397
|
+
var highlighted_in_visible = visible_multi_line_trs.filter('.highlighted');
|
398
|
+
if (highlighted_in_visible.length === visible_multi_line_trs.length) {
|
399
|
+
highlighted_in_visible.removeClass('highlighted');
|
521
400
|
} else {
|
522
|
-
|
401
|
+
visible_multi_line_trs.filter(':not(.highlighted)').addClass('highlighted');
|
523
402
|
}
|
524
403
|
}
|
525
404
|
|
@@ -774,7 +653,7 @@ module PWN
|
|
774
653
|
</script>
|
775
654
|
</body>
|
776
655
|
</html>
|
777
|
-
|
656
|
+
)
|
778
657
|
|
779
658
|
File.open("#{dir_path}/#{report_name}.html", 'w') do |f|
|
780
659
|
f.print(html_report)
|
data/lib/pwn/reports.rb
CHANGED
@@ -9,6 +9,7 @@ module PWN
|
|
9
9
|
# autoload :JSON, 'pwn/reports/json'
|
10
10
|
# autoload :PDF, 'pwn/reports/pdf'
|
11
11
|
autoload :Fuzz, 'pwn/reports/fuzz'
|
12
|
+
autoload :HTMLHeader, 'pwn/reports/html_header'
|
12
13
|
autoload :Phone, 'pwn/reports/phone'
|
13
14
|
autoload :SAST, 'pwn/reports/sast'
|
14
15
|
autoload :URIBuster, 'pwn/reports/uri_buster'
|
data/lib/pwn/version.rb
CHANGED
data/pwn.gemspec
CHANGED
@@ -59,6 +59,9 @@ Gem::Specification.new do |spec|
|
|
59
59
|
gem_name = columns[1].delete("'").delete(',')
|
60
60
|
gem_version = columns.last.delete("'")
|
61
61
|
|
62
|
+
# Good for debugging issues in Gemfile
|
63
|
+
# puts "pwn.gemspec: Adding dependency: #{gem_name} #{gem_version}"
|
64
|
+
|
62
65
|
if dev_dependency_arr.include?(gem_name.to_sym)
|
63
66
|
spec.add_development_dependency(
|
64
67
|
gem_name,
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe PWN::Reports::HTMLHeader do
|
6
|
+
it 'should display information for authors' do
|
7
|
+
authors_response = PWN::Reports::HTMLHeader
|
8
|
+
expect(authors_response).to respond_to :authors
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should display information for existing help method' do
|
12
|
+
help_response = PWN::Reports::HTMLHeader
|
13
|
+
expect(help_response).to respond_to :help
|
14
|
+
end
|
15
|
+
end
|
data/third_party/pwn_rdoc.jsonl
CHANGED
@@ -901,7 +901,7 @@
|
|
901
901
|
{"messages":[{"role":"user","content":"PWN::Plugins::SSN.generate Usage"},{"role":"assistant","content":"`PWN::Plugins::SSN.generate`: Supported Method Parameters\n\nPWN::Plugins::SSN.generate(\n\ncount: 'required - number of SSN numbers to generate'\n\n)\n"}]}
|
902
902
|
{"messages":[{"role":"user","content":"PWN::Plugins::SSN.help Usage"},{"role":"assistant","content":"`PWN::Plugins::SSN.help`: "}]}
|
903
903
|
{"messages":[{"role":"user","content":"PWN::Plugins::ScannableCodes.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::ScannableCodes.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
904
|
-
{"messages":[{"role":"user","content":"PWN::Plugins::ScannableCodes.generate Usage"},{"role":"assistant","content":"`PWN::Plugins::ScannableCodes.generate`: Supported Method Parameters\n\nresponse = PWN::Plugins::ScannableCodes.generate(\n\ndata: 'required - data to encode',\ntype: 'optional - :barcode || :qrcode (defaults to :qrcode)',\npath: 'optional - path to save image (defaults to \"./#{data}.png\")'\n\n)\n"}]}
|
904
|
+
{"messages":[{"role":"user","content":"PWN::Plugins::ScannableCodes.generate Usage"},{"role":"assistant","content":"`PWN::Plugins::ScannableCodes.generate`: Supported Method Parameters\n\nresponse = PWN::Plugins::ScannableCodes.generate(\n\ndata: 'required - data to encode',\ntype: 'optional - :barcode || :qrcode (defaults to :qrcode)',\nsize: 'optional - size of the image when type is :qrcode (defaults to 200)',\npath: 'optional - path to save image (defaults to \"./#{data}.png\")'\nreturn_type: 'optional - :base64 || :file (defaults to :file)'\n\n)\n"}]}
|
905
905
|
{"messages":[{"role":"user","content":"PWN::Plugins::ScannableCodes.help Usage"},{"role":"assistant","content":"`PWN::Plugins::ScannableCodes.help`: "}]}
|
906
906
|
{"messages":[{"role":"user","content":"PWN::Plugins::Serial.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::Serial.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
907
907
|
{"messages":[{"role":"user","content":"PWN::Plugins::Serial.connect Usage"},{"role":"assistant","content":"`PWN::Plugins::Serial.connect`: Supported Method Parameters\n\nserial_obj = PWN::Plugins::Serial.connect(\n\nblock_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)',\nbaud: 'optional - (defaults to 9600)',\ndata_bits: 'optional - (defaults to 8)',\nstop_bits: 'optional - (defaults to 1)',\nparity: 'optional - :even|:mark|:odd|:space|:none (defaults to :none)'\n\n)\n"}]}
|
@@ -1050,6 +1050,9 @@
|
|
1050
1050
|
{"messages":[{"role":"user","content":"PWN::Reports::Fuzz.authors Usage"},{"role":"assistant","content":"`PWN::Reports::Fuzz.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
1051
1051
|
{"messages":[{"role":"user","content":"PWN::Reports::Fuzz.generate Usage"},{"role":"assistant","content":"`PWN::Reports::Fuzz.generate`: Supported Method Parameters\n\nPWN::Reports::Fuzz.generate(\n\ndir_path: dir_path,\nresults_hash: results_hash,\nchar_encoding: 'optional - character encoding returned by PWN::Plugins::Char.list_encoders (defaults to UTF-8)'\n\n)\n"}]}
|
1052
1052
|
{"messages":[{"role":"user","content":"PWN::Reports::Fuzz.help Usage"},{"role":"assistant","content":"`PWN::Reports::Fuzz.help`: "}]}
|
1053
|
+
{"messages":[{"role":"user","content":"PWN::Reports::HTMLHeader.authors Usage"},{"role":"assistant","content":"`PWN::Reports::HTMLHeader.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
1054
|
+
{"messages":[{"role":"user","content":"PWN::Reports::HTMLHeader.generate Usage"},{"role":"assistant","content":"`PWN::Reports::HTMLHeader.generate`: Supported Method Parameters\n\nPWN::Reports::HTMLHeader.generate(\n\ncolumn_names: 'required - array of column names to use in the report table',\ndriver_src_uri: 'required - pwn driver source code uri',\n\n)\n"}]}
|
1055
|
+
{"messages":[{"role":"user","content":"PWN::Reports::HTMLHeader.help Usage"},{"role":"assistant","content":"`PWN::Reports::HTMLHeader.help`: "}]}
|
1053
1056
|
{"messages":[{"role":"user","content":"PWN::Reports::Phone.authors Usage"},{"role":"assistant","content":"`PWN::Reports::Phone.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
1054
1057
|
{"messages":[{"role":"user","content":"PWN::Reports::Phone.generate Usage"},{"role":"assistant","content":"`PWN::Reports::Phone.generate`: Supported Method Parameters\n\nPWN::Reports::Phone.generate(\n\ndir_path: dir_path,\nresults_hash: results_hash\n\n)\n"}]}
|
1055
1058
|
{"messages":[{"role":"user","content":"PWN::Reports::Phone.help Usage"},{"role":"assistant","content":"`PWN::Reports::Phone.help`: "}]}
|
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.
|
4
|
+
version: 0.5.391
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
@@ -757,14 +757,14 @@ dependencies:
|
|
757
757
|
requirements:
|
758
758
|
- - '='
|
759
759
|
- !ruby/object:Gem::Version
|
760
|
-
version: 1.6.
|
760
|
+
version: 1.6.2
|
761
761
|
type: :runtime
|
762
762
|
prerelease: false
|
763
763
|
version_requirements: !ruby/object:Gem::Requirement
|
764
764
|
requirements:
|
765
765
|
- - '='
|
766
766
|
- !ruby/object:Gem::Version
|
767
|
-
version: 1.6.
|
767
|
+
version: 1.6.2
|
768
768
|
- !ruby/object:Gem::Dependency
|
769
769
|
name: pry
|
770
770
|
requirement: !ruby/object:Gem::Requirement
|
@@ -967,14 +967,14 @@ dependencies:
|
|
967
967
|
requirements:
|
968
968
|
- - '='
|
969
969
|
- !ruby/object:Gem::Version
|
970
|
-
version: 3.
|
970
|
+
version: 3.7.0
|
971
971
|
type: :runtime
|
972
972
|
prerelease: false
|
973
973
|
version_requirements: !ruby/object:Gem::Requirement
|
974
974
|
requirements:
|
975
975
|
- - '='
|
976
976
|
- !ruby/object:Gem::Version
|
977
|
-
version: 3.
|
977
|
+
version: 3.7.0
|
978
978
|
- !ruby/object:Gem::Dependency
|
979
979
|
name: ruby-audio
|
980
980
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1279,6 +1279,7 @@ executables:
|
|
1279
1279
|
- pwn_aws_describe_resources
|
1280
1280
|
- pwn_bdba_groups
|
1281
1281
|
- pwn_bdba_scan
|
1282
|
+
- pwn_burp_suite_pro_active_rest_api_scan
|
1282
1283
|
- pwn_burp_suite_pro_active_scan
|
1283
1284
|
- pwn_char_base64_encoding
|
1284
1285
|
- pwn_char_dec_encoding
|
@@ -1348,6 +1349,7 @@ files:
|
|
1348
1349
|
- bin/pwn_aws_describe_resources
|
1349
1350
|
- bin/pwn_bdba_groups
|
1350
1351
|
- bin/pwn_bdba_scan
|
1352
|
+
- bin/pwn_burp_suite_pro_active_rest_api_scan
|
1351
1353
|
- bin/pwn_burp_suite_pro_active_scan
|
1352
1354
|
- bin/pwn_char_base64_encoding
|
1353
1355
|
- bin/pwn_char_dec_encoding
|
@@ -1900,6 +1902,7 @@ files:
|
|
1900
1902
|
- lib/pwn/plugins/xxd.rb
|
1901
1903
|
- lib/pwn/reports.rb
|
1902
1904
|
- lib/pwn/reports/fuzz.rb
|
1905
|
+
- lib/pwn/reports/html_header.rb
|
1903
1906
|
- lib/pwn/reports/phone.rb
|
1904
1907
|
- lib/pwn/reports/sast.rb
|
1905
1908
|
- lib/pwn/reports/uri_buster.rb
|
@@ -2242,6 +2245,7 @@ files:
|
|
2242
2245
|
- spec/lib/pwn/plugins/xxd_spec.rb
|
2243
2246
|
- spec/lib/pwn/plugins_spec.rb
|
2244
2247
|
- spec/lib/pwn/reports/fuzz_spec.rb
|
2248
|
+
- spec/lib/pwn/reports/html_header_spec.rb
|
2245
2249
|
- spec/lib/pwn/reports/phone_spec.rb
|
2246
2250
|
- spec/lib/pwn/reports/sast_spec.rb
|
2247
2251
|
- spec/lib/pwn/reports/uri_buster_spec.rb
|