pwn 0.5.387 → 0.5.390
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 +1 -1
- data/README.md +3 -3
- data/lib/pwn/plugins/git.rb +2 -6
- data/lib/pwn/plugins/scannable_codes.rb +20 -3
- data/lib/pwn/reports/html_header.rb +255 -0
- data/lib/pwn/reports/sast.rb +123 -243
- 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 +1 -3
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29455d0f44118f016d59ba4370e80b883a189d960697d2ad98f1c6d36b6b953d
|
4
|
+
data.tar.gz: bda5ff363c12e7b054daf8f71936d8d83ccf973c7e927333331e6107ddb9e4df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 885789f3328900c0e0cfee3c69a868a54851b9b156c61399a32f789daa767e1f33d5a1f4846d197832f76f8916da525cd40e564666691ed2489b495e0e47cc06
|
7
|
+
data.tar.gz: b25394c00e67546058cc7cc0b8da9cdf2b93a1165f4305ed056c5959907273f4b884607be987550095fd9fcae14bdacfd81a58a7e08c6381742cca2be6c947ee
|
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
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.390]: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.390]: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.390]: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:
|
data/lib/pwn/plugins/git.rb
CHANGED
@@ -56,11 +56,7 @@ module PWN
|
|
56
56
|
target_file = opts[:target_file].to_s
|
57
57
|
target_file.gsub!(%r{^#{repo_root}/}, '')
|
58
58
|
|
59
|
-
if File.directory?(repo_root) && File.file?("#{repo_root}/#{target_file}")
|
60
|
-
`git --git-dir="#{Shellwords.escape(repo_root)}/.git" log -L #{from_line},#{to_line}:"#{Shellwords.escape(target_file)}" 2> /dev/null | grep Author | head -n 1`.to_s.scrub
|
61
|
-
else
|
62
|
-
-1
|
63
|
-
end
|
59
|
+
`git --git-dir="#{Shellwords.escape(repo_root)}/.git" log -L #{from_line},#{to_line}:"#{Shellwords.escape(target_file)}" 2> /dev/null | grep Author | head -n 1`.to_s.scrub if File.directory?(repo_root) && File.file?("#{repo_root}/#{target_file}")
|
64
60
|
rescue StandardError => e
|
65
61
|
raise e
|
66
62
|
end
|
@@ -120,7 +116,7 @@ module PWN
|
|
120
116
|
)
|
121
117
|
end
|
122
118
|
|
123
|
-
author
|
119
|
+
author ||= 'N/A'
|
124
120
|
rescue StandardError => e
|
125
121
|
raise e
|
126
122
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'barby'
|
4
|
-
require '
|
4
|
+
require 'base64'
|
5
|
+
require 'fileutils'
|
5
6
|
require 'chunky_png'
|
7
|
+
require 'rqrcode'
|
6
8
|
|
7
9
|
module PWN
|
8
10
|
module Plugins
|
@@ -12,7 +14,9 @@ module PWN
|
|
12
14
|
# response = PWN::Plugins::ScannableCodes.generate(
|
13
15
|
# data: 'required - data to encode',
|
14
16
|
# type: 'optional - :barcode || :qrcode (defaults to :qrcode)',
|
17
|
+
# size: 'optional - size of the image when type is :qrcode (defaults to 200)',
|
15
18
|
# path: 'optional - path to save image (defaults to "./#{data}.png")'
|
19
|
+
# return_type: 'optional - :base64 || :file (defaults to :file)'
|
16
20
|
# )
|
17
21
|
|
18
22
|
public_class_method def self.generate(opts = {})
|
@@ -22,22 +26,34 @@ module PWN
|
|
22
26
|
type = opts[:type]
|
23
27
|
type ||= :qrcode
|
24
28
|
|
29
|
+
size = opts[:size]
|
30
|
+
raise 'ERROR: size is only applicable when type is :qrcode.' if size && type != :qrcode
|
31
|
+
|
25
32
|
path = opts[:path]
|
26
33
|
path ||= "./#{data}.png"
|
27
34
|
|
35
|
+
return_type = opts[:return_type] ||= :file
|
36
|
+
|
28
37
|
case type
|
29
38
|
when :barcode
|
30
39
|
barcode = Barby::Code128B.new(data)
|
31
40
|
barcode.to_png.save(path)
|
32
41
|
when :qrcode
|
42
|
+
size ||= 200
|
33
43
|
qrcode = RQRCode::QRCode.new(data)
|
34
44
|
png = qrcode.as_png
|
35
|
-
png.resize(
|
45
|
+
png.resize(size, size).save(path)
|
36
46
|
else
|
37
47
|
raise 'ERROR: type must be :barcode or :qrcode.'
|
38
48
|
end
|
39
49
|
|
40
|
-
|
50
|
+
data = "Saved #{type} to #{path}"
|
51
|
+
if return_type == :base64
|
52
|
+
data = Base64.strict_encode64(File.binread(path))
|
53
|
+
FileUtils.rm_f(path)
|
54
|
+
end
|
55
|
+
|
56
|
+
data
|
41
57
|
rescue Interrupt
|
42
58
|
puts "\nGoodbye."
|
43
59
|
rescue StandardError => e
|
@@ -59,6 +75,7 @@ module PWN
|
|
59
75
|
#{self}.generate(
|
60
76
|
data: 'required - data to encode',
|
61
77
|
type: 'optional - :barcode || :qrcode (defaults to :qrcode)',
|
78
|
+
size: 'optional - size of the image when type is :qrcode (defaults to 200)',
|
62
79
|
path: 'optional - path to save image (defaults to \"./\#{data}.png\")'
|
63
80
|
)
|
64
81
|
|
@@ -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,140 +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://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
|
211
|
-
|
212
|
-
<!--
|
213
|
-
<script type="text/javascript" src="//code.jquery.com/jquery-3.6.0.min.js"></script>
|
214
|
-
|
215
|
-
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/v/dt/dt-1.11.4/b-2.2.2/b-colvis-2.2.2/b-html5-2.2.2/b-print-2.2.2/cr-1.5.5/fc-4.0.1/fh-3.2.1/kt-2.6.4/r-2.2.9/rg-1.1.4/rr-1.2.8/sc-2.0.5/sp-1.4.0/sl-1.3.4/datatables.min.css"/>
|
216
|
-
|
217
|
-
<script type="text/javascript" src="//cdn.datatables.net/v/dt/dt-1.11.4/b-2.2.2/b-colvis-2.2.2/b-html5-2.2.2/b-print-2.2.2/cr-1.5.5/fc-4.0.1/fh-3.2.1/kt-2.6.4/r-2.2.9/rg-1.1.4/rr-1.2.8/sc-2.0.5/sp-1.4.0/sl-1.3.4/datatables.min.js"></script>
|
218
|
-
-->
|
219
|
-
</head>
|
220
|
-
|
221
|
-
<body id="pwn_body">
|
222
|
-
|
223
|
-
<h1 style="display:inline">
|
224
|
-
<a href="https://github.com/0dayinc/pwn/tree/master">~ pwn sast</a>
|
225
|
-
</h1><br /><br />
|
226
|
-
<h2 id="report_name"></h2><br />
|
227
|
-
|
228
|
-
<div class="dt-buttons" id="button_group">
|
229
|
-
<!--<button type="button" id="debug_rows_selected">Rows Selected</button>-->
|
230
|
-
</div>
|
231
|
-
|
232
|
-
<div>
|
233
|
-
<b>Toggle Column(s) Visibility:</b>
|
234
|
-
<a class="toggle-vis" data-column="1" href="#">Timestamp</a> |
|
235
|
-
<a class="toggle-vis" data-column="2" href="#">Test Case / Security References</a> |
|
236
|
-
<a class="toggle-vis" data-column="3" href="#">Path</a> |
|
237
|
-
<a class="toggle-vis" data-column="4" href="#">Line#, Formatted Content, AI Analysis, & Last Committed By</a> |
|
238
|
-
<a class="toggle-vis" data-column="5" href="#">Raw Content</a> |
|
239
|
-
<a class="toggle-vis" data-column="6" href="#">Test Case (Anti-Pattern) Filter</a>
|
240
|
-
</div>
|
241
|
-
<br /><br />
|
242
|
-
|
243
|
-
<div>
|
244
|
-
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").
|
245
|
-
</div><br />
|
246
|
-
|
247
|
-
<div>
|
248
|
-
<table id="pwn_scan_git_source_results" class="display" cellspacing="0">
|
249
|
-
<thead>
|
250
|
-
<tr>
|
251
|
-
<th>#</th>
|
252
|
-
<th>Timestamp</th>
|
253
|
-
<th>Test Case / Security References</th>
|
254
|
-
<th>Path</th>
|
255
|
-
<th>Line#, Formatted Content, AI Analysis, & Last Committed By</th>
|
256
|
-
<th>Raw Content</th>
|
257
|
-
<th>Test Case (Anti-Pattern) Filter</th>
|
258
|
-
</tr>
|
259
|
-
</thead>
|
260
|
-
<!-- DataTables <tbody> -->
|
261
|
-
</table>
|
262
|
-
</div>
|
263
|
-
|
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)}
|
264
142
|
<script>
|
265
143
|
var htmlEntityEncode = $.fn.dataTable.render.text().display;
|
266
144
|
|
@@ -273,10 +151,11 @@ module PWN
|
|
273
151
|
var offset = 400;
|
274
152
|
var min_scroll_height = 100;
|
275
153
|
var scrollYHeight = Math.max(min_scroll_height, windowHeight - offset); // Ensure minimum of 600px
|
276
|
-
var table = $('#
|
154
|
+
var table = $('#pwn_results').DataTable( {
|
277
155
|
"order": [[2, 'asc']],
|
278
156
|
"scrollY": scrollYHeight + "px",
|
279
157
|
"scrollCollapse": true,
|
158
|
+
"searchHighlight": true,
|
280
159
|
"paging": true,
|
281
160
|
"lengthMenu": [25, 50, 100, 250, 500, 1000, 2500, 5000],
|
282
161
|
"drawCallback": function () {
|
@@ -449,61 +328,52 @@ module PWN
|
|
449
328
|
]
|
450
329
|
});
|
451
330
|
|
452
|
-
table.buttons().container().
|
331
|
+
table.buttons().container().appendTo('#toggle_col_and_button_group');
|
453
332
|
}
|
454
333
|
});
|
455
334
|
|
456
|
-
$('#
|
335
|
+
$('#pwn_results tbody').on('click', '.multi_line_select tr', function () {
|
457
336
|
$(this).toggleClass('highlighted');
|
458
337
|
});
|
459
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
|
+
|
460
360
|
// Custom advanced search handling
|
461
|
-
$('
|
462
|
-
$('
|
463
|
-
var
|
464
|
-
|
465
|
-
var
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
filterFunc = function(settings, data, dataIndex) {
|
470
|
-
var rowData = data.join(' ');
|
471
|
-
return regex.test(rowData);
|
472
|
-
};
|
473
|
-
} catch (e) {
|
474
|
-
filterFunc = function(settings, data, dataIndex) {
|
475
|
-
return true;
|
476
|
-
};
|
477
|
-
}
|
478
|
-
} else {
|
479
|
-
var positives = [];
|
480
|
-
var negatives = [];
|
481
|
-
var terms = search.split(/\\s+/).filter(function(t) { return t.length > 0; });
|
482
|
-
for (var i = 0; i < terms.length; i++) {
|
483
|
-
var term = terms[i];
|
484
|
-
if (term.startsWith('-')) {
|
485
|
-
var cleanTerm = term.substring(1).toLowerCase();
|
486
|
-
if (cleanTerm) negatives.push(cleanTerm);
|
487
|
-
} else {
|
488
|
-
positives.push(term.toLowerCase());
|
489
|
-
}
|
490
|
-
}
|
491
|
-
filterFunc = function(settings, data, dataIndex) {
|
492
|
-
var rowData = data.join(' ').toLowerCase();
|
493
|
-
for (var j = 0; j < positives.length; j++) {
|
494
|
-
if (!rowData.includes(positives[j])) return false;
|
495
|
-
}
|
496
|
-
for (var k = 0; k < negatives.length; k++) {
|
497
|
-
if (rowData.includes(negatives[k])) return false;
|
498
|
-
}
|
499
|
-
return true;
|
500
|
-
};
|
501
|
-
}
|
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
|
+
});
|
502
369
|
|
503
|
-
|
504
|
-
|
505
|
-
table
|
506
|
-
|
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();
|
507
377
|
});
|
508
378
|
|
509
379
|
// Toggle Columns
|
@@ -523,10 +393,12 @@ module PWN
|
|
523
393
|
|
524
394
|
// Select All and Deselect All
|
525
395
|
function select_deselect_all() {
|
526
|
-
|
527
|
-
|
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');
|
528
400
|
} else {
|
529
|
-
|
401
|
+
visible_multi_line_trs.filter(':not(.highlighted)').addClass('highlighted');
|
530
402
|
}
|
531
403
|
}
|
532
404
|
|
@@ -614,6 +486,8 @@ module PWN
|
|
614
486
|
test_case: row.security_references.sast_module.split('::')[2],
|
615
487
|
nist_800_53_security_control: row.security_references.nist_800_53_uri,
|
616
488
|
cwe: row.security_references.cwe_uri,
|
489
|
+
nist_section: row.security_references.section,
|
490
|
+
cwe_id: row.security_references.cwe_id,
|
617
491
|
path: row.filename.entry,
|
618
492
|
line_no: line.line_no,
|
619
493
|
contents: line.contents,
|
@@ -627,63 +501,70 @@ module PWN
|
|
627
501
|
var title = '~ pwn sast >>> ' + report_name + ' (Exported on ' + exportDate + ')';
|
628
502
|
|
629
503
|
if (type === 'xlsx') {
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
//
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
{
|
645
|
-
{
|
646
|
-
{
|
647
|
-
|
648
|
-
{wpx: 110},
|
649
|
-
{wpx: 40},
|
650
|
-
{wpx: 370},
|
651
|
-
{wpx: 370},
|
652
|
-
{wpx: 185}
|
653
|
-
];
|
654
|
-
|
655
|
-
// Style header row (row 2, since title at 1, header at 2, data from 3)
|
656
|
-
var headerStyle = {
|
657
|
-
font: { bold: true, color: { rgb: "000000" } },
|
658
|
-
fill: { fgColor: { rgb: "999999" } },
|
659
|
-
alignment: { horizontal: 'center', wrapText: true }
|
660
|
-
};
|
661
|
-
for (var col = 0; col < 9; col++) {
|
662
|
-
var cellRef = XLSX.utils.encode_cell({r:1, c:col}); // Row 2 (0-based)
|
663
|
-
if (ws[cellRef]) ws[cellRef].s = headerStyle;
|
664
|
-
}
|
504
|
+
const workbook = new ExcelJS.Workbook();
|
505
|
+
const worksheet = workbook.addWorksheet('PWN SAST Results');
|
506
|
+
|
507
|
+
// Add title row and merge
|
508
|
+
worksheet.mergeCells('A1:I1');
|
509
|
+
const titleCell = worksheet.getCell('A1');
|
510
|
+
titleCell.value = title;
|
511
|
+
titleCell.font = { size: 14, bold: true };
|
512
|
+
titleCell.alignment = { horizontal: 'center' };
|
513
|
+
|
514
|
+
// Add header row
|
515
|
+
worksheet.addRow(['Timestamp', 'Test Case', 'NIST 800-53', 'CWE', 'Path', 'Line#', 'Content', 'AI Analysis', 'Author']);
|
516
|
+
const headerRow = worksheet.getRow(2);
|
517
|
+
headerRow.eachCell((cell) => {
|
518
|
+
cell.font = { bold: true, color: { argb: 'FF000000' } };
|
519
|
+
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF999999' } };
|
520
|
+
cell.alignment = { horizontal: 'center', wrapText: true };
|
521
|
+
});
|
665
522
|
|
666
|
-
//
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
523
|
+
// Add data rows with alternating fills and hyperlinks
|
524
|
+
flatData.forEach((item, index) => {
|
525
|
+
const row = worksheet.addRow([
|
526
|
+
item.timestamp,
|
527
|
+
item.test_case,
|
528
|
+
{ text: item.nist_section, hyperlink: item.nist_800_53_security_control },
|
529
|
+
{ text: item.cwe_id, hyperlink: item.cwe },
|
530
|
+
item.path,
|
531
|
+
item.line_no,
|
532
|
+
item.contents,
|
533
|
+
item.ai_analysis,
|
534
|
+
item.author
|
535
|
+
]);
|
536
|
+
|
537
|
+
const fill = (index % 2 === 0)
|
538
|
+
? { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFDEDEDE' } }
|
539
|
+
: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFFFFF' } };
|
540
|
+
|
541
|
+
row.eachCell((cell) => {
|
542
|
+
cell.fill = fill;
|
543
|
+
cell.alignment = { wrapText: true, vertical: 'top', horizontal: 'left' };
|
544
|
+
});
|
545
|
+
});
|
680
546
|
|
681
|
-
//
|
682
|
-
|
547
|
+
// Set column widths (converted from pixels to character units approx.)
|
548
|
+
const pixelWidthsInches = [1.0, 2.0, 4.5, 0.5, 2.5, 0.75, 3.5, 3.5, 2];
|
549
|
+
worksheet.columns = pixelWidthsInches.map(inches => {
|
550
|
+
let width;
|
551
|
+
width = inches / 0.077
|
552
|
+
return { width: width };
|
553
|
+
});
|
683
554
|
|
684
|
-
|
685
|
-
|
686
|
-
|
555
|
+
// Freeze header
|
556
|
+
worksheet.views = [{ state: 'frozen', ySplit: 2 }];
|
557
|
+
|
558
|
+
// Generate and download the file
|
559
|
+
workbook.xlsx.writeBuffer().then(buffer => {
|
560
|
+
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
561
|
+
const url = URL.createObjectURL(blob);
|
562
|
+
const a = document.createElement('a');
|
563
|
+
a.href = url;
|
564
|
+
a.download = report_name + '.xlsx';
|
565
|
+
a.click();
|
566
|
+
URL.revokeObjectURL(url);
|
567
|
+
});
|
687
568
|
} else if (type === 'pdf') {
|
688
569
|
var docDefinition = {
|
689
570
|
pageOrientation: 'landscape',
|
@@ -716,8 +597,8 @@ module PWN
|
|
716
597
|
...flatData.map(r => [
|
717
598
|
r.timestamp,
|
718
599
|
r.test_case,
|
719
|
-
r.nist_800_53_security_control,
|
720
|
-
r.cwe,
|
600
|
+
{ text: r.nist_section, link: r.nist_800_53_security_control, style: {decoration: 'underline'} },
|
601
|
+
{ text: r.cwe_id, link: r.cwe, style: {decoration: 'underline'} },
|
721
602
|
r.path,
|
722
603
|
r.line_no,
|
723
604
|
r.contents,
|
@@ -761,7 +642,6 @@ module PWN
|
|
761
642
|
}
|
762
643
|
});
|
763
644
|
}
|
764
|
-
|
765
645
|
// Detect window size changes and recalculate/update scrollY
|
766
646
|
$(window).resize(function() {
|
767
647
|
var newWindowHeight = $(window).height();
|
@@ -773,7 +653,7 @@ module PWN
|
|
773
653
|
</script>
|
774
654
|
</body>
|
775
655
|
</html>
|
776
|
-
|
656
|
+
)
|
777
657
|
|
778
658
|
File.open("#{dir_path}/#{report_name}.html", 'w') do |f|
|
779
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"}]}
|
@@ -1053,9 +1053,7 @@
|
|
1053
1053
|
{"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
1054
|
{"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
1055
|
{"messages":[{"role":"user","content":"PWN::Reports::Phone.help Usage"},{"role":"assistant","content":"`PWN::Reports::Phone.help`: "}]}
|
1056
|
-
{"messages":[{"role":"user","content":"PWN::Reports::SAST.authors Usage"},{"role":"assistant","content":"`PWN::Reports::SAST.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
1057
1056
|
{"messages":[{"role":"user","content":"PWN::Reports::SAST.generate Usage"},{"role":"assistant","content":"`PWN::Reports::SAST.generate`: Supported Method Parameters\n\nPWN::Reports::SAST.generate(\n\ndir_path: 'optional - Directory path to save the report (defaults to .)',\nresults_hash: 'optional - Hash containing the results of the SAST analysis (defaults to empty hash structure)',\nreport_name: 'optional - Name of the report file (defaults to current directory name)',\nai_engine: 'optional - AI engine to use for analysis (:grok, :ollama, or :openai)',\nai_model: 'optionnal - AI Model to Use for Respective AI Engine (e.g., grok-4i-0709, chargpt-4o-latest, llama-3.1, etc.)',\nai_key: 'optional - AI Key/Token for Respective AI Engine',\nai_fqdn: 'optional - AI FQDN (Only Required for \"ollama\" AI Engine)',\nai_system_role_content: 'optional - AI System Role Content (Defaults to \"Is this code vulnerable or a false positive? Valid responses are only: \"VULNERABLE\" or \"FALSE+\". DO NOT PROVIDE ANY OTHER TEXT OR EXPLANATIONS.\")',\nai_temp: 'optional - AI Temperature (Defaults to 0.9)'\n\n)\n"}]}
|
1058
|
-
{"messages":[{"role":"user","content":"PWN::Reports::SAST.help Usage"},{"role":"assistant","content":"`PWN::Reports::SAST.help`: "}]}
|
1059
1057
|
{"messages":[{"role":"user","content":"PWN::Reports::URIBuster.authors Usage"},{"role":"assistant","content":"`PWN::Reports::URIBuster.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
1060
1058
|
{"messages":[{"role":"user","content":"PWN::Reports::URIBuster.generate Usage"},{"role":"assistant","content":"`PWN::Reports::URIBuster.generate`: Supported Method Parameters\n\nPWN::Reports::URIBuster.generate(\n\ndir_path: dir_path,\nresults_hash: results_hash\n\n)\n"}]}
|
1061
1059
|
{"messages":[{"role":"user","content":"PWN::Reports::URIBuster.help Usage"},{"role":"assistant","content":"`PWN::Reports::URIBuster.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.390
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
@@ -939,14 +939,14 @@ dependencies:
|
|
939
939
|
requirements:
|
940
940
|
- - '='
|
941
941
|
- !ruby/object:Gem::Version
|
942
|
-
version: 1.80.
|
942
|
+
version: 1.80.1
|
943
943
|
type: :runtime
|
944
944
|
prerelease: false
|
945
945
|
version_requirements: !ruby/object:Gem::Requirement
|
946
946
|
requirements:
|
947
947
|
- - '='
|
948
948
|
- !ruby/object:Gem::Version
|
949
|
-
version: 1.80.
|
949
|
+
version: 1.80.1
|
950
950
|
- !ruby/object:Gem::Dependency
|
951
951
|
name: rubocop-rake
|
952
952
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1900,6 +1900,7 @@ files:
|
|
1900
1900
|
- lib/pwn/plugins/xxd.rb
|
1901
1901
|
- lib/pwn/reports.rb
|
1902
1902
|
- lib/pwn/reports/fuzz.rb
|
1903
|
+
- lib/pwn/reports/html_header.rb
|
1903
1904
|
- lib/pwn/reports/phone.rb
|
1904
1905
|
- lib/pwn/reports/sast.rb
|
1905
1906
|
- lib/pwn/reports/uri_buster.rb
|
@@ -2242,6 +2243,7 @@ files:
|
|
2242
2243
|
- spec/lib/pwn/plugins/xxd_spec.rb
|
2243
2244
|
- spec/lib/pwn/plugins_spec.rb
|
2244
2245
|
- spec/lib/pwn/reports/fuzz_spec.rb
|
2246
|
+
- spec/lib/pwn/reports/html_header_spec.rb
|
2245
2247
|
- spec/lib/pwn/reports/phone_spec.rb
|
2246
2248
|
- spec/lib/pwn/reports/sast_spec.rb
|
2247
2249
|
- spec/lib/pwn/reports/uri_buster_spec.rb
|