pwn 0.4.700 → 0.4.702
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG_BETWEEN_TAGS.txt +492 -108
- data/README.md +2 -2
- data/bin/pwn_burp_suite_pro_active_scan +2 -1
- data/bin/pwn_domain_reversewhois +8 -7
- data/bin/pwn_owasp_zap_active_scan +3 -2
- data/bin/pwn_pastebin_sample_filter +6 -4
- data/bin/pwn_web_cache_deception +11 -8
- data/bin/pwn_www_checkip +6 -5
- data/bin/pwn_www_uri_buster +5 -4
- data/bin/pwn_xss_dom_vectors +12 -9
- data/lib/pwn/plugins/baresip.rb +3 -2
- data/lib/pwn/plugins/beef.rb +5 -2
- data/lib/pwn/plugins/burp_suite.rb +7 -5
- data/lib/pwn/plugins/defect_dojo.rb +5 -3
- data/lib/pwn/plugins/github.rb +2 -1
- data/lib/pwn/plugins/hacker_one.rb +4 -2
- data/lib/pwn/plugins/ibm_appscan.rb +13 -6
- data/lib/pwn/plugins/ip_info.rb +4 -2
- data/lib/pwn/plugins/jira_server.rb +2 -1
- data/lib/pwn/plugins/nessus_cloud.rb +2 -1
- data/lib/pwn/plugins/open_ai.rb +3 -1
- data/lib/pwn/plugins/owasp_zap.rb +2 -1
- data/lib/pwn/plugins/shodan.rb +2 -1
- data/lib/pwn/plugins/transparent_browser.rb +26 -36
- data/lib/pwn/plugins/twitter_api.rb +5 -2
- data/lib/pwn/plugins/vsphere.rb +1 -2
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn/www/app_cobalt_io.rb +19 -13
- data/lib/pwn/www/bing.rb +9 -6
- data/lib/pwn/www/bug_crowd.rb +19 -13
- data/lib/pwn/www/checkip.rb +7 -5
- data/lib/pwn/www/coinbase_pro.rb +18 -12
- data/lib/pwn/www/duckduckgo.rb +15 -8
- data/lib/pwn/www/facebook.rb +16 -10
- data/lib/pwn/www/google.rb +12 -8
- data/lib/pwn/www/hacker_one.rb +16 -10
- data/lib/pwn/www/linkedin.rb +16 -10
- data/lib/pwn/www/pandora.rb +16 -10
- data/lib/pwn/www/pastebin.rb +9 -5
- data/lib/pwn/www/paypal.rb +36 -28
- data/lib/pwn/www/synack.rb +19 -13
- data/lib/pwn/www/torch.rb +12 -7
- data/lib/pwn/www/trading_view.rb +19 -13
- data/lib/pwn/www/twitter.rb +20 -12
- data/lib/pwn/www/uber.rb +16 -10
- data/lib/pwn/www/upwork.rb +16 -10
- data/lib/pwn/www/youtube.rb +9 -6
- metadata +2 -6
- data/bin/pwn_arachni +0 -157
- data/bin/pwn_arachni_rest +0 -174
data/lib/pwn/www/twitter.rb
CHANGED
@@ -9,13 +9,14 @@ module PWN
|
|
9
9
|
# Supported Method Parameters::
|
10
10
|
# browser_obj = PWN::WWW::Twitter.open(
|
11
11
|
# browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
12
|
-
# proxy: 'optional - scheme://proxy_host:port ||
|
12
|
+
# proxy: 'optional - scheme://proxy_host:port || tor'
|
13
13
|
# )
|
14
14
|
|
15
15
|
public_class_method def self.open(opts = {})
|
16
16
|
browser_obj = PWN::Plugins::TransparentBrowser.open(opts)
|
17
17
|
|
18
|
-
browser_obj
|
18
|
+
browser = browser_obj[:browser]
|
19
|
+
browser.goto('https://twitter.com')
|
19
20
|
|
20
21
|
browser_obj
|
21
22
|
rescue StandardError => e
|
@@ -35,6 +36,8 @@ module PWN
|
|
35
36
|
username = opts[:username].to_s.scrub.strip.chomp
|
36
37
|
password = opts[:password]
|
37
38
|
|
39
|
+
browser = browser_obj[:browser]
|
40
|
+
|
38
41
|
if password.nil?
|
39
42
|
password = PWN::Plugins::AuthenticationHelper.mask_password
|
40
43
|
else
|
@@ -44,14 +47,16 @@ module PWN
|
|
44
47
|
|
45
48
|
browser_obj.goto('https://twitter.com/login')
|
46
49
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
+
browser.text_field(index: 2).wait_until(&:present?).set(username)
|
51
|
+
browser.text_field(index: 3).wait_until(&:present?).set(password)
|
52
|
+
browser.button(index: 1).click!
|
50
53
|
|
51
54
|
if mfa
|
52
|
-
until
|
53
|
-
|
54
|
-
|
55
|
+
until browser.url == 'https://twitter.com/' ||
|
56
|
+
browser.url == 'https://twitter.com/home'
|
57
|
+
|
58
|
+
browser.text_field(id: 'challenge_response').wait_until(&:present?).set(PWN::Plugins::AuthenticationHelper.mfa(prompt: 'enter mfa token'))
|
59
|
+
browser.button(id: 'email_challenge_submit').click!
|
55
60
|
sleep 3
|
56
61
|
end
|
57
62
|
print "\n"
|
@@ -69,8 +74,10 @@ module PWN
|
|
69
74
|
|
70
75
|
public_class_method def self.logout(opts = {})
|
71
76
|
browser_obj = opts[:browser_obj]
|
72
|
-
|
73
|
-
browser_obj
|
77
|
+
|
78
|
+
browser = browser_obj[:browser]
|
79
|
+
browser.li(id: 'user-dropdown').wait_until(&:present?).click!
|
80
|
+
browser.button(text: 'Log out').wait_until(&:present?).click!
|
74
81
|
|
75
82
|
browser_obj
|
76
83
|
rescue StandardError => e
|
@@ -105,9 +112,10 @@ module PWN
|
|
105
112
|
puts "USAGE:
|
106
113
|
browser_obj = #{self}.open(
|
107
114
|
browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
108
|
-
proxy: 'optional - scheme://proxy_host:port ||
|
115
|
+
proxy: 'optional - scheme://proxy_host:port || tor'
|
109
116
|
)
|
110
|
-
|
117
|
+
browser = browser_obj[:browser]
|
118
|
+
puts browser.public_methods
|
111
119
|
|
112
120
|
browser_obj = #{self}.login(
|
113
121
|
browser_obj: 'required - browser_obj returned from #open method',
|
data/lib/pwn/www/uber.rb
CHANGED
@@ -9,13 +9,14 @@ module PWN
|
|
9
9
|
# Supported Method Parameters::
|
10
10
|
# browser_obj = PWN::WWW::Uber.open(
|
11
11
|
# browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
12
|
-
# proxy: 'optional - scheme://proxy_host:port ||
|
12
|
+
# proxy: 'optional - scheme://proxy_host:port || tor'
|
13
13
|
# )
|
14
14
|
|
15
15
|
public_class_method def self.open(opts = {})
|
16
16
|
browser_obj = PWN::Plugins::TransparentBrowser.open(opts)
|
17
17
|
|
18
|
-
browser_obj
|
18
|
+
browser = browser_obj[:browser]
|
19
|
+
browser.goto('https://www.uber.com')
|
19
20
|
|
20
21
|
browser_obj
|
21
22
|
rescue StandardError => e
|
@@ -34,17 +35,19 @@ module PWN
|
|
34
35
|
username = opts[:username].to_s.scrub.strip.chomp
|
35
36
|
password = opts[:password]
|
36
37
|
|
38
|
+
browser = browser_obj[:browser]
|
39
|
+
|
37
40
|
if password.nil?
|
38
41
|
password = PWN::Plugins::AuthenticationHelper.mask_password
|
39
42
|
else
|
40
43
|
password = opts[:password].to_s.scrub.strip.chomp
|
41
44
|
end
|
42
45
|
|
43
|
-
|
46
|
+
browser.goto('https://login.uber.com/login')
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
browser.text_field(id: 'email').wait_until(&:present?).set(username)
|
49
|
+
browser.text_field(id: 'password').wait_until(&:present?).set(password)
|
50
|
+
browser.button(id: 'login-submit-btn').click!
|
48
51
|
|
49
52
|
browser_obj
|
50
53
|
rescue StandardError => e
|
@@ -58,8 +61,10 @@ module PWN
|
|
58
61
|
|
59
62
|
public_class_method def self.logout(opts = {})
|
60
63
|
browser_obj = opts[:browser_obj]
|
61
|
-
|
62
|
-
browser_obj
|
64
|
+
|
65
|
+
browser = browser_obj[:browser]
|
66
|
+
browser.span(index: 5).wait_until(&:present?).hover
|
67
|
+
browser.link(index: 13).wait_until(&:present?).click!
|
63
68
|
|
64
69
|
browser_obj
|
65
70
|
rescue StandardError => e
|
@@ -94,9 +99,10 @@ module PWN
|
|
94
99
|
puts "USAGE:
|
95
100
|
browser_obj = #{self}.open(
|
96
101
|
browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
97
|
-
proxy: 'optional - scheme://proxy_host:port ||
|
102
|
+
proxy: 'optional - scheme://proxy_host:port || tor'
|
98
103
|
)
|
99
|
-
|
104
|
+
browser = browser_obj[:browser]
|
105
|
+
puts browser.public_methods
|
100
106
|
|
101
107
|
browser_obj = #{self}.login(
|
102
108
|
browser_obj: 'required - browser_obj returned from #open method',
|
data/lib/pwn/www/upwork.rb
CHANGED
@@ -9,13 +9,14 @@ module PWN
|
|
9
9
|
# Supported Method Parameters::
|
10
10
|
# browser_obj = PWN::WWW::Upwork.open(
|
11
11
|
# browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
12
|
-
# proxy: 'optional - scheme://proxy_host:port ||
|
12
|
+
# proxy: 'optional - scheme://proxy_host:port || tor'
|
13
13
|
# )
|
14
14
|
|
15
15
|
public_class_method def self.open(opts = {})
|
16
16
|
browser_obj = PWN::Plugins::TransparentBrowser.open(opts)
|
17
17
|
|
18
|
-
browser_obj
|
18
|
+
browser = browser_obj[:browser]
|
19
|
+
browser.goto('https://www.upwork.com')
|
19
20
|
|
20
21
|
browser_obj
|
21
22
|
rescue StandardError => e
|
@@ -34,17 +35,19 @@ module PWN
|
|
34
35
|
username = opts[:username].to_s.scrub.strip.chomp
|
35
36
|
password = opts[:password]
|
36
37
|
|
38
|
+
browser = browser_obj[:browser]
|
39
|
+
|
37
40
|
if password.nil?
|
38
41
|
password = PWN::Plugins::AuthenticationHelper.mask_password
|
39
42
|
else
|
40
43
|
password = opts[:password].to_s.scrub.strip.chomp
|
41
44
|
end
|
42
45
|
|
43
|
-
|
46
|
+
browser.goto('https://www.upwork.com/ab/account-security/login')
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
browser.text_field(id: 'login_username').wait_until(&:present?).set(username)
|
49
|
+
browser.text_field(id: 'login_password').wait_until(&:present?).set(password)
|
50
|
+
browser.button(text: 'Log In').click!
|
48
51
|
|
49
52
|
browser_obj
|
50
53
|
rescue StandardError => e
|
@@ -58,8 +61,10 @@ module PWN
|
|
58
61
|
|
59
62
|
public_class_method def self.logout(opts = {})
|
60
63
|
browser_obj = opts[:browser_obj]
|
61
|
-
|
62
|
-
browser_obj
|
64
|
+
|
65
|
+
browser = browser_obj[:browser]
|
66
|
+
browser.span(class: 'organization-selector').wait_until(&:present?).click!
|
67
|
+
browser.link(index: 39).wait_until(&:present?).click!
|
63
68
|
|
64
69
|
browser_obj
|
65
70
|
rescue StandardError => e
|
@@ -94,9 +99,10 @@ module PWN
|
|
94
99
|
puts "USAGE:
|
95
100
|
browser_obj = #{self}.open(
|
96
101
|
browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
97
|
-
proxy: 'optional - scheme://proxy_host:port ||
|
102
|
+
proxy: 'optional - scheme://proxy_host:port || tor'
|
98
103
|
)
|
99
|
-
|
104
|
+
browser = browser_obj[:browser]
|
105
|
+
puts browser.public_methods
|
100
106
|
|
101
107
|
browser_obj = #{self}.login(
|
102
108
|
browser_obj: 'required - browser_obj returned from #open method',
|
data/lib/pwn/www/youtube.rb
CHANGED
@@ -7,13 +7,14 @@ module PWN
|
|
7
7
|
# Supported Method Parameters::
|
8
8
|
# browser_obj = PWN::WWW::Youtube.open(
|
9
9
|
# browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
10
|
-
# proxy: 'optional - scheme://proxy_host:port ||
|
10
|
+
# proxy: 'optional - scheme://proxy_host:port || tor'
|
11
11
|
# )
|
12
12
|
|
13
13
|
public_class_method def self.open(opts = {})
|
14
14
|
browser_obj = PWN::Plugins::TransparentBrowser.open(opts)
|
15
15
|
|
16
|
-
browser_obj
|
16
|
+
browser = browser_obj[:browser]
|
17
|
+
browser.goto('https://www.youtube.com')
|
17
18
|
|
18
19
|
browser_obj
|
19
20
|
rescue StandardError => e
|
@@ -30,8 +31,9 @@ module PWN
|
|
30
31
|
browser_obj = opts[:browser_obj]
|
31
32
|
q = opts[:q].to_s
|
32
33
|
|
33
|
-
browser_obj
|
34
|
-
|
34
|
+
browser = browser_obj[:browser]
|
35
|
+
browser.text_field(name: 'search_query').wait_until(&:present?).set(q)
|
36
|
+
browser.button(id: 'search-btn').click!
|
35
37
|
|
36
38
|
browser_obj
|
37
39
|
rescue StandardError => e
|
@@ -66,9 +68,10 @@ module PWN
|
|
66
68
|
puts "USAGE:
|
67
69
|
browser_obj =#{self}.open(
|
68
70
|
browser_type: 'optional - :firefox|:chrome|:ie|:headless (Defaults to :firefox)',
|
69
|
-
proxy: 'optional - scheme://proxy_host:port ||
|
71
|
+
proxy: 'optional - scheme://proxy_host:port || tor'
|
70
72
|
)
|
71
|
-
|
73
|
+
browser = browser_obj[:browser]
|
74
|
+
puts 'browser.public_methods'
|
72
75
|
|
73
76
|
browser_obj =#{self}.search(
|
74
77
|
browser_obj: 'required - browser_obj returned from #open method',
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.702
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -1150,8 +1150,6 @@ email:
|
|
1150
1150
|
executables:
|
1151
1151
|
- pwn
|
1152
1152
|
- pwn_android_war_dialer
|
1153
|
-
- pwn_arachni
|
1154
|
-
- pwn_arachni_rest
|
1155
1153
|
- pwn_autoinc_version
|
1156
1154
|
- pwn_aws_describe_resources
|
1157
1155
|
- pwn_burp_suite_pro_active_scan
|
@@ -1217,8 +1215,6 @@ files:
|
|
1217
1215
|
- Vagrantfile
|
1218
1216
|
- bin/pwn
|
1219
1217
|
- bin/pwn_android_war_dialer
|
1220
|
-
- bin/pwn_arachni
|
1221
|
-
- bin/pwn_arachni_rest
|
1222
1218
|
- bin/pwn_autoinc_version
|
1223
1219
|
- bin/pwn_aws_describe_resources
|
1224
1220
|
- bin/pwn_burp_suite_pro_active_scan
|
data/bin/pwn_arachni
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'pwn'
|
5
|
-
require 'optparse'
|
6
|
-
|
7
|
-
opts = {}
|
8
|
-
OptionParser.new do |options|
|
9
|
-
options.banner = "USAGE:
|
10
|
-
#{$PROGRAM_NAME} [opts]
|
11
|
-
"
|
12
|
-
|
13
|
-
options.on('-tTARGET', '--target_url=TARGET', '<Required - Target URI to Scan>') do |t|
|
14
|
-
opts[:target_url] = t
|
15
|
-
end
|
16
|
-
|
17
|
-
options.on('-oDIR', '--report_output_dir=DIR', '<Required - Output Directory for Results Generation>') do |o|
|
18
|
-
opts[:output_dir] = o
|
19
|
-
end
|
20
|
-
|
21
|
-
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless> (Defaults to chrome)>') do |b|
|
22
|
-
opts[:browser_type] = b
|
23
|
-
end
|
24
|
-
|
25
|
-
options.on('-IINST', '--navigation_instruct=INST', '<Optional - Path to Navigation Instructions (e.g. Auth w/ Target - see /pwn/etc/arachni/navigation.instruct.EXAMPLE)>') do |i|
|
26
|
-
opts[:navigation_instruct] = i
|
27
|
-
end
|
28
|
-
|
29
|
-
options.on('-pPROXY', '--proxy=PROXY', '<Optional - Proxy SCHEME://ADDRESS:PORT>') do |p|
|
30
|
-
opts[:proxy] = p
|
31
|
-
end
|
32
|
-
|
33
|
-
options.on('-xTYPE', '--proxy-type=TYPE', '<Optional - Proxy Type (See arachni --help)>') do |x|
|
34
|
-
opts[:proxy_type] = x
|
35
|
-
end
|
36
|
-
|
37
|
-
options.on('-ePATTERN', '--exclude-pattern=PATTERN', '<Optional - Exclude comma-delimited resources whose URL matches pattern>') do |e|
|
38
|
-
opts[:exclude_pattern] = e
|
39
|
-
end
|
40
|
-
|
41
|
-
options.on('-d', '--[no-]deep', '<Optional - Enable Deep Scanning (Much Longer to Complete)>') do |d|
|
42
|
-
opts[:deep_scan] = d
|
43
|
-
end
|
44
|
-
end.parse!
|
45
|
-
|
46
|
-
if opts.empty?
|
47
|
-
puts `#{$PROGRAM_NAME} --help`
|
48
|
-
exit 1
|
49
|
-
end
|
50
|
-
|
51
|
-
begin
|
52
|
-
logger = PWN::Plugins::PWNLogger.create
|
53
|
-
|
54
|
-
target_url = opts[:target_url].to_s.scrub
|
55
|
-
output_dir = opts[:output_dir].to_s.scrub if Dir.exist?(opts[:output_dir].to_s.scrub)
|
56
|
-
if opts[:browser_type].nil?
|
57
|
-
browser_type = :chrome
|
58
|
-
else
|
59
|
-
browser_type = opts[:browser_type].to_s.strip.chomp.scrub.to_sym
|
60
|
-
end
|
61
|
-
navigation_instruct = opts[:navigation_instruct].to_s.strip.chomp.scrub if File.exist?(opts[:navigation_instruct].to_s.strip.chomp.scrub)
|
62
|
-
proxy = opts[:proxy]
|
63
|
-
proxy_type = opts[:proxy_type]
|
64
|
-
exclude_pattern = opts[:exclude_pattern]
|
65
|
-
deep_scan = opts[:deep_scan]
|
66
|
-
|
67
|
-
raise 'ERROR: please use pwn_arachni_rest for REST Scanning.' if browser_type == :rest
|
68
|
-
|
69
|
-
browser = PWN::Plugins::TransparentBrowser.open(
|
70
|
-
browser_type: browser_type,
|
71
|
-
proxy: proxy
|
72
|
-
)
|
73
|
-
|
74
|
-
browser.goto(target_url)
|
75
|
-
|
76
|
-
if navigation_instruct
|
77
|
-
File.read(navigation_instruct).each_line do |instruction|
|
78
|
-
browser.instance_eval(instruction.to_s.scrub.strip.chomp)
|
79
|
-
end
|
80
|
-
|
81
|
-
# We should have an authenticated session by now in our browser object...
|
82
|
-
http_cookie_header = ''
|
83
|
-
browser.cookies.to_a.each_with_index do |this_symbolized_cookie_hash, index|
|
84
|
-
# Need to convert symbolized key names in browser.cookies.to_a[index]
|
85
|
-
# to strings for proper CGI::Cookie consumption
|
86
|
-
this_cookie = {}
|
87
|
-
this_symbolized_cookie_hash.each do |key, val|
|
88
|
-
this_cookie[key.to_s] = val
|
89
|
-
end
|
90
|
-
|
91
|
-
cgi_cookie_str = CGI::Cookie.new(this_cookie).to_s
|
92
|
-
|
93
|
-
if index.zero?
|
94
|
-
http_cookie_header = cgi_cookie_str
|
95
|
-
else
|
96
|
-
http_cookie_header = "#{http_cookie_header}, #{cgi_cookie_str}"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
arachni_cmd_str = "arachni #{target_url} --audit-parameter-names"
|
102
|
-
arachni_cmd_str = "#{arachni_cmd_str} --output-debug"
|
103
|
-
arachni_cmd_str = "#{arachni_cmd_str} --checks=*"
|
104
|
-
arachni_cmd_str = "#{arachni_cmd_str} --audit-ui-inputs --audit-ui-forms"
|
105
|
-
arachni_cmd_str = "#{arachni_cmd_str} --audit-jsons --audit-xmls"
|
106
|
-
arachni_cmd_str = "#{arachni_cmd_str} --audit-links --audit-forms --audit-cookies"
|
107
|
-
arachni_cmd_str = "#{arachni_cmd_str} --report-save-path=#{output_dir}/arachni_results.afr"
|
108
|
-
arachni_cmd_str = "#{arachni_cmd_str} --http-proxy #{proxy}" if proxy
|
109
|
-
arachni_cmd_str = "#{arachni_cmd_str} --http-proxy-type #{proxy_type}" if proxy_type
|
110
|
-
arachni_cmd_str = "#{arachni_cmd_str} --http-cookie-string='#{http_cookie_header}'" if navigation_instruct
|
111
|
-
arachni_cmd_str = "#{arachni_cmd_str} --audit-headers --audit-with-both-methods --audit-cookies-extensively" if deep_scan
|
112
|
-
|
113
|
-
if exclude_pattern
|
114
|
-
exclude_pattern.to_s.split(',').each do |exclude_entry|
|
115
|
-
arachni_cmd_str = "#{arachni_cmd_str} --scope-exclude-pattern #{exclude_entry}"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
# Kick off scan as defined by pwn_arachni flags
|
120
|
-
system(
|
121
|
-
'sudo',
|
122
|
-
'/bin/bash',
|
123
|
-
'--login',
|
124
|
-
'-c',
|
125
|
-
arachni_cmd_str
|
126
|
-
)
|
127
|
-
|
128
|
-
# Report Scan Results
|
129
|
-
system(
|
130
|
-
'sudo',
|
131
|
-
'/bin/bash',
|
132
|
-
'--login',
|
133
|
-
'-c',
|
134
|
-
"arachni_reporter #{output_dir}/arachni_results.afr --reporter=html:outfile=#{output_dir}/arachni_results.html.zip"
|
135
|
-
)
|
136
|
-
|
137
|
-
system(
|
138
|
-
'sudo',
|
139
|
-
'/bin/bash',
|
140
|
-
'--login',
|
141
|
-
'-c',
|
142
|
-
"arachni_reporter #{output_dir}/arachni_results.afr --reporter=json:outfile=#{output_dir}/arachni_results.json"
|
143
|
-
)
|
144
|
-
|
145
|
-
# Unzip Results in Output Dir
|
146
|
-
system(
|
147
|
-
'sudo',
|
148
|
-
'/bin/bash',
|
149
|
-
'--login',
|
150
|
-
'-c',
|
151
|
-
"cd #{output_dir} && unzip -o arachni_results.html.zip"
|
152
|
-
)
|
153
|
-
rescue StandardError, SystemExit, Interrupt => e
|
154
|
-
raise e
|
155
|
-
ensure
|
156
|
-
browser = PWN::Plugins::TransparentBrowser.close(browser_obj: browser) unless browser.nil?
|
157
|
-
end
|
data/bin/pwn_arachni_rest
DELETED
@@ -1,174 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'pwn'
|
5
|
-
require 'optparse'
|
6
|
-
require 'securerandom'
|
7
|
-
require 'pty'
|
8
|
-
require 'json'
|
9
|
-
|
10
|
-
opts = {}
|
11
|
-
OptionParser.new do |options|
|
12
|
-
options.banner = "USAGE:
|
13
|
-
#{$PROGRAM_NAME} [opts]
|
14
|
-
"
|
15
|
-
|
16
|
-
options.on('-tTARGET', '--target_url=TARGET', '<Required - Target URI to Scan>') do |t|
|
17
|
-
opts[:target_url] = t
|
18
|
-
end
|
19
|
-
|
20
|
-
options.on('-oDIR', '--report_output_dir=DIR', '<Required - Output Directory for Results Generation>') do |o|
|
21
|
-
opts[:output_dir] = o
|
22
|
-
end
|
23
|
-
|
24
|
-
options.on('-IINST', '--navigation_instruct=INST', '<Required - Path to Navigation Instructions (e.g. Auth w/ Target - see /pwn/etc/arachni/navigation-REST.instruct.EXAMPLE)>') do |i|
|
25
|
-
opts[:navigation_instruct] = i
|
26
|
-
end
|
27
|
-
|
28
|
-
options.on('-pPROXY', '--proxy=PROXY', '<Optional - Proxy SCHEME://ADDRESS:PORT>') do |p|
|
29
|
-
opts[:proxy] = p
|
30
|
-
end
|
31
|
-
|
32
|
-
options.on('-xTYPE', '--proxy-type=TYPE', '<Optional - Proxy Type (See arachni --help)>') do |x|
|
33
|
-
opts[:proxy_type] = x
|
34
|
-
end
|
35
|
-
|
36
|
-
options.on('-ePATTERN', '--exclude-pattern=PATTERN', '<Optional - Exclude comma-delimited resources whose URL matches pattern>') do |e|
|
37
|
-
opts[:exclude_pattern] = e
|
38
|
-
end
|
39
|
-
|
40
|
-
options.on('-d', '--[no-]deep', '<Optional - Enable Deep Scanning (Much Longer to Complete)>') do |d|
|
41
|
-
opts[:deep_scan] = d
|
42
|
-
end
|
43
|
-
end.parse!
|
44
|
-
|
45
|
-
if opts.empty?
|
46
|
-
puts `#{$PROGRAM_NAME} --help`
|
47
|
-
exit 1
|
48
|
-
end
|
49
|
-
|
50
|
-
logger = PWN::Plugins::PWNLogger.create
|
51
|
-
|
52
|
-
target_url = opts[:target_url].to_s.scrub
|
53
|
-
output_dir = opts[:output_dir].to_s.scrub if Dir.exist?(opts[:output_dir].to_s.scrub)
|
54
|
-
navigation_instruct = opts[:navigation_instruct].to_s.strip.chomp.scrub if File.exist?(opts[:navigation_instruct].to_s.strip.chomp.scrub)
|
55
|
-
proxy = opts[:proxy]
|
56
|
-
proxy_type = opts[:proxy_type]
|
57
|
-
exclude_pattern = opts[:exclude_pattern]
|
58
|
-
deep_scan = opts[:deep_scan]
|
59
|
-
|
60
|
-
# Proxy defaults to 127.0.0.1:8282
|
61
|
-
arachni_cmd_str = 'arachni --plugin=proxy:address=127.0.0.1,port=8282'
|
62
|
-
arachni_cmd_str = "#{arachni_cmd_str} --output-debug"
|
63
|
-
arachni_cmd_str = "#{arachni_cmd_str} --scope-page-limit=0"
|
64
|
-
arachni_cmd_str = "#{arachni_cmd_str} --checks=*,-common_*,-backup*,-backdoors,-directory_listing,-csrf"
|
65
|
-
arachni_cmd_str = "#{arachni_cmd_str} --report-save-path=#{output_dir}/arachni_results.afr"
|
66
|
-
arachni_cmd_str = "#{arachni_cmd_str} --http-proxy #{proxy}" if proxy
|
67
|
-
arachni_cmd_str = "#{arachni_cmd_str} --http-proxy-type #{proxy_type}" if proxy_type
|
68
|
-
arachni_cmd_str = "#{arachni_cmd_str} --audit-jsons --audit-xmls --audit-forms --audit-links"
|
69
|
-
arachni_cmd_str = "#{arachni_cmd_str} --audit-headers --audit-with-both-methods --audit-parameter-names" if deep_scan
|
70
|
-
arachni_cmd_str = "#{arachni_cmd_str} #{target_url}"
|
71
|
-
|
72
|
-
if exclude_pattern
|
73
|
-
exclude_pattern.to_s.split(',').each do |exclude_entry|
|
74
|
-
arachni_cmd_str = "#{arachni_cmd_str} --scope-exclude-pattern #{exclude_entry}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
arachni_stdout_log_path = "/tmp/pwn_arachni_rest-#{SecureRandom.hex}.log"
|
79
|
-
arachni_stdout_log = File.new(arachni_stdout_log_path, 'w')
|
80
|
-
# Immediately writes all buffered data in IO to disk
|
81
|
-
arachni_stdout_log.sync = true
|
82
|
-
arachni_stdout_log.fsync
|
83
|
-
|
84
|
-
trained_attack_vectors_yaml = ''
|
85
|
-
|
86
|
-
# Kick off scan as defined by pwn_arachni_rest flags
|
87
|
-
begin
|
88
|
-
fork_pid = Process.fork do
|
89
|
-
PTY.spawn(
|
90
|
-
"sudo /bin/bash --login -c \"#{arachni_cmd_str}\""
|
91
|
-
) do |stdout, _stdin, _pid|
|
92
|
-
stdout.each do |line|
|
93
|
-
puts line
|
94
|
-
arachni_stdout_log.puts line
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
Process.detach(fork_pid)
|
99
|
-
puts 'Arachni proxy plugin process exiting...'
|
100
|
-
rescue StandardError => e
|
101
|
-
puts 'ERROR: Arachni proxy plugin process exiting...'
|
102
|
-
raise e
|
103
|
-
rescue Interrupt
|
104
|
-
puts 'CTRL+C Detected - goodbye.'
|
105
|
-
exit 1
|
106
|
-
ensure
|
107
|
-
Process.kill('TERM', fork_pid) if fork_pid
|
108
|
-
File.unlink(arachni_stdout_log_path)
|
109
|
-
File.unlink(trained_attack_vectors_yaml)
|
110
|
-
end
|
111
|
-
|
112
|
-
# Watch for Arachni proxy plugin to intialize prior to invoking navigation-REST.instruct
|
113
|
-
return_pattern = 'Proxy: The scan will resume once you visit the shutdown URL.'
|
114
|
-
loop do
|
115
|
-
if File.exist?(arachni_stdout_log_path) &&
|
116
|
-
File.read(arachni_stdout_log_path).include?(return_pattern)
|
117
|
-
|
118
|
-
print 'Proxy started...sleeping for 9s. '
|
119
|
-
sleep 9
|
120
|
-
puts 'Ready to proceed.'
|
121
|
-
break
|
122
|
-
end
|
123
|
-
sleep 3
|
124
|
-
end
|
125
|
-
|
126
|
-
# Initiate rest_client object to pump requests through Arachni proxy plugin.
|
127
|
-
rest_client = PWN::Plugins::TransparentBrowser.open(
|
128
|
-
browser_type: :rest,
|
129
|
-
proxy: 'http://127.0.0.1:8282'
|
130
|
-
)::Request
|
131
|
-
|
132
|
-
# Now that the proxy is up, we can run the navigation-REST.instruct through the Arachni
|
133
|
-
# proxy plugin (http://127.0.0.1:8282) to train arachni how to interact w/ the API.
|
134
|
-
puts "Initialize REST API Training: #{navigation_instruct}"
|
135
|
-
pwn_arachni_rest_custom_http_header = instance_eval(File.read(navigation_instruct), navigation_instruct)
|
136
|
-
puts "REST API Training Complete: #{navigation_instruct}"
|
137
|
-
puts 'Sleeping for 9s prior to proceeding...'
|
138
|
-
sleep 9
|
139
|
-
|
140
|
-
# Close rest_client used for training Arachni
|
141
|
-
PWN::Plugins::TransparentBrowser.close(browser_obj: rest_client)
|
142
|
-
|
143
|
-
trained_attack_vectors_yaml = "#{File.dirname(arachni_stdout_log_path)}/#{File.basename(arachni_stdout_log_path, File.extname(arachni_stdout_log_path))}.yml"
|
144
|
-
|
145
|
-
# TODO: Use Process.spawn instead of system to capture pid for proper cleanup
|
146
|
-
system("/bin/bash --login -c \"http_proxy=http://127.0.0.1:8282 curl http://arachni.proxy/panel/vectors.yml -o #{trained_attack_vectors_yaml}\"")
|
147
|
-
# TODO: Use Process.spawn instead of system to capture pid for proper cleanup
|
148
|
-
system('/bin/bash --login -c "http_proxy=http://127.0.0.1:8282 curl http://arachni.proxy/shutdown"')
|
149
|
-
fork_pid = nil
|
150
|
-
|
151
|
-
arachni_trained_cmd_str = "arachni --plugin=vector_feed:yaml_file=#{trained_attack_vectors_yaml}"
|
152
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --output-debug"
|
153
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --scope-page-limit=0"
|
154
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --checks=*,-common_*,-backup*,-backdoors,-directory_listing,-csrf"
|
155
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --http-request-header='#{pwn_arachni_rest_custom_http_header}'" if pwn_arachni_rest_custom_http_header != ''
|
156
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --report-save-path=#{output_dir}/arachni_results.afr"
|
157
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --http-proxy #{proxy}" if proxy
|
158
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --http-proxy-type #{proxy_type}" if proxy_type
|
159
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --audit-jsons --audit-xmls --audit-forms --audit-links"
|
160
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} --audit-headers --audit-with-both-methods --audit-parameter-names" if deep_scan
|
161
|
-
arachni_trained_cmd_str = "#{arachni_trained_cmd_str} #{target_url}"
|
162
|
-
|
163
|
-
# TODO: Use Process.spawn instead of system to capture pid for proper cleanup
|
164
|
-
system("sudo /bin/bash --login -c \"#{arachni_trained_cmd_str}\"")
|
165
|
-
|
166
|
-
# Report Scan Results
|
167
|
-
# TODO: Use Process.spawn instead of system to capture pid for proper cleanup
|
168
|
-
system("sudo /bin/bash --login -c \"arachni_reporter #{output_dir}/arachni_results.afr --reporter=html:outfile=#{output_dir}/arachni_results.html.zip\"")
|
169
|
-
# TODO: Use Process.spawn instead of system to capture pid for proper cleanup
|
170
|
-
system("sudo /bin/bash --login -c \"arachni_reporter #{output_dir}/arachni_results.afr --reporter=json:outfile=#{output_dir}/arachni_results.json\"")
|
171
|
-
|
172
|
-
# Unzip Results in Output Dir
|
173
|
-
# TODO: Use Process.spawn instead of system to capture pid for proper cleanup
|
174
|
-
system("sudo /bin/bash --login -c \"cd #{output_dir} && unzip -o arachni_results.html.zip\"")
|