pwn 0.5.164 → 0.5.166
Sign up to get free protection for your applications and to get access to all the features.
- 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 +83 -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
|