pwn 0.5.425 → 0.5.426
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 +1 -1
- data/README.md +3 -3
- data/bin/pwn +2 -10
- data/lib/pwn/ai.rb +1 -1
- data/lib/pwn/blockchain/btc.rb +160 -0
- data/lib/pwn/blockchain/eth.rb +160 -0
- data/lib/pwn/blockchain.rb +17 -0
- data/lib/pwn/plugins/repl.rb +7 -6
- data/lib/pwn/plugins/vault.rb +5 -5
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn.rb +1 -0
- data/spec/lib/pwn/blockchain/btc_spec.rb +15 -0
- data/spec/lib/pwn/blockchain/eth_spec.rb +15 -0
- data/spec/lib/pwn/blockchain_spec.rb +10 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6bbdb81c1c0df4969edc99d219a625265fa48d5af722628a2a77d3ead2741cb
|
4
|
+
data.tar.gz: 68e09e473021b7b574074f737c066e06cc0276171eb74f99f9c8495f34a8825d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e279405371694e5d6c602a869662fab95ebdd18f7b207734a6023a4c0d2d98a3ddf903f03f150d966c14fbb02a7e9dda36ad8eef77850eacebf870179c5ff56
|
7
|
+
data.tar.gz: e832fd158b5427c267e6240d8c7473d766ce1a9fdc53c5ff3353e08933cc4f3c2e2cc45a93f6b270092d6b38e1ccacc2d4a437fdc7983c201c71cb68dcc978d5
|
data/Gemfile
CHANGED
@@ -90,7 +90,7 @@ gem 'ruby-nmap', '1.0.3'
|
|
90
90
|
gem 'ruby-saml', '1.18.1'
|
91
91
|
gem 'rvm', '1.11.3.9'
|
92
92
|
gem 'savon', '2.15.1'
|
93
|
-
gem 'selenium-devtools', '0.
|
93
|
+
gem 'selenium-devtools', '0.140.0'
|
94
94
|
# gem 'serialport', '1.3.2'
|
95
95
|
# gem 'sinatra', '4.0.0'
|
96
96
|
gem 'slack-ruby-client', '3.0.0'
|
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.426]: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.426]: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.426]: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/bin/pwn
CHANGED
@@ -14,16 +14,8 @@ OptionParser.new do |options|
|
|
14
14
|
opts[:yaml_config_path] = p
|
15
15
|
end
|
16
16
|
|
17
|
-
options.on('-dPATH', '--decryptor=PATH', '<Optional - File
|
18
|
-
opts[:
|
19
|
-
end
|
20
|
-
|
21
|
-
options.on('-kKEY', '--decryption-key=KEY', '<Optional - Decryption Key>') do |k|
|
22
|
-
opts[:key] = k
|
23
|
-
end
|
24
|
-
|
25
|
-
options.on('-iIV', '--decryption-iv=PATH', '<Optional - Decryption IV>') do |i|
|
26
|
-
opts[:iv] = i
|
17
|
+
options.on('-dPATH', '--yaml-decryptor=PATH', '<Optional - Out-of-Band YAML File with :key && :iv>') do |d|
|
18
|
+
opts[:yaml_decryptor_path] = d
|
27
19
|
end
|
28
20
|
end.parse!
|
29
21
|
|
data/lib/pwn/ai.rb
CHANGED
@@ -0,0 +1,160 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'rest-client'
|
5
|
+
require 'tty-spinner'
|
6
|
+
|
7
|
+
module PWN
|
8
|
+
module Blockchain
|
9
|
+
# This plugin interacts with BitCoin's Blockchain API.
|
10
|
+
module BTC
|
11
|
+
# Supported Method Parameters::
|
12
|
+
# btc_rest_call(
|
13
|
+
# http_method: 'optional HTTP method (defaults to GET)
|
14
|
+
# rest_call: 'required rest call to make per the schema',
|
15
|
+
# params: 'optional params passed in the URI or HTTP Headers',
|
16
|
+
# http_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',
|
17
|
+
# timeout: 'optional timeout in seconds (defaults to 180)',
|
18
|
+
# spinner: 'optional - display spinner (defaults to false)'
|
19
|
+
# )
|
20
|
+
|
21
|
+
private_class_method def self.btc_rest_call(opts = {})
|
22
|
+
http_method = if opts[:http_method].nil?
|
23
|
+
:get
|
24
|
+
else
|
25
|
+
opts[:http_method].to_s.scrub.to_sym
|
26
|
+
end
|
27
|
+
|
28
|
+
base_uri = 'https://api.blockcypher.com/v1/btc/'
|
29
|
+
rest_call = opts[:rest_call].to_s.scrub
|
30
|
+
params = opts[:params]
|
31
|
+
headers = { content_type: 'application/json; charset=UTF-8' }
|
32
|
+
|
33
|
+
http_body = opts[:http_body]
|
34
|
+
http_body ||= {}
|
35
|
+
|
36
|
+
timeout = opts[:timeout]
|
37
|
+
timeout ||= 180
|
38
|
+
|
39
|
+
spinner = opts[:spinner] || false
|
40
|
+
|
41
|
+
browser_obj = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
|
42
|
+
rest_client = browser_obj[:browser]::Request
|
43
|
+
|
44
|
+
if spinner
|
45
|
+
spin = TTY::Spinner.new(format: :dots)
|
46
|
+
spin.auto_spin
|
47
|
+
end
|
48
|
+
|
49
|
+
retries = 0
|
50
|
+
case http_method
|
51
|
+
when :delete, :get
|
52
|
+
headers[:params] = params
|
53
|
+
response = rest_client.execute(
|
54
|
+
method: http_method,
|
55
|
+
url: "#{base_uri}#{rest_call}",
|
56
|
+
headers: headers,
|
57
|
+
verify_ssl: false,
|
58
|
+
timeout: timeout
|
59
|
+
)
|
60
|
+
|
61
|
+
when :post
|
62
|
+
if http_body.key?(:multipart)
|
63
|
+
headers[:content_type] = 'multipart/form-data'
|
64
|
+
|
65
|
+
response = rest_client.execute(
|
66
|
+
method: http_method,
|
67
|
+
url: "#{base_uri}#{rest_call}",
|
68
|
+
headers: headers,
|
69
|
+
payload: http_body,
|
70
|
+
verify_ssl: false,
|
71
|
+
timeout: timeout
|
72
|
+
)
|
73
|
+
else
|
74
|
+
response = rest_client.execute(
|
75
|
+
method: http_method,
|
76
|
+
url: "#{base_uri}#{rest_call}",
|
77
|
+
headers: headers,
|
78
|
+
payload: http_body.to_json,
|
79
|
+
verify_ssl: false,
|
80
|
+
timeout: timeout
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
else
|
85
|
+
raise "Unsupported HTTP Method #{http_method} for #{self} Plugin"
|
86
|
+
end
|
87
|
+
|
88
|
+
response
|
89
|
+
rescue RestClient::ExceptionWithResponse => e
|
90
|
+
case e.http_code
|
91
|
+
when 400, 404
|
92
|
+
"#{e.http_code} #{e.message}: #{e.response.body}"
|
93
|
+
else
|
94
|
+
raise e
|
95
|
+
end
|
96
|
+
rescue StandardError => e
|
97
|
+
raise e
|
98
|
+
ensure
|
99
|
+
spin.stop if spinner
|
100
|
+
end
|
101
|
+
|
102
|
+
# Supported Method Parameters::
|
103
|
+
# latest_block = PWN::Blockchain::BTC.get_latest_block(
|
104
|
+
# token: 'optional - API token for higher rate limits'
|
105
|
+
# )
|
106
|
+
|
107
|
+
public_class_method def self.get_latest_block(opts = {})
|
108
|
+
params = {}
|
109
|
+
params[:token] = opts[:token] if opts[:token]
|
110
|
+
|
111
|
+
rest_call = 'main'
|
112
|
+
response = btc_rest_call(rest_call: rest_call, params: params)
|
113
|
+
|
114
|
+
JSON.parse(response.body, symbolize_names: true)
|
115
|
+
rescue StandardError => e
|
116
|
+
raise e
|
117
|
+
end
|
118
|
+
|
119
|
+
# Supported Method Parameters::
|
120
|
+
# PWN::Blockchain::BTC.get_block_details(
|
121
|
+
# height: 'required - block height number',
|
122
|
+
# token: 'optional - API token for higher rate limits'
|
123
|
+
# )
|
124
|
+
public_class_method def self.get_block_details(opts = {})
|
125
|
+
height = opts[:height]
|
126
|
+
params = {}
|
127
|
+
params[:token] = opts[:token] if opts[:token]
|
128
|
+
|
129
|
+
rest_call = "main/blocks/#{height}"
|
130
|
+
response = btc_rest_call(rest_call: rest_call, params: params)
|
131
|
+
|
132
|
+
JSON.parse(response.body, symbolize_names: true)
|
133
|
+
rescue StandardError => e
|
134
|
+
raise e
|
135
|
+
end
|
136
|
+
|
137
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
138
|
+
|
139
|
+
public_class_method def self.authors
|
140
|
+
"AUTHOR(S):
|
141
|
+
0day Inc. <support@0dayinc.com>
|
142
|
+
"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Display Usage for this Module
|
146
|
+
|
147
|
+
public_class_method def self.help
|
148
|
+
puts "USAGE:
|
149
|
+
latest_block = #{self}.get_latest_block
|
150
|
+
|
151
|
+
block_details = #{self}.get_block_details(
|
152
|
+
height: 'required - block height number'
|
153
|
+
)
|
154
|
+
|
155
|
+
#{self}.authors
|
156
|
+
"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'rest-client'
|
5
|
+
require 'tty-spinner'
|
6
|
+
|
7
|
+
module PWN
|
8
|
+
module Blockchain
|
9
|
+
# This plugin interacts with BitCoin's Blockchain API.
|
10
|
+
module ETH
|
11
|
+
# Supported Method Parameters::
|
12
|
+
# eth_rest_call(
|
13
|
+
# http_method: 'optional HTTP method (defaults to GET)
|
14
|
+
# rest_call: 'required rest call to make per the schema',
|
15
|
+
# params: 'optional params passed in the URI or HTTP Headers',
|
16
|
+
# http_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',
|
17
|
+
# timeout: 'optional timeout in seconds (defaults to 180)',
|
18
|
+
# spinner: 'optional - display spinner (defaults to false)'
|
19
|
+
# )
|
20
|
+
|
21
|
+
private_class_method def self.eth_rest_call(opts = {})
|
22
|
+
http_method = if opts[:http_method].nil?
|
23
|
+
:get
|
24
|
+
else
|
25
|
+
opts[:http_method].to_s.scrub.to_sym
|
26
|
+
end
|
27
|
+
|
28
|
+
base_uri = 'https://api.blockcypher.com/v1/eth/'
|
29
|
+
rest_call = opts[:rest_call].to_s.scrub
|
30
|
+
params = opts[:params]
|
31
|
+
headers = { content_type: 'application/json; charset=UTF-8' }
|
32
|
+
|
33
|
+
http_body = opts[:http_body]
|
34
|
+
http_body ||= {}
|
35
|
+
|
36
|
+
timeout = opts[:timeout]
|
37
|
+
timeout ||= 180
|
38
|
+
|
39
|
+
spinner = opts[:spinner] || false
|
40
|
+
|
41
|
+
browser_obj = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
|
42
|
+
rest_client = browser_obj[:browser]::Request
|
43
|
+
|
44
|
+
if spinner
|
45
|
+
spin = TTY::Spinner.new(format: :dots)
|
46
|
+
spin.auto_spin
|
47
|
+
end
|
48
|
+
|
49
|
+
retries = 0
|
50
|
+
case http_method
|
51
|
+
when :delete, :get
|
52
|
+
headers[:params] = params
|
53
|
+
response = rest_client.execute(
|
54
|
+
method: http_method,
|
55
|
+
url: "#{base_uri}#{rest_call}",
|
56
|
+
headers: headers,
|
57
|
+
verify_ssl: false,
|
58
|
+
timeout: timeout
|
59
|
+
)
|
60
|
+
|
61
|
+
when :post
|
62
|
+
if http_body.key?(:multipart)
|
63
|
+
headers[:content_type] = 'multipart/form-data'
|
64
|
+
|
65
|
+
response = rest_client.execute(
|
66
|
+
method: http_method,
|
67
|
+
url: "#{base_uri}#{rest_call}",
|
68
|
+
headers: headers,
|
69
|
+
payload: http_body,
|
70
|
+
verify_ssl: false,
|
71
|
+
timeout: timeout
|
72
|
+
)
|
73
|
+
else
|
74
|
+
response = rest_client.execute(
|
75
|
+
method: http_method,
|
76
|
+
url: "#{base_uri}#{rest_call}",
|
77
|
+
headers: headers,
|
78
|
+
payload: http_body.to_json,
|
79
|
+
verify_ssl: false,
|
80
|
+
timeout: timeout
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
else
|
85
|
+
raise "Unsupported HTTP Method #{http_method} for #{self} Plugin"
|
86
|
+
end
|
87
|
+
|
88
|
+
response
|
89
|
+
rescue RestClient::ExceptionWithResponse => e
|
90
|
+
case e.http_code
|
91
|
+
when 400, 404
|
92
|
+
"#{e.http_code} #{e.message}: #{e.response.body}"
|
93
|
+
else
|
94
|
+
raise e
|
95
|
+
end
|
96
|
+
rescue StandardError => e
|
97
|
+
raise e
|
98
|
+
ensure
|
99
|
+
spin.stop if spinner
|
100
|
+
end
|
101
|
+
|
102
|
+
# Supported Method Parameters::
|
103
|
+
# latest_block = PWN::Blockchain::ETH.get_latest_block(
|
104
|
+
# token: 'optional - API token for higher rate limits'
|
105
|
+
# )
|
106
|
+
|
107
|
+
public_class_method def self.get_latest_block(opts = {})
|
108
|
+
params = {}
|
109
|
+
params[:token] = opts[:token] if opts[:token]
|
110
|
+
|
111
|
+
rest_call = 'main'
|
112
|
+
response = eth_rest_call(rest_call: rest_call, params: params)
|
113
|
+
|
114
|
+
JSON.parse(response.body, symbolize_names: true)
|
115
|
+
rescue StandardError => e
|
116
|
+
raise e
|
117
|
+
end
|
118
|
+
|
119
|
+
# Supported Method Parameters::
|
120
|
+
# PWN::Blockchain::ETH.get_block_details(
|
121
|
+
# height: 'required - block height number',
|
122
|
+
# token: 'optional - API token for higher rate limits'
|
123
|
+
# )
|
124
|
+
public_class_method def self.get_block_details(opts = {})
|
125
|
+
height = opts[:height]
|
126
|
+
params = {}
|
127
|
+
params[:token] = opts[:token] if opts[:token]
|
128
|
+
|
129
|
+
rest_call = "main/blocks/#{height}"
|
130
|
+
response = eth_rest_call(rest_call: rest_call, params: params)
|
131
|
+
|
132
|
+
JSON.parse(response.body, symbolize_names: true)
|
133
|
+
rescue StandardError => e
|
134
|
+
raise e
|
135
|
+
end
|
136
|
+
|
137
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
138
|
+
|
139
|
+
public_class_method def self.authors
|
140
|
+
"AUTHOR(S):
|
141
|
+
0day Inc. <support@0dayinc.com>
|
142
|
+
"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Display Usage for this Module
|
146
|
+
|
147
|
+
public_class_method def self.help
|
148
|
+
puts "USAGE:
|
149
|
+
latest_block = #{self}.get_latest_block
|
150
|
+
|
151
|
+
block_details = #{self}.get_block_details(
|
152
|
+
height: 'required - block height number'
|
153
|
+
)
|
154
|
+
|
155
|
+
#{self}.authors
|
156
|
+
"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PWN
|
4
|
+
# This file, using the autoload directive loads SP plugins
|
5
|
+
# into memory only when they're needed. For more information, see:
|
6
|
+
# http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html
|
7
|
+
module Blockchain
|
8
|
+
autoload :BTC, 'pwn/blockchain/btc'
|
9
|
+
autoload :ETH, 'pwn/blockchain/eth'
|
10
|
+
|
11
|
+
# Display a List of Every PWN::Blockchain Module
|
12
|
+
|
13
|
+
public_class_method def self.help
|
14
|
+
constants.sort
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/pwn/plugins/repl.rb
CHANGED
@@ -469,12 +469,13 @@ module PWN
|
|
469
469
|
return
|
470
470
|
end
|
471
471
|
|
472
|
-
|
473
|
-
unless File.exist?(
|
474
|
-
puts "ERROR: pwn.decryptor.yaml not found: #{
|
472
|
+
yaml_decryptor_path = pi.config.yaml_decryptor_path ||= "#{Dir.home}/.pwn/pwn.decryptor.yaml"
|
473
|
+
unless File.exist?(yaml_decryptor_path)
|
474
|
+
puts "ERROR: pwn.decryptor.yaml not found: #{yaml_decryptor_path}"
|
475
475
|
return
|
476
476
|
end
|
477
|
-
|
477
|
+
|
478
|
+
decryptor = YAML.load_file(yaml_decryptor_path, symbolize_names: true)
|
478
479
|
key = decryptor[:key]
|
479
480
|
iv = decryptor[:iv]
|
480
481
|
|
@@ -539,7 +540,7 @@ module PWN
|
|
539
540
|
Pry.config.hooks.add_hook(:before_session, :init_opts) do |_output, _binding, pi|
|
540
541
|
opts[:pi] = pi
|
541
542
|
Pry.config.yaml_config_path = opts[:yaml_config_path]
|
542
|
-
Pry.config.
|
543
|
+
Pry.config.yaml_decryptor_path = opts[:yaml_decryptor_path]
|
543
544
|
|
544
545
|
PWN::Plugins::Vault.refresh_config_for_repl(opts)
|
545
546
|
end
|
@@ -690,7 +691,7 @@ module PWN
|
|
690
691
|
pwn_config_root = "#{Dir.home}/.pwn"
|
691
692
|
FileUtils.mkdir_p(pwn_config_root)
|
692
693
|
opts[:yaml_config_path] ||= "#{pwn_config_root}/pwn.yaml"
|
693
|
-
opts[:
|
694
|
+
opts[:yaml_decryptor_path] ||= "#{pwn_config_root}/pwn.decryptor.yaml"
|
694
695
|
|
695
696
|
add_hooks(opts)
|
696
697
|
|
data/lib/pwn/plugins/vault.rb
CHANGED
@@ -238,7 +238,7 @@ module PWN
|
|
238
238
|
# PWN::Plugins::Vault.refresh_config_for_repl(
|
239
239
|
# yaml_config_path: 'required - full path to pwn.yaml file',
|
240
240
|
# pi: 'optional - Pry instance (default: Pry)',
|
241
|
-
#
|
241
|
+
# yaml_decryptor_path: 'optional - full path to decryption YAML file'
|
242
242
|
# )
|
243
243
|
public_class_method def self.refresh_config_for_repl(opts = {})
|
244
244
|
yaml_config_path = opts[:yaml_config_path]
|
@@ -251,10 +251,10 @@ module PWN
|
|
251
251
|
|
252
252
|
if is_encrypted
|
253
253
|
# TODO: Implement "something you know, something you have, && something you are?"
|
254
|
-
|
255
|
-
raise "ERROR: #{
|
254
|
+
yaml_decryptor_path = opts[:yaml_decryptor_path] ||= "#{Dir.home}/.pwn/pwn.decryptor.yaml"
|
255
|
+
raise "ERROR: #{yaml_decryptor_path} does not exist." unless File.exist?(yaml_decryptor_path)
|
256
256
|
|
257
|
-
yaml_decryptor = YAML.load_file(
|
257
|
+
yaml_decryptor = YAML.load_file(yaml_decryptor_path, symbolize_names: true)
|
258
258
|
|
259
259
|
key = opts[:key] ||= yaml_decryptor[:key] ||= ENV.fetch('PWN_DECRYPTOR_KEY')
|
260
260
|
key = PWN::Plugins::AuthenticationHelper.mask_password(prompt: 'Decryption Key') if key.nil?
|
@@ -377,7 +377,7 @@ module PWN
|
|
377
377
|
#{self}.refresh_config_for_repl(
|
378
378
|
yaml_config_path: 'required - full path to pwn.yaml file',
|
379
379
|
pi: 'optional - Pry instance (default: Pry)',
|
380
|
-
|
380
|
+
yaml_decryptor_path: 'optional - full path to decryption YAML file'
|
381
381
|
)
|
382
382
|
|
383
383
|
#{self}.authors
|
data/lib/pwn/version.rb
CHANGED
data/lib/pwn.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe PWN::Blockchain::BTC do
|
6
|
+
it 'should display information for authors' do
|
7
|
+
authors_response = PWN::Blockchain::BTC
|
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::Blockchain::BTC
|
13
|
+
expect(help_response).to respond_to :help
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe PWN::Blockchain::ETH do
|
6
|
+
it 'should display information for authors' do
|
7
|
+
authors_response = PWN::Blockchain::ETH
|
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::Blockchain::ETH
|
13
|
+
expect(help_response).to respond_to :help
|
14
|
+
end
|
15
|
+
end
|
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.426
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
@@ -1051,14 +1051,14 @@ dependencies:
|
|
1051
1051
|
requirements:
|
1052
1052
|
- - '='
|
1053
1053
|
- !ruby/object:Gem::Version
|
1054
|
-
version: 0.
|
1054
|
+
version: 0.140.0
|
1055
1055
|
type: :runtime
|
1056
1056
|
prerelease: false
|
1057
1057
|
version_requirements: !ruby/object:Gem::Requirement
|
1058
1058
|
requirements:
|
1059
1059
|
- - '='
|
1060
1060
|
- !ruby/object:Gem::Version
|
1061
|
-
version: 0.
|
1061
|
+
version: 0.140.0
|
1062
1062
|
- !ruby/object:Gem::Dependency
|
1063
1063
|
name: slack-ruby-client
|
1064
1064
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1829,6 +1829,9 @@ files:
|
|
1829
1829
|
- lib/pwn/banner/radare2.rb
|
1830
1830
|
- lib/pwn/banner/radare2_ai.rb
|
1831
1831
|
- lib/pwn/banner/white_rabbit.rb
|
1832
|
+
- lib/pwn/blockchain.rb
|
1833
|
+
- lib/pwn/blockchain/btc.rb
|
1834
|
+
- lib/pwn/blockchain/eth.rb
|
1832
1835
|
- lib/pwn/ffi.rb
|
1833
1836
|
- lib/pwn/ffi/stdio.rb
|
1834
1837
|
- lib/pwn/plugins.rb
|
@@ -2174,6 +2177,9 @@ files:
|
|
2174
2177
|
- spec/lib/pwn/banner/radare2_spec.rb
|
2175
2178
|
- spec/lib/pwn/banner/white_rabbit_spec.rb
|
2176
2179
|
- spec/lib/pwn/banner_spec.rb
|
2180
|
+
- spec/lib/pwn/blockchain/btc_spec.rb
|
2181
|
+
- spec/lib/pwn/blockchain/eth_spec.rb
|
2182
|
+
- spec/lib/pwn/blockchain_spec.rb
|
2177
2183
|
- spec/lib/pwn/ffi/stdio_spec.rb
|
2178
2184
|
- spec/lib/pwn/ffi_spec.rb
|
2179
2185
|
- spec/lib/pwn/plugins/android_spec.rb
|