pwn 0.5.164 → 0.5.165
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/README.md +3 -3
- data/bin/pwn +1 -1
- data/bin/pwn_android_war_dialer +2 -2
- data/bin/pwn_aws_describe_resources +2 -2
- data/bin/pwn_bdba_groups +2 -2
- data/bin/pwn_bdba_scan +2 -2
- data/bin/pwn_burp_suite_pro_active_scan +2 -2
- data/bin/pwn_char_base64_encoding +2 -2
- data/bin/pwn_char_dec_encoding +2 -2
- data/bin/pwn_char_hex_escaped_encoding +2 -2
- data/bin/pwn_char_html_entity_encoding +2 -2
- data/bin/pwn_char_unicode_escaped_encoding +2 -2
- data/bin/pwn_char_url_encoding +2 -2
- data/bin/pwn_crt_sh +82 -0
- data/bin/pwn_defectdojo_engagement_create +2 -2
- data/bin/pwn_defectdojo_importscan +2 -2
- data/bin/pwn_defectdojo_reimportscan +2 -2
- data/bin/pwn_diff_csv_files_w_column_exclude +4 -4
- data/bin/pwn_domain_reversewhois +2 -2
- data/bin/pwn_fuzz_net_app_proto +3 -3
- data/bin/pwn_gqrx_scanner +2 -2
- data/bin/pwn_jenkins_create_job +2 -2
- data/bin/pwn_jenkins_create_view +2 -2
- data/bin/pwn_jenkins_install_plugin +2 -2
- data/bin/pwn_jenkins_thinBackup_aws_s3 +2 -2
- data/bin/pwn_jenkins_update_plugins +2 -2
- data/bin/pwn_jenkins_useradd +2 -2
- data/bin/pwn_mail_agent +2 -2
- data/bin/pwn_nessus_cloud_scan_crud +2 -2
- data/bin/pwn_nessus_cloud_vulnscan +2 -2
- data/bin/pwn_nexpose +2 -2
- data/bin/pwn_nmap_discover_tcp_udp +2 -2
- data/bin/pwn_openvas_vulnscan +2 -2
- data/bin/pwn_owasp_zap_active_scan +2 -2
- data/bin/pwn_pastebin_sample_filter +2 -2
- data/bin/pwn_phone +3 -3
- data/bin/pwn_sast +3 -3
- data/bin/pwn_serial_check_voicemail +2 -2
- data/bin/pwn_serial_msr206 +2 -2
- data/bin/pwn_serial_son_micro_sm132_rfid +2 -2
- data/bin/pwn_shodan_graphql_introspection +1 -1
- data/bin/pwn_shodan_search +2 -2
- data/bin/pwn_simple_http_server +1 -1
- data/bin/pwn_web_cache_deception +4 -4
- data/bin/pwn_www_checkip +3 -1
- data/bin/pwn_www_uri_buster +141 -57
- data/bin/pwn_xss_dom_vectors +2 -2
- data/lib/pwn/plugins/authentication_helper.rb +2 -2
- data/lib/pwn/plugins/ip_info.rb +2 -0
- data/lib/pwn/plugins/log.rb +3 -1
- data/lib/pwn/plugins/repl.rb +3 -1
- data/lib/pwn/plugins/thread_pool.rb +12 -42
- data/lib/pwn/plugins/tor.rb +51 -12
- data/lib/pwn/plugins/transparent_browser.rb +3 -0
- data/lib/pwn/plugins/voice.rb +3 -3
- data/lib/pwn/reports/uri_buster.rb +18 -6
- data/lib/pwn/version.rb +1 -1
- metadata +8 -6
@@ -8,7 +8,7 @@ require 'yaml'
|
|
8
8
|
opts = {}
|
9
9
|
OptionParser.new do |options|
|
10
10
|
options.banner = "USAGE:
|
11
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
12
12
|
"
|
13
13
|
|
14
14
|
options.on('-cYPATH', '--yaml-config=YPATH', '<Required - YAML Config Containing Access & Secret Keys for Authentication>') do |c|
|
@@ -29,7 +29,7 @@ OptionParser.new do |options|
|
|
29
29
|
end.parse!
|
30
30
|
|
31
31
|
if opts.empty?
|
32
|
-
puts `#{$PROGRAM_NAME} --help`
|
32
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
33
33
|
exit 1
|
34
34
|
end
|
35
35
|
|
data/bin/pwn_nexpose
CHANGED
@@ -7,7 +7,7 @@ require 'optparse'
|
|
7
7
|
opts = {}
|
8
8
|
OptionParser.new do |options|
|
9
9
|
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
10
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
13
|
# Nexpose Flags
|
@@ -19,7 +19,7 @@ OptionParser.new do |options|
|
|
19
19
|
end.parse!
|
20
20
|
|
21
21
|
if opts.empty?
|
22
|
-
puts `#{$PROGRAM_NAME} --help`
|
22
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
23
23
|
exit 1
|
24
24
|
end
|
25
25
|
|
@@ -9,7 +9,7 @@ require 'time'
|
|
9
9
|
opts = {}
|
10
10
|
OptionParser.new do |options|
|
11
11
|
options.banner = "USAGE:
|
12
|
-
#{$PROGRAM_NAME} [opts]
|
12
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
13
13
|
"
|
14
14
|
|
15
15
|
options.on('-fFILE', '--target-file=FILE', '<Required if --target-range excluded - File containing one supported nmap target / line e.g. foo.bar, 10.1.1.1, 192.168.1.1-20, 192.168.1.0/24, etc>') do |f|
|
@@ -42,7 +42,7 @@ OptionParser.new do |options|
|
|
42
42
|
end.parse!
|
43
43
|
|
44
44
|
if opts.empty?
|
45
|
-
puts `#{$PROGRAM_NAME} --help`
|
45
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
46
46
|
exit 1
|
47
47
|
end
|
48
48
|
|
data/bin/pwn_openvas_vulnscan
CHANGED
@@ -8,7 +8,7 @@ require 'yaml'
|
|
8
8
|
opts = {}
|
9
9
|
OptionParser.new do |options|
|
10
10
|
options.banner = "USAGE:
|
11
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
12
12
|
"
|
13
13
|
|
14
14
|
options.on('-cYPATH', '--yaml-config=YPATH', '<Required - YAML Config Containing Username & Password for Authentication>') do |c|
|
@@ -29,7 +29,7 @@ OptionParser.new do |options|
|
|
29
29
|
end.parse!
|
30
30
|
|
31
31
|
if opts.empty?
|
32
|
-
puts `#{$PROGRAM_NAME} --help`
|
32
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
33
33
|
exit 1
|
34
34
|
end
|
35
35
|
|
@@ -7,7 +7,7 @@ require 'optparse'
|
|
7
7
|
opts = {}
|
8
8
|
OptionParser.new do |options|
|
9
9
|
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
10
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
13
|
options.on('-aAPIKEY', '--api_key=APIKEY', '<Required - OWASP Zap API Key (Tools>Options>API)>') do |a|
|
@@ -44,7 +44,7 @@ OptionParser.new do |options|
|
|
44
44
|
end.parse!
|
45
45
|
|
46
46
|
if opts.empty?
|
47
|
-
puts `#{$PROGRAM_NAME} --help`
|
47
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
48
48
|
exit 1
|
49
49
|
end
|
50
50
|
|
@@ -7,7 +7,7 @@ require 'optparse'
|
|
7
7
|
opts = {}
|
8
8
|
OptionParser.new do |options|
|
9
9
|
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
10
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
13
|
options.on('-rPATTERN', '--regex=PATTERN', "<Required - Regex Pattern for Interesting Pastes ('.*' for All)>") do |r|
|
@@ -20,7 +20,7 @@ OptionParser.new do |options|
|
|
20
20
|
end.parse!
|
21
21
|
|
22
22
|
if opts.empty?
|
23
|
-
puts `#{$PROGRAM_NAME} --help`
|
23
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
24
24
|
exit 1
|
25
25
|
end
|
26
26
|
|
data/bin/pwn_phone
CHANGED
@@ -11,7 +11,7 @@ require 'waveform'
|
|
11
11
|
opts = {}
|
12
12
|
OptionParser.new do |options|
|
13
13
|
options.banner = "USAGE:
|
14
|
-
#{$PROGRAM_NAME} [opts]
|
14
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
15
15
|
"
|
16
16
|
|
17
17
|
options.on('-tPATH', '--target-file=PATH', '<Required - File Containing List of Targets to Dial>') do |t|
|
@@ -64,7 +64,7 @@ OptionParser.new do |options|
|
|
64
64
|
end.parse!
|
65
65
|
|
66
66
|
if opts.empty?
|
67
|
-
puts `#{$PROGRAM_NAME} --help`
|
67
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
68
68
|
exit 1
|
69
69
|
end
|
70
70
|
|
@@ -105,7 +105,7 @@ begin
|
|
105
105
|
)
|
106
106
|
|
107
107
|
# Generate HTML Report
|
108
|
-
print "#{$PROGRAM_NAME} Generating Report..."
|
108
|
+
print "#{File.basename($PROGRAM_NAME)} Generating Report..."
|
109
109
|
PWN::Reports::Phone.generate(
|
110
110
|
dir_path: session_root,
|
111
111
|
results_hash: results_hash
|
data/bin/pwn_sast
CHANGED
@@ -8,7 +8,7 @@ require 'htmlentities'
|
|
8
8
|
opts = {}
|
9
9
|
OptionParser.new do |options|
|
10
10
|
options.banner = "USAGE:
|
11
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
12
12
|
"
|
13
13
|
|
14
14
|
options.on('-uGITURI', '--uri-source-root=GITURI', '<Required - HTTP URI of Git Repo Scanned e.g. https://github.com/0dayInc/pwn/tree/master>') do |u|
|
@@ -41,7 +41,7 @@ OptionParser.new do |options|
|
|
41
41
|
end.parse!
|
42
42
|
|
43
43
|
if opts.empty?
|
44
|
-
puts `#{$PROGRAM_NAME} --help`
|
44
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
45
45
|
exit 1
|
46
46
|
end
|
47
47
|
|
@@ -155,7 +155,7 @@ begin
|
|
155
155
|
end
|
156
156
|
|
157
157
|
# Generate HTML Report
|
158
|
-
print "#{$PROGRAM_NAME} Generating Report..."
|
158
|
+
print "#{File.basename($PROGRAM_NAME)} Generating Report..."
|
159
159
|
PWN::Reports::SAST.generate(
|
160
160
|
dir_path: dir_path,
|
161
161
|
results_hash: results_hash
|
@@ -7,7 +7,7 @@ require 'optparse'
|
|
7
7
|
opts = {}
|
8
8
|
OptionParser.new do |options|
|
9
9
|
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
10
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
13
|
options.on('-vNUM', '--voicemail_num=num', '<Required - Number to Voicemail Service>') do |num|
|
@@ -19,7 +19,7 @@ OptionParser.new do |options|
|
|
19
19
|
end.parse!
|
20
20
|
|
21
21
|
if opts.empty?
|
22
|
-
puts `#{$PROGRAM_NAME} --help`
|
22
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
23
23
|
exit 1
|
24
24
|
end
|
25
25
|
|
data/bin/pwn_serial_msr206
CHANGED
@@ -8,7 +8,7 @@ require 'json'
|
|
8
8
|
opts = {}
|
9
9
|
OptionParser.new do |options|
|
10
10
|
options.banner = "USAGE:
|
11
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
12
12
|
"
|
13
13
|
|
14
14
|
options.on('-dDEV', '--block-dev=DEV', '<Optional - MSR206 block device path (defaults to /dev/ttyUSB0)>') do |d|
|
@@ -37,7 +37,7 @@ OptionParser.new do |options|
|
|
37
37
|
end.parse!
|
38
38
|
|
39
39
|
if opts.empty?
|
40
|
-
puts `#{$PROGRAM_NAME} --help`
|
40
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
41
41
|
exit 1
|
42
42
|
end
|
43
43
|
|
@@ -8,7 +8,7 @@ require 'json'
|
|
8
8
|
opts = {}
|
9
9
|
OptionParser.new do |options|
|
10
10
|
options.banner = "USAGE:
|
11
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
12
12
|
"
|
13
13
|
|
14
14
|
options.on('-dDEV', '--block-dev=DEV', '<Optional - SonMicroRFID block device path (defaults to /dev/ttyUSB0)>') do |d|
|
@@ -37,7 +37,7 @@ OptionParser.new do |options|
|
|
37
37
|
end.parse!
|
38
38
|
|
39
39
|
if opts.empty?
|
40
|
-
puts `#{$PROGRAM_NAME} --help`
|
40
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
41
41
|
exit 1
|
42
42
|
end
|
43
43
|
|
data/bin/pwn_shodan_search
CHANGED
@@ -9,7 +9,7 @@ require 'json'
|
|
9
9
|
opts = {}
|
10
10
|
OptionParser.new do |options|
|
11
11
|
options.banner = "USAGE:
|
12
|
-
#{$PROGRAM_NAME} [opts]
|
12
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
13
13
|
"
|
14
14
|
|
15
15
|
options.on('-cYAML', '--config-yaml=YAML', '<Required - YAML config containing api_key from Shodan.io>') do |y|
|
@@ -30,7 +30,7 @@ OptionParser.new do |options|
|
|
30
30
|
end.parse!
|
31
31
|
|
32
32
|
if opts.empty?
|
33
|
-
puts `#{$PROGRAM_NAME} --help`
|
33
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
34
34
|
exit 1
|
35
35
|
end
|
36
36
|
|
data/bin/pwn_simple_http_server
CHANGED
@@ -6,7 +6,7 @@ require 'optparse'
|
|
6
6
|
opts = {}
|
7
7
|
OptionParser.new do |options|
|
8
8
|
options.banner = "USAGE:
|
9
|
-
#{$PROGRAM_NAME} [opts]
|
9
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
10
10
|
"
|
11
11
|
options.on('-iIP', '--bind-ip=IP', '<Optional - HTTP Bind IP to Listen> (Defaults to Localhost)') do |i|
|
12
12
|
opts[:bind_ip] = i
|
data/bin/pwn_web_cache_deception
CHANGED
@@ -7,7 +7,7 @@ require 'optparse'
|
|
7
7
|
opts = {}
|
8
8
|
OptionParser.new do |options|
|
9
9
|
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
10
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
13
|
options.on('-tURL', '--target-url=URL', '<Required - URL to Target>') do |t|
|
@@ -44,7 +44,7 @@ OptionParser.new do |options|
|
|
44
44
|
end.parse!
|
45
45
|
|
46
46
|
if opts.empty?
|
47
|
-
puts `#{$PROGRAM_NAME} --help`
|
47
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
48
48
|
exit 1
|
49
49
|
end
|
50
50
|
|
@@ -142,12 +142,12 @@ begin
|
|
142
142
|
pwn_www_mod = PWN::WWW.const_get(pwn_www_mod_str)
|
143
143
|
unless pwn_www_mod.respond_to?('open') && pwn_www_mod.respond_to?('login') && pwn_www_mod.respond_to?('logout')
|
144
144
|
puts "#{@dark_red}Module PWN::WWW::#{pwn_www_mod_str} Missing #open #login and/or #logout Method(s)#{@end_of_color}"
|
145
|
-
puts `#{$PROGRAM_NAME} -l`
|
145
|
+
puts `#{File.basename($PROGRAM_NAME)} -l`
|
146
146
|
exit
|
147
147
|
end
|
148
148
|
rescue NAME_ERROR => e
|
149
149
|
puts "#{@dark_red}Invalid module PWN::WWW::#{pwn_www_mod_str}#{@end_of_color}"
|
150
|
-
puts `#{$PROGRAM_NAME} -l`
|
150
|
+
puts `#{File.basename($PROGRAM_NAME)} -l`
|
151
151
|
exit
|
152
152
|
end
|
153
153
|
|
data/bin/pwn_www_checkip
CHANGED
@@ -8,7 +8,7 @@ require 'optparse'
|
|
8
8
|
opts = {}
|
9
9
|
OptionParser.new do |options|
|
10
10
|
options.banner = "USAGE:
|
11
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
12
12
|
"
|
13
13
|
options.on('-tIP_HOST', '--target=IP_HOST', '<Optional - IP or Host to Check (Default - Your Public IP)>') do |t|
|
14
14
|
opts[:target] = t
|
@@ -64,6 +64,8 @@ begin
|
|
64
64
|
)
|
65
65
|
puts JSON.pretty_generate(ip_info_obj)
|
66
66
|
end
|
67
|
+
rescue Interrupt
|
68
|
+
puts "\n#{File.basename($PROGRAM_NAME)} => Goodbye."
|
67
69
|
rescue StandardError => e
|
68
70
|
raise e
|
69
71
|
ensure
|
data/bin/pwn_www_uri_buster
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: false
|
3
3
|
|
4
|
+
require 'time'
|
4
5
|
require 'pwn'
|
5
6
|
require 'optparse'
|
6
7
|
require 'uri'
|
@@ -12,7 +13,7 @@ require 'json'
|
|
12
13
|
opts = {}
|
13
14
|
OptionParser.new do |options|
|
14
15
|
options.banner = "USAGE:
|
15
|
-
#{$PROGRAM_NAME} [opts]
|
16
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
16
17
|
"
|
17
18
|
|
18
19
|
options.on('-uURL', '--target-url=URL', '<Required - Target URL)>') do |t|
|
@@ -27,6 +28,14 @@ OptionParser.new do |options|
|
|
27
28
|
opts[:append_pattern] = a
|
28
29
|
end
|
29
30
|
|
31
|
+
options.on('-TFLOAT', '--max-timeout=FLOAT', '<Optional - HTTP Request Timeout (Default 6.0 Seconds)>') do |t|
|
32
|
+
opts[:max_timeout] = t
|
33
|
+
end
|
34
|
+
|
35
|
+
options.on('-TFLOAT', '--max-retries=FLOAT', '<Optional - HTTP Request Retries (Default 3)>') do |r|
|
36
|
+
opts[:max_retries] = r
|
37
|
+
end
|
38
|
+
|
30
39
|
options.on('-pPROXY', '--proxy=PROXY', '<Optional - Proxy SCHEME://ADDRESS:PORT || tor>') do |p|
|
31
40
|
opts[:proxy] = p
|
32
41
|
end
|
@@ -61,7 +70,7 @@ OptionParser.new do |options|
|
|
61
70
|
end.parse!
|
62
71
|
|
63
72
|
if opts.empty?
|
64
|
-
puts `#{$PROGRAM_NAME} --help`
|
73
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
65
74
|
exit 1
|
66
75
|
end
|
67
76
|
|
@@ -71,43 +80,60 @@ def request_path(opts = {})
|
|
71
80
|
http_request_headers = opts[:http_request_headers]
|
72
81
|
wordlist_line = opts[:wordlist_line]
|
73
82
|
http_method = opts[:http_method]
|
83
|
+
max_timeout = opts[:max_timeout]
|
84
|
+
timeout = opts[:max_timeout] ||= max_timeout / 21.0
|
85
|
+
max_retries = opts[:max_retries]
|
74
86
|
|
75
87
|
rest_client_resp_hash = {}
|
76
|
-
begin
|
77
|
-
print '.'
|
78
|
-
http_uri = "#{target_url}/#{wordlist_line}"
|
79
|
-
if proxy
|
80
|
-
browser_obj = PWN::Plugins::TransparentBrowser.open(
|
81
|
-
browser_type: :rest,
|
82
|
-
proxy: proxy
|
83
|
-
)
|
84
|
-
else
|
85
|
-
browser_obj = PWN::Plugins::TransparentBrowser.open(
|
86
|
-
browser_type: :rest
|
87
|
-
)
|
88
|
-
end
|
89
|
-
rest_client = browser_obj[:browser]::Request
|
90
88
|
|
91
|
-
|
92
|
-
|
93
|
-
}
|
89
|
+
# request_count && timeout values to begin with
|
90
|
+
request_count = 1
|
94
91
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
92
|
+
if proxy
|
93
|
+
browser_obj = PWN::Plugins::TransparentBrowser.open(
|
94
|
+
browser_type: :rest,
|
95
|
+
proxy: proxy
|
96
|
+
)
|
97
|
+
else
|
98
|
+
browser_obj = PWN::Plugins::TransparentBrowser.open(
|
99
|
+
browser_type: :rest
|
100
|
+
)
|
101
|
+
end
|
102
|
+
rest_client = browser_obj[:browser]::Request
|
103
|
+
|
104
|
+
headers = {
|
105
|
+
user_agent: Faker::Internet.user_agent
|
106
|
+
}
|
107
|
+
|
108
|
+
http_uri = "#{target_url}/#{wordlist_line}"
|
109
|
+
|
110
|
+
if http_request_headers
|
111
|
+
headers = JSON.parse(
|
112
|
+
http_request_headers,
|
113
|
+
symbolize_names: true
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
timestamp_fmt = '%Y-%m-%d %H:%M:%S.%L'
|
101
118
|
|
119
|
+
begin
|
120
|
+
request_timestamp = Time.now.strftime(timestamp_fmt)
|
102
121
|
response = rest_client.execute(
|
103
122
|
method: http_method,
|
104
123
|
url: http_uri,
|
105
124
|
headers: headers,
|
106
|
-
verify_ssl: false
|
125
|
+
verify_ssl: false,
|
126
|
+
timeout: timeout
|
107
127
|
)
|
128
|
+
response_timestamp = Time.now.strftime(timestamp_fmt)
|
129
|
+
|
130
|
+
# duration in milliseconds
|
131
|
+
duration = Time.parse(response_timestamp) - Time.parse(request_timestamp)
|
108
132
|
|
109
133
|
rest_client_resp_hash = {
|
110
|
-
request_timestamp:
|
134
|
+
request_timestamp: request_timestamp,
|
135
|
+
response_timestamp: response_timestamp,
|
136
|
+
duration: duration,
|
111
137
|
http_uri: http_uri,
|
112
138
|
http_method: http_method,
|
113
139
|
http_resp_code: response.code,
|
@@ -115,9 +141,8 @@ def request_path(opts = {})
|
|
115
141
|
http_resp_headers: JSON.pretty_generate(response.headers),
|
116
142
|
http_resp: "#{response.body[0..300]}..."
|
117
143
|
}
|
118
|
-
rescue Errno::ECONNREFUSED
|
119
|
-
|
120
|
-
rescue Errno::ECONNRESET,
|
144
|
+
rescue Errno::ECONNREFUSED,
|
145
|
+
Errno::ECONNRESET,
|
121
146
|
NoMethodError,
|
122
147
|
OpenSSL::SSL::SSLError,
|
123
148
|
RestClient::Exceptions::ReadTimeout,
|
@@ -125,9 +150,16 @@ def request_path(opts = {})
|
|
125
150
|
RestClient::ServerBrokeConnection,
|
126
151
|
SOCKSError => e
|
127
152
|
|
153
|
+
timeout += 0.1
|
154
|
+
retry if timeout < max_timeout
|
155
|
+
|
128
156
|
# May be best to switch Tor channel if SOCKSError is rescued
|
157
|
+
response_timestamp = Time.now.strftime(timestamp_fmt)
|
158
|
+
duration = Time.parse(response_timestamp) - Time.parse(request_timestamp)
|
129
159
|
rest_client_resp_hash = {
|
130
|
-
request_timestamp:
|
160
|
+
request_timestamp: request_timestamp,
|
161
|
+
response_timestamp: response_timestamp,
|
162
|
+
duration: duration,
|
131
163
|
http_uri: http_uri,
|
132
164
|
http_method: http_method,
|
133
165
|
http_resp_code: e.class,
|
@@ -136,9 +168,14 @@ def request_path(opts = {})
|
|
136
168
|
http_resp: "ERROR: #{e.message}"
|
137
169
|
}
|
138
170
|
rescue RestClient::ExceptionWithResponse => e
|
171
|
+
response_timestamp = Time.now.strftime(timestamp_fmt)
|
172
|
+
duration = Time.parse(response_timestamp) - Time.parse(request_timestamp)
|
173
|
+
|
139
174
|
if e.respond_to?(:response)
|
140
175
|
rest_client_resp_hash = {
|
141
|
-
request_timestamp:
|
176
|
+
request_timestamp: request_timestamp,
|
177
|
+
response_timestamp: response_timestamp,
|
178
|
+
duration: duration,
|
142
179
|
http_uri: http_uri,
|
143
180
|
http_method: http_method,
|
144
181
|
http_resp_code: e.response.code,
|
@@ -148,7 +185,9 @@ def request_path(opts = {})
|
|
148
185
|
}
|
149
186
|
else
|
150
187
|
resp_client_resp_hash = {
|
151
|
-
request_timestamp:
|
188
|
+
request_timestamp: request_timestamp,
|
189
|
+
response_timestamp: response_timestamp,
|
190
|
+
duration: duration,
|
152
191
|
http_uri: http_uri,
|
153
192
|
http_method: http_method,
|
154
193
|
http_resp_code: 'N/A',
|
@@ -163,17 +202,20 @@ def request_path(opts = {})
|
|
163
202
|
url_encoded_wordlist_arr.push(CGI.escape(path))
|
164
203
|
end
|
165
204
|
wordlist_line = url_encoded_wordlist_arr.join('/')
|
166
|
-
|
167
|
-
retry
|
168
205
|
rescue RestClient::TooManyRequests
|
206
|
+
request_count += 1
|
169
207
|
sleep 60
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
)
|
208
|
+
|
209
|
+
retry if request_count < max_retries
|
210
|
+
rescue SystemExit, Interrupt
|
211
|
+
puts "\n#{File.basename($PROGRAM_NAME)}.#{__method__} Goodbye."
|
174
212
|
end
|
175
213
|
|
176
214
|
rest_client_resp_hash
|
215
|
+
ensure
|
216
|
+
browser_obj = PWN::Plugins::TransparentBrowser.close(
|
217
|
+
browser_obj: browser_obj
|
218
|
+
)
|
177
219
|
end
|
178
220
|
|
179
221
|
begin
|
@@ -189,18 +231,31 @@ begin
|
|
189
231
|
raise "ERROR: #{wordlist} Does Not Exist." unless File.exist?(wordlist)
|
190
232
|
|
191
233
|
append_pattern = opts[:append_pattern]
|
192
|
-
|
234
|
+
max_timeout = opts[:max_timeout] ||= 6
|
235
|
+
if max_timeout
|
236
|
+
max_timeout = max_timeout.to_f
|
237
|
+
raise 'ERROR: --max-timeout must be a positive float.' unless max_timeout.positive?
|
238
|
+
end
|
193
239
|
|
194
|
-
|
195
|
-
|
240
|
+
max_retries = opts[:max_retries] ||= 3
|
241
|
+
if max_retries
|
242
|
+
max_retries = max_retries.to_i
|
243
|
+
raise 'ERROR: --max-retries must be a positive integer.' unless max_retries.positive?
|
244
|
+
end
|
196
245
|
|
197
|
-
|
246
|
+
proxy = opts[:proxy]
|
247
|
+
max_threads = opts[:max_threads] ||= 25
|
248
|
+
if max_threads
|
249
|
+
max_threads = max_threads.to_i
|
250
|
+
raise 'ERROR: --max-threads must be a positive integer.' unless max_threads.positive?
|
251
|
+
end
|
198
252
|
|
253
|
+
http_request_headers = opts[:http_request_headers]
|
199
254
|
include_http_response_codes = opts[:include_http_response_codes]
|
200
|
-
include_http_response_codes = include_http_response_codes.delete("\s").split(',') if include_http_response_codes
|
255
|
+
include_http_response_codes = include_http_response_codes.to_s.delete("\s").split(',') if include_http_response_codes
|
201
256
|
|
202
257
|
exclude_http_response_codes = opts[:exclude_http_response_codes]
|
203
|
-
exclude_http_response_codes = exclude_http_response_codes.delete("\s").split(',') if exclude_http_response_codes
|
258
|
+
exclude_http_response_codes = exclude_http_response_codes.to_s.delete("\s").split(',') if exclude_http_response_codes
|
204
259
|
|
205
260
|
raise 'ERROR: Flags --include-response-codes and --exclude-response-codes cannot be used together.' if include_http_response_codes && exclude_http_response_codes
|
206
261
|
|
@@ -230,33 +285,60 @@ begin
|
|
230
285
|
|
231
286
|
next if wordlist_line.match?(/^#/)
|
232
287
|
|
233
|
-
http_methods = %i[
|
288
|
+
http_methods = %i[
|
289
|
+
DELETE
|
290
|
+
GET
|
291
|
+
HEAD
|
292
|
+
OPTIONS
|
293
|
+
PATCH
|
294
|
+
POST
|
295
|
+
PUT
|
296
|
+
TRACE
|
297
|
+
].shuffle
|
298
|
+
|
299
|
+
timeout = nil
|
234
300
|
http_methods.each do |http_method|
|
235
301
|
# TODO: Implement HTTP response timeout
|
302
|
+
prev_rest_client_resp_hash = results_hash[:data].last
|
236
303
|
rest_client_resp_hash = request_path(
|
237
304
|
target_url: target_url,
|
238
305
|
proxy: proxy,
|
239
306
|
http_request_headers: http_request_headers,
|
240
307
|
wordlist_line: "#{wordlist_line}#{append_pattern}",
|
241
|
-
http_method: http_method
|
308
|
+
http_method: http_method,
|
309
|
+
max_timeout: max_timeout,
|
310
|
+
timeout: timeout,
|
311
|
+
max_retries: max_retries
|
242
312
|
)
|
243
313
|
|
244
314
|
mutex.synchronize do
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
315
|
+
ret_http_resp_code = rest_client_resp_hash[:http_resp_code].to_s
|
316
|
+
# Better waY to implement this?
|
317
|
+
if include_http_response_codes.is_a?(Array)
|
318
|
+
# If include_http_response_codes is an array, only include
|
319
|
+
# the response into the results_hash if the response code
|
320
|
+
# is in the include_http_response_codes array
|
321
|
+
results_hash[:data].push(rest_client_resp_hash) if include_http_response_codes.include?(ret_http_resp_code) &&
|
322
|
+
prev_rest_client_resp_hash != rest_client_resp_hash &&
|
323
|
+
rest_client_resp_hash.any?
|
251
324
|
else
|
252
|
-
|
325
|
+
# If exclude_http_response_codes is an array, only include
|
326
|
+
# the response into the results_hash if the response code
|
327
|
+
# is not in the exclude_http_response_codes array
|
328
|
+
results_hash[:data].push(rest_client_resp_hash) unless exclude_http_response_codes.is_a?(Array) &&
|
329
|
+
exclude_http_response_codes.include?(ret_http_resp_code) &&
|
330
|
+
prev_rest_client_resp_hash != rest_client_resp_hash &&
|
331
|
+
rest_client_resp_hash.any?
|
253
332
|
end
|
333
|
+
# Finally puts the last line of the results_hash to STDOUT
|
334
|
+
puts results_hash[:data].last if results_hash[:data].last.any?
|
335
|
+
timeout = results_hash[:data].last[:duration].to_f if results_hash[:data].last.any?
|
254
336
|
end
|
255
337
|
end
|
256
338
|
end
|
257
339
|
|
258
340
|
# Generate HTML Report
|
259
|
-
print "#{$PROGRAM_NAME} Generating Report..."
|
341
|
+
print "#{File.basename($PROGRAM_NAME)} Generating Report..."
|
260
342
|
PWN::Reports::URIBuster.generate(
|
261
343
|
dir_path: dir_path,
|
262
344
|
results_hash: results_hash
|
@@ -283,8 +365,10 @@ begin
|
|
283
365
|
listen_port
|
284
366
|
)
|
285
367
|
end
|
286
|
-
rescue SystemExit, Interrupt
|
287
|
-
|
368
|
+
# rescue SystemExit, Interrupt
|
369
|
+
# puts "\nGoodbye."
|
370
|
+
rescue Interrupt
|
371
|
+
puts "\n#{File.basename($PROGRAM_NAME)} Goodbye."
|
288
372
|
rescue StandardError => e
|
289
373
|
puts e.backtrace
|
290
374
|
raise e
|
data/bin/pwn_xss_dom_vectors
CHANGED
@@ -7,7 +7,7 @@ require 'optparse'
|
|
7
7
|
opts = {}
|
8
8
|
OptionParser.new do |options|
|
9
9
|
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
10
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
13
|
options.on('-tFQDN', '--target-fqdn=FQDN', '<Required - FQDN to Target>') do |t|
|
@@ -36,7 +36,7 @@ OptionParser.new do |options|
|
|
36
36
|
end.parse!
|
37
37
|
|
38
38
|
if opts.empty?
|
39
|
-
puts `#{$PROGRAM_NAME} --help`
|
39
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
40
40
|
exit 1
|
41
41
|
end
|
42
42
|
|
@@ -30,7 +30,7 @@ module PWN
|
|
30
30
|
pass = TTY::Prompt.new.mask("#{prompt}: ")
|
31
31
|
pass.to_s.strip.chomp.scrub
|
32
32
|
rescue Interrupt
|
33
|
-
puts
|
33
|
+
puts "#{self}.#{__method__} => Goodbye."
|
34
34
|
rescue StandardError => e
|
35
35
|
raise e
|
36
36
|
end
|
@@ -46,7 +46,7 @@ module PWN
|
|
46
46
|
mfa = TTY::Prompt.new.ask("#{prompt}: ")
|
47
47
|
mfa.to_s.strip.chomp.scrub
|
48
48
|
rescue Interrupt
|
49
|
-
puts
|
49
|
+
puts "#{self}.#{__method__} => Goodbye."
|
50
50
|
rescue StandardError => e
|
51
51
|
raise e
|
52
52
|
end
|