pwn 0.4.463 → 0.4.466
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +16 -16
- data/Gemfile +3 -3
- data/README.md +2 -2
- data/bin/pwn_serial_msr206 +145 -12
- data/lib/pwn/plugins/msr206.rb +406 -18
- data/lib/pwn/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b22a31f1952951d9c3bd1a8dd912b58e1b6ccf39d93a55327b10e285729e67de
|
|
4
|
+
data.tar.gz: a15ab49fbf548031599248380aca04bb05e9220357d771d27de63d477af33038
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 360eab449207970607c8052dfd3ee9beae9026ed19c41f690f2874cdc932eb8981c341792d37316bc202a5feb2332cdf86686f39416dd001b0338d8b19dbad72
|
|
7
|
+
data.tar.gz: d85c5f1785095b00c058727366896774a47afcb107aa69d0115aa4d501b83daa71df4699983f51acafdc46fa91fc9bcba52bdd7cb770fade67ac5ba85e3ecf9d
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2022-05-
|
|
3
|
+
# on 2022-05-27 23:04:56 UTC using RuboCop version 1.30.0.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
9
|
+
# Offense count: 234
|
|
10
10
|
Lint/UselessAssignment:
|
|
11
11
|
Enabled: false
|
|
12
12
|
|
|
13
|
-
# Offense count:
|
|
13
|
+
# Offense count: 253
|
|
14
14
|
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
|
15
15
|
Metrics/AbcSize:
|
|
16
16
|
Max: 328
|
|
17
17
|
|
|
18
|
-
# Offense count:
|
|
18
|
+
# Offense count: 63
|
|
19
19
|
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
|
20
20
|
# IgnoredMethods: refine
|
|
21
21
|
Metrics/BlockLength:
|
|
22
|
-
Max:
|
|
22
|
+
Max: 196
|
|
23
23
|
|
|
24
24
|
# Offense count: 45
|
|
25
25
|
# Configuration parameters: CountBlocks.
|
|
26
26
|
Metrics/BlockNesting:
|
|
27
27
|
Max: 5
|
|
28
28
|
|
|
29
|
-
# Offense count:
|
|
29
|
+
# Offense count: 89
|
|
30
30
|
# Configuration parameters: IgnoredMethods.
|
|
31
31
|
Metrics/CyclomaticComplexity:
|
|
32
32
|
Max: 231
|
|
33
33
|
|
|
34
|
-
# Offense count:
|
|
34
|
+
# Offense count: 459
|
|
35
35
|
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
|
36
36
|
Metrics/MethodLength:
|
|
37
37
|
Max: 466
|
|
38
38
|
|
|
39
|
-
# Offense count:
|
|
39
|
+
# Offense count: 34
|
|
40
40
|
# Configuration parameters: CountComments, CountAsOne.
|
|
41
41
|
Metrics/ModuleLength:
|
|
42
42
|
Max: 1186
|
|
43
43
|
|
|
44
|
-
# Offense count:
|
|
44
|
+
# Offense count: 81
|
|
45
45
|
# Configuration parameters: IgnoredMethods.
|
|
46
46
|
Metrics/PerceivedComplexity:
|
|
47
47
|
Max: 51
|
|
@@ -50,33 +50,33 @@ Metrics/PerceivedComplexity:
|
|
|
50
50
|
Style/ClassVars:
|
|
51
51
|
Enabled: false
|
|
52
52
|
|
|
53
|
-
# Offense count:
|
|
54
|
-
# This cop supports safe
|
|
53
|
+
# Offense count: 285
|
|
54
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
55
55
|
# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
|
|
56
56
|
# SupportedStyles: assign_to_condition, assign_inside_condition
|
|
57
57
|
Style/ConditionalAssignment:
|
|
58
58
|
Enabled: false
|
|
59
59
|
|
|
60
60
|
# Offense count: 2
|
|
61
|
-
# This cop supports safe
|
|
61
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
62
62
|
Style/ExplicitBlockArgument:
|
|
63
63
|
Exclude:
|
|
64
64
|
- 'lib/pwn/plugins/nmap_it.rb'
|
|
65
65
|
|
|
66
66
|
# Offense count: 95
|
|
67
|
-
# This cop supports safe
|
|
67
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
68
68
|
Style/RedundantCondition:
|
|
69
69
|
Exclude:
|
|
70
70
|
- 'bin/pwn_simple_http_server'
|
|
71
71
|
- 'lib/pwn/plugins/packet.rb'
|
|
72
72
|
|
|
73
73
|
# Offense count: 44
|
|
74
|
-
# This cop supports unsafe
|
|
74
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
75
75
|
Style/SlicingWithRange:
|
|
76
76
|
Enabled: false
|
|
77
77
|
|
|
78
|
-
# Offense count:
|
|
79
|
-
# This cop supports safe
|
|
78
|
+
# Offense count: 555
|
|
79
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
80
80
|
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns.
|
|
81
81
|
# URISchemes: http, https
|
|
82
82
|
Layout/LineLength:
|
data/Gemfile
CHANGED
|
@@ -13,12 +13,12 @@ gemspec
|
|
|
13
13
|
# to review these custom flags (e.g. pg, serialport, etc).
|
|
14
14
|
gem 'activesupport', '7.0.3'
|
|
15
15
|
gem 'anemone', '0.7.2'
|
|
16
|
-
gem 'authy', '3.0.
|
|
16
|
+
gem 'authy', '3.0.1'
|
|
17
17
|
gem 'aws-sdk', '3.1.0'
|
|
18
18
|
gem 'bettercap', '1.6.2'
|
|
19
19
|
gem 'brakeman', '5.2.3'
|
|
20
20
|
gem 'bson', '4.15.0'
|
|
21
|
-
gem 'bundler', '>=2.3.
|
|
21
|
+
gem 'bundler', '>=2.3.15'
|
|
22
22
|
gem 'bundler-audit', '0.9.1'
|
|
23
23
|
gem 'bunny', '2.19.0'
|
|
24
24
|
gem 'colorize', '0.8.1'
|
|
@@ -80,4 +80,4 @@ gem 'watir', '7.1.0'
|
|
|
80
80
|
gem 'waveform', '0.1.2'
|
|
81
81
|
gem 'webrick', '1.7.0'
|
|
82
82
|
gem 'wicked_pdf', '2.6.3'
|
|
83
|
-
gem 'yard', '0.9.
|
|
83
|
+
gem 'yard', '0.9.28'
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ $ rvm use ruby-3.1.2@pwn
|
|
|
37
37
|
$ rvm list gemsets
|
|
38
38
|
$ gem install --verbose pwn
|
|
39
39
|
$ pwn
|
|
40
|
-
pwn[v0.4.
|
|
40
|
+
pwn[v0.4.466]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.1.2@pwn
|
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
|
53
53
|
$ gem install --verbose pwn
|
|
54
54
|
$ pwn
|
|
55
|
-
pwn[v0.4.
|
|
55
|
+
pwn[v0.4.466]:001 >>> PWN.help
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
|
data/bin/pwn_serial_msr206
CHANGED
|
@@ -14,24 +14,24 @@ OptionParser.new do |options|
|
|
|
14
14
|
opts[:block_dev] = d
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
options.on('-bBAUD', '--baud=
|
|
18
|
-
opts[:
|
|
17
|
+
options.on('-bBAUD', '--baud=BAUD', '<Optional - (defaults to 9600)>') do |b|
|
|
18
|
+
opts[:baud] = b
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
options.on('-DDATABITS', '--data-bits=DATABITS', '<Optional - (defaults to
|
|
22
|
-
opts[:
|
|
21
|
+
options.on('-DDATABITS', '--data-bits=DATABITS', '<Optional - (defaults to 8)>') do |d|
|
|
22
|
+
opts[:data_bits] = d
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
options.on('-sSTOPBITS', '--stop-bits=STOPBITS', '<Optional - (defaults to 1)>') do |
|
|
26
|
-
opts[:
|
|
25
|
+
options.on('-sSTOPBITS', '--stop-bits=STOPBITS', '<Optional - (defaults to 1)>') do |s|
|
|
26
|
+
opts[:stop_bits] = s
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
options.on('-pPARITY', '--parity=PARITY', '<Optional -
|
|
30
|
-
opts[:
|
|
29
|
+
options.on('-pPARITY', '--parity=PARITY', '<Optional - even|mark|odd|space|none (defaults to none)>') do |p|
|
|
30
|
+
opts[:parity] = p
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
options.on('-
|
|
34
|
-
opts[:
|
|
33
|
+
options.on('-fFLOWCTRL', '--flow-control=FLOWCTRL', '<Optional - none||hard||soft (defaults to none)>') do |f|
|
|
34
|
+
opts[:flow_control] = f
|
|
35
35
|
end
|
|
36
36
|
end.parse!
|
|
37
37
|
|
|
@@ -41,7 +41,7 @@ if opts.empty?
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
begin
|
|
44
|
-
block_dev = opts[:block_dev]
|
|
44
|
+
block_dev = opts[:block_dev] if File.exist?(opts[:block_dev])
|
|
45
45
|
baud = opts[:baud]
|
|
46
46
|
data_bits = opts[:data_bits]
|
|
47
47
|
stop_bits = opts[:stop_bits]
|
|
@@ -57,10 +57,143 @@ begin
|
|
|
57
57
|
flow_control: flow_control
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
puts "- Welcome to #{File.basename($PROGRAM_NAME)} -"
|
|
61
|
+
puts "Connected via: #{block_dev} @ #{msr206_obj[:serial_conn].modem_params}"
|
|
62
|
+
puts "Flow Control: #{msr206_obj[:serial_conn].flow_control}"
|
|
63
|
+
puts "Signals: #{msr206_obj[:serial_conn].signals}"
|
|
64
|
+
|
|
65
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
61
66
|
msr206_obj: msr206_obj,
|
|
62
67
|
cmd: :simulate_power_cycle_warm_reset
|
|
63
68
|
)
|
|
69
|
+
|
|
70
|
+
# TODO: Parse Binary Bits to Derive Readable Configuration
|
|
71
|
+
# e.g. 'Read & Write All Three Tracks' if binary_resp == '11101111'
|
|
72
|
+
# Probably better to split each bit and then evaluate
|
|
73
|
+
# binary_resp_arr = binary_resp.chars
|
|
74
|
+
# --------------------------------------------------
|
|
75
|
+
# Bit|Bit = 0 |Bit = 1
|
|
76
|
+
# --------------------------------------------------
|
|
77
|
+
# 0 |Track 1 Read not present |Track 1 Read present
|
|
78
|
+
# 1 |Track 2 Read not present |Track 2 Read present
|
|
79
|
+
# 2 |Track 3 Read not present |Track 3 Read present
|
|
80
|
+
# 3 |not used – should be 0 |not used
|
|
81
|
+
# 4 |Track 3 Write not present|Track 3 Write present
|
|
82
|
+
# 5 |Track 2 Write not present|Track 2 Write present
|
|
83
|
+
# 6 |Track 1 Write not present|Track 1 Write present
|
|
84
|
+
# 7 |parity bit** |parity bit**
|
|
85
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
86
|
+
msr206_obj: msr206_obj,
|
|
87
|
+
cmd: :configuration_request
|
|
88
|
+
)
|
|
89
|
+
puts "Configuration Bits: #{exec_resp[:binary].first}"
|
|
90
|
+
|
|
91
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
92
|
+
msr206_obj: msr206_obj,
|
|
93
|
+
cmd: :version_report
|
|
94
|
+
)
|
|
95
|
+
puts "Firmware Version: #{exec_resp[:decoded]}"
|
|
96
|
+
|
|
97
|
+
# Main Menu
|
|
98
|
+
menu_msg = ''
|
|
99
|
+
loop do
|
|
100
|
+
unless menu_msg.include?('ERROR')
|
|
101
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
102
|
+
msr206_obj: msr206_obj,
|
|
103
|
+
cmd: :yellow_on
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
puts "\n>> MAIN MENU OPTIONS:"
|
|
108
|
+
puts '[(R)ead Card]'
|
|
109
|
+
puts '[(C)opy Card]'
|
|
110
|
+
puts '[(E)dit Card]'
|
|
111
|
+
puts '[(B)ackup Card]'
|
|
112
|
+
puts '[(W)arm Reset]'
|
|
113
|
+
puts '[(Q)uit]'
|
|
114
|
+
puts menu_msg
|
|
115
|
+
print 'MAIN MENU OPTION >>> '
|
|
116
|
+
menu_msg = ''
|
|
117
|
+
option = gets.scrub.chomp.strip.upcase.to_sym
|
|
118
|
+
|
|
119
|
+
case option
|
|
120
|
+
when :R
|
|
121
|
+
menu_msg = 'READY TO READ - PLEASE SWIPE CARD'
|
|
122
|
+
# Read Card
|
|
123
|
+
PWN::Plugins::MSR206.wait_for_swipe(
|
|
124
|
+
msr206_obj: msr206_obj,
|
|
125
|
+
type: :arm_to_read
|
|
126
|
+
)
|
|
127
|
+
when :C
|
|
128
|
+
menu_msg = 'READY TO COPY - PLEASE SWIPE ORIGINAL CARD'
|
|
129
|
+
# Read Original Card
|
|
130
|
+
PWN::Plugins::MSR206.wait_for_swipe(
|
|
131
|
+
msr206_obj: msr206_obj,
|
|
132
|
+
type: :arm_to_read
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# TODO: Save Original Card Contents
|
|
136
|
+
# arm_to_write card to clone
|
|
137
|
+
# read cloned card to verify successful write
|
|
138
|
+
when :E
|
|
139
|
+
menu_msg = 'READY TO EDIT - PLEASE SWIPE TARGET CARD'
|
|
140
|
+
# Read Target Card
|
|
141
|
+
PWN::Plugins::MSR206.wait_for_swipe(
|
|
142
|
+
msr206_obj: msr206_obj,
|
|
143
|
+
type: :arm_to_read
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# TODO: Save Original Card Contents
|
|
147
|
+
# arm_to_write card to edit
|
|
148
|
+
# read edited card to verify successful write
|
|
149
|
+
when :B
|
|
150
|
+
menu_msg = 'READY TO BACKUP - PLEASE SWIPE CARD'
|
|
151
|
+
# Read Card
|
|
152
|
+
PWN::Plugins::MSR206.wait_for_swipe(
|
|
153
|
+
msr206_obj: msr206_obj,
|
|
154
|
+
type: :arm_to_read
|
|
155
|
+
)
|
|
156
|
+
when :W
|
|
157
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
158
|
+
msr206_obj: msr206_obj,
|
|
159
|
+
cmd: :simulate_power_cycle_warm_reset
|
|
160
|
+
)
|
|
161
|
+
puts exec_resp.inspect
|
|
162
|
+
when :Q
|
|
163
|
+
exit
|
|
164
|
+
else
|
|
165
|
+
menu_msg = '****** ERROR: Invalid Menu Option Selected ******'
|
|
166
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
167
|
+
msr206_obj: msr206_obj,
|
|
168
|
+
cmd: :yellow_off
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
172
|
+
msr206_obj: msr206_obj,
|
|
173
|
+
cmd: :red_flash
|
|
174
|
+
)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
rescue StandardError => e
|
|
178
|
+
raise e
|
|
64
179
|
rescue SystemExit, Interrupt
|
|
65
180
|
puts "\nGoodbye."
|
|
181
|
+
ensure
|
|
182
|
+
# Lights Off
|
|
183
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
184
|
+
msr206_obj: msr206_obj,
|
|
185
|
+
cmd: :green_off
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
189
|
+
msr206_obj: msr206_obj,
|
|
190
|
+
cmd: :yellow_off
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
194
|
+
msr206_obj: msr206_obj,
|
|
195
|
+
cmd: :red_off
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
msr206_obj = PWN::Plugins::MSR206.disconnect(msr206_obj: msr206_obj) if msr206_obj
|
|
66
199
|
end
|
data/lib/pwn/plugins/msr206.rb
CHANGED
|
@@ -9,9 +9,9 @@ module PWN
|
|
|
9
9
|
# msr206_obj = PWN::Plugins::MSR206.connect(
|
|
10
10
|
# block_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)',
|
|
11
11
|
# baud: 'optional - (defaults to 9600)',
|
|
12
|
-
# data_bits: 'optional - (defaults to
|
|
12
|
+
# data_bits: 'optional - (defaults to 8)',
|
|
13
13
|
# stop_bits: 'optional - (defaults to 1)',
|
|
14
|
-
# parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :
|
|
14
|
+
# parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :none),'
|
|
15
15
|
# flow_control: 'optional - :none||:hard||:soft (defaults to :none)'
|
|
16
16
|
# )
|
|
17
17
|
|
|
@@ -19,9 +19,9 @@ module PWN
|
|
|
19
19
|
# Default Baud Rate for this Device is 19200
|
|
20
20
|
opts[:block_dev] = '/dev/ttyUSB0' unless opts[:block_dev]
|
|
21
21
|
opts[:baud] = 9_600 unless opts[:baud]
|
|
22
|
-
opts[:data_bits] =
|
|
22
|
+
opts[:data_bits] = 8 unless opts[:data_bits]
|
|
23
23
|
opts[:stop_bits] = 1 unless opts[:stop_bits]
|
|
24
|
-
opts[:parity] = :
|
|
24
|
+
opts[:parity] = :none unless opts[:parity]
|
|
25
25
|
opts[:flow_control] = :none unless opts[:flow_control]
|
|
26
26
|
msr206_obj = PWN::Plugins::Serial.connect(opts)
|
|
27
27
|
rescue StandardError => e
|
|
@@ -93,6 +93,241 @@ module PWN
|
|
|
93
93
|
raise e
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
# Supported Method Parameters::
|
|
97
|
+
# parsed_cmd_resp_arr = decode(
|
|
98
|
+
# raw_byte_arr: 'required - raw_byte_arr produced in #parse_responses'
|
|
99
|
+
# )
|
|
100
|
+
|
|
101
|
+
private_class_method def self.decode(opts = {})
|
|
102
|
+
raw_byte_arr = opts[:raw_byte_arr]
|
|
103
|
+
|
|
104
|
+
decoded_data_str = ''
|
|
105
|
+
if raw_byte_arr
|
|
106
|
+
raw_byte_arr.first.split.each do |byte_str|
|
|
107
|
+
case byte_str
|
|
108
|
+
when '1B'
|
|
109
|
+
decoded_data_str += ''
|
|
110
|
+
when '20'
|
|
111
|
+
decoded_data_str += ' '
|
|
112
|
+
when '21'
|
|
113
|
+
decoded_data_str += '!'
|
|
114
|
+
when '22'
|
|
115
|
+
decoded_data_str += '"'
|
|
116
|
+
when '23'
|
|
117
|
+
decoded_data_str += '#'
|
|
118
|
+
when '24'
|
|
119
|
+
decoded_data_str += '$'
|
|
120
|
+
when '25'
|
|
121
|
+
decoded_data_str += '%'
|
|
122
|
+
when '26'
|
|
123
|
+
decoded_data_str += '&'
|
|
124
|
+
when '27'
|
|
125
|
+
decoded_data_str += "'"
|
|
126
|
+
when '28'
|
|
127
|
+
decoded_data_str += '('
|
|
128
|
+
when '29'
|
|
129
|
+
decoded_data_str += ')'
|
|
130
|
+
when '2A', 'AA'
|
|
131
|
+
decoded_data_str += '*'
|
|
132
|
+
when '2B', 'AB'
|
|
133
|
+
decoded_data_str += '+'
|
|
134
|
+
when '2C', 'AC'
|
|
135
|
+
decoded_data_str += ','
|
|
136
|
+
when '2D', 'AD'
|
|
137
|
+
decoded_data_str += '-'
|
|
138
|
+
when '2E', 'AE'
|
|
139
|
+
decoded_data_str += '.'
|
|
140
|
+
when '2F', 'AF'
|
|
141
|
+
decoded_data_str += '/'
|
|
142
|
+
when '30', 'B0'
|
|
143
|
+
decoded_data_str += '0'
|
|
144
|
+
when '31', 'B1'
|
|
145
|
+
decoded_data_str += '1'
|
|
146
|
+
when '32', 'B2'
|
|
147
|
+
decoded_data_str += '2'
|
|
148
|
+
when '33', 'B3'
|
|
149
|
+
decoded_data_str += '3'
|
|
150
|
+
when '34', 'B4'
|
|
151
|
+
decoded_data_str += '4'
|
|
152
|
+
when '35', 'B5'
|
|
153
|
+
decoded_data_str += '5'
|
|
154
|
+
when '36', 'B6'
|
|
155
|
+
decoded_data_str += '6'
|
|
156
|
+
when '37', 'B7'
|
|
157
|
+
decoded_data_str += '7'
|
|
158
|
+
when '38', 'B8'
|
|
159
|
+
decoded_data_str += '8'
|
|
160
|
+
when '39', 'B9'
|
|
161
|
+
decoded_data_str += '9'
|
|
162
|
+
when '3A', 'BA'
|
|
163
|
+
decoded_data_str += ':'
|
|
164
|
+
when '3B', 'BB'
|
|
165
|
+
decoded_data_str += ';'
|
|
166
|
+
when '3C', 'BC'
|
|
167
|
+
decoded_data_str += '<'
|
|
168
|
+
when '3D', 'BD'
|
|
169
|
+
decoded_data_str += '='
|
|
170
|
+
when '3E', 'BE'
|
|
171
|
+
decoded_data_str += '>'
|
|
172
|
+
when '3F', 'BF'
|
|
173
|
+
decoded_data_str += '?'
|
|
174
|
+
when '40', 'C0'
|
|
175
|
+
decoded_data_str += '@'
|
|
176
|
+
when '41', 'C1'
|
|
177
|
+
decoded_data_str += 'A'
|
|
178
|
+
when '42', 'C2'
|
|
179
|
+
decoded_data_str += 'B'
|
|
180
|
+
when '43', 'C3'
|
|
181
|
+
decoded_data_str += 'C'
|
|
182
|
+
when '44', 'C4'
|
|
183
|
+
decoded_data_str += 'D'
|
|
184
|
+
when '45', 'C5'
|
|
185
|
+
decoded_data_str += 'E'
|
|
186
|
+
when '46', 'C6'
|
|
187
|
+
decoded_data_str += 'F'
|
|
188
|
+
when '47', 'C7'
|
|
189
|
+
decoded_data_str += 'G'
|
|
190
|
+
when '48', 'C8'
|
|
191
|
+
decoded_data_str += 'H'
|
|
192
|
+
when '49', 'C9'
|
|
193
|
+
decoded_data_str += 'I'
|
|
194
|
+
when '4A', 'CA'
|
|
195
|
+
decoded_data_str += 'J'
|
|
196
|
+
when '4B', 'CB'
|
|
197
|
+
decoded_data_str += 'K'
|
|
198
|
+
when '4C', 'CC'
|
|
199
|
+
decoded_data_str += 'L'
|
|
200
|
+
when '4D', 'CD'
|
|
201
|
+
decoded_data_str += 'M'
|
|
202
|
+
when '4E', 'CE'
|
|
203
|
+
decoded_data_str += 'N'
|
|
204
|
+
when '4F', 'CF'
|
|
205
|
+
decoded_data_str += 'O'
|
|
206
|
+
when '50', 'D0'
|
|
207
|
+
decoded_data_str += 'P'
|
|
208
|
+
when '51', 'D1'
|
|
209
|
+
decoded_data_str += 'Q'
|
|
210
|
+
when '52', 'D2'
|
|
211
|
+
decoded_data_str += 'R'
|
|
212
|
+
when '53', 'D3'
|
|
213
|
+
decoded_data_str += 'S'
|
|
214
|
+
when '54', 'D4'
|
|
215
|
+
decoded_data_str += 'T'
|
|
216
|
+
when '55', 'D5'
|
|
217
|
+
decoded_data_str += 'U'
|
|
218
|
+
when '56', 'D6'
|
|
219
|
+
decoded_data_str += 'V'
|
|
220
|
+
when '57', 'D7'
|
|
221
|
+
decoded_data_str += 'W'
|
|
222
|
+
when '58', 'D8'
|
|
223
|
+
decoded_data_str += 'X'
|
|
224
|
+
when '59', 'D9'
|
|
225
|
+
decoded_data_str += 'Y'
|
|
226
|
+
when '5A', 'DA'
|
|
227
|
+
decoded_data_str += 'Z'
|
|
228
|
+
when '5B', 'DB'
|
|
229
|
+
decoded_data_str += '['
|
|
230
|
+
when '5C', 'DC'
|
|
231
|
+
decoded_data_str += '\\'
|
|
232
|
+
when '5D', 'DD'
|
|
233
|
+
decoded_data_str += ']'
|
|
234
|
+
when '5E', 'DE'
|
|
235
|
+
decoded_data_str += '^'
|
|
236
|
+
when '5F', 'DF'
|
|
237
|
+
decoded_data_str += '_'
|
|
238
|
+
when '60', 'E0'
|
|
239
|
+
decoded_data_str += '`'
|
|
240
|
+
when '61', 'E1'
|
|
241
|
+
decoded_data_str += 'a'
|
|
242
|
+
when '62', 'E2'
|
|
243
|
+
decoded_data_str += 'b'
|
|
244
|
+
when '63', 'E3'
|
|
245
|
+
decoded_data_str += 'c'
|
|
246
|
+
when '64', 'E4'
|
|
247
|
+
decoded_data_str += 'd'
|
|
248
|
+
when '65', 'E5'
|
|
249
|
+
decoded_data_str += 'e'
|
|
250
|
+
when '66', 'E6'
|
|
251
|
+
decoded_data_str += 'f'
|
|
252
|
+
when '67', 'E7'
|
|
253
|
+
decoded_data_str += 'g'
|
|
254
|
+
when '68', 'E8'
|
|
255
|
+
decoded_data_str += 'h'
|
|
256
|
+
when '69', 'E9'
|
|
257
|
+
decoded_data_str += 'i'
|
|
258
|
+
when '6A', 'EA'
|
|
259
|
+
decoded_data_str += 'j'
|
|
260
|
+
when '6B', 'EB'
|
|
261
|
+
decoded_data_str += 'k'
|
|
262
|
+
when '6C', 'EC'
|
|
263
|
+
decoded_data_str += 'l'
|
|
264
|
+
when '6D', 'ED'
|
|
265
|
+
decoded_data_str += 'm'
|
|
266
|
+
when '6E', 'EE'
|
|
267
|
+
decoded_data_str += 'n'
|
|
268
|
+
when '6F', 'EF'
|
|
269
|
+
decoded_data_str += 'o'
|
|
270
|
+
when '70', 'F0'
|
|
271
|
+
decoded_data_str += 'p'
|
|
272
|
+
when '71', 'F1'
|
|
273
|
+
decoded_data_str += 'q'
|
|
274
|
+
when '72', 'F2'
|
|
275
|
+
decoded_data_str += 'r'
|
|
276
|
+
when '73', 'F3'
|
|
277
|
+
decoded_data_str += 's'
|
|
278
|
+
when '74', 'F4'
|
|
279
|
+
decoded_data_str += 't'
|
|
280
|
+
when '75', 'F5'
|
|
281
|
+
decoded_data_str += 'u'
|
|
282
|
+
when '76', 'F6'
|
|
283
|
+
decoded_data_str += 'v'
|
|
284
|
+
when '77', 'F7'
|
|
285
|
+
decoded_data_str += 'w'
|
|
286
|
+
when '78', 'F8'
|
|
287
|
+
decoded_data_str += 'x'
|
|
288
|
+
when '79', 'F9'
|
|
289
|
+
decoded_data_str += 'y'
|
|
290
|
+
when '7A', 'FA'
|
|
291
|
+
decoded_data_str += 'z'
|
|
292
|
+
when '7B', 'FB'
|
|
293
|
+
decoded_data_str += '{'
|
|
294
|
+
when '7C', 'FC'
|
|
295
|
+
decoded_data_str += '|'
|
|
296
|
+
when '7D', 'FD'
|
|
297
|
+
decoded_data_str += '}'
|
|
298
|
+
when '7E', 'FE'
|
|
299
|
+
decoded_data_str += '~'
|
|
300
|
+
else
|
|
301
|
+
decoded_data_str += "\u00BF"
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
decoded_data_str
|
|
307
|
+
rescue StandardError => e
|
|
308
|
+
raise e
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Supported Method Parameters::
|
|
312
|
+
# parsed_cmd_resp_arr = binary(
|
|
313
|
+
# raw_byte_arr: 'required - raw_byte_arr produced in #parse_responses'
|
|
314
|
+
# )
|
|
315
|
+
|
|
316
|
+
private_class_method def self.binary(opts = {})
|
|
317
|
+
raw_byte_arr = opts[:raw_byte_arr]
|
|
318
|
+
|
|
319
|
+
binary_byte_arr = []
|
|
320
|
+
if raw_byte_arr
|
|
321
|
+
raw_byte_arr.first.split.each do |byte_str|
|
|
322
|
+
binary_byte_arr.push([byte_str].pack('H*').unpack('B*').first.reverse)
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
binary_byte_arr
|
|
327
|
+
rescue StandardError => e
|
|
328
|
+
raise e
|
|
329
|
+
end
|
|
330
|
+
|
|
96
331
|
# Supported Method Parameters::
|
|
97
332
|
# parsed_cmd_resp_arr = parse_responses(
|
|
98
333
|
# cmd_resp: 'required - command response string'
|
|
@@ -100,11 +335,15 @@ module PWN
|
|
|
100
335
|
|
|
101
336
|
private_class_method def self.parse_responses(opts = {})
|
|
102
337
|
msr206_obj = opts[:msr206_obj]
|
|
103
|
-
cmd = opts[:cmd]
|
|
338
|
+
cmd = opts[:cmd]
|
|
104
339
|
|
|
105
340
|
keep_parsing_responses = true
|
|
106
341
|
next_response_detected = false
|
|
107
|
-
|
|
342
|
+
response = {}
|
|
343
|
+
response[:cmd] = cmd
|
|
344
|
+
response[:cmd] ||= :na
|
|
345
|
+
|
|
346
|
+
raw_byte_arr = []
|
|
108
347
|
a_cmd_r_len = 0
|
|
109
348
|
last_a_cmd_r_len = 0
|
|
110
349
|
|
|
@@ -114,26 +353,58 @@ module PWN
|
|
|
114
353
|
|
|
115
354
|
while keep_parsing_responses
|
|
116
355
|
until next_response_detected
|
|
117
|
-
|
|
118
|
-
cmd_resp =
|
|
356
|
+
raw_byte_arr = PWN::Plugins::Serial.response(serial_obj: msr206_obj)
|
|
357
|
+
cmd_resp = raw_byte_arr.last
|
|
119
358
|
bytes_in_cmd_resp = cmd_resp.split.length if cmd_resp
|
|
120
|
-
a_cmd_r_len =
|
|
359
|
+
a_cmd_r_len = raw_byte_arr.length
|
|
121
360
|
|
|
122
361
|
next_response_detected = true if a_cmd_r_len > last_a_cmd_r_len
|
|
123
362
|
end
|
|
124
363
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
364
|
+
case cmd_resp
|
|
365
|
+
when '21', 'A1'
|
|
366
|
+
response[:msg] = :invalid_command
|
|
367
|
+
when '28', 'A8'
|
|
368
|
+
response[:msg] = :card_speed_measurement_start
|
|
369
|
+
when '29', 'A9'
|
|
370
|
+
response[:msg] = :card_speed_measurement_end
|
|
371
|
+
when '2A', 'AA'
|
|
372
|
+
response[:msg] = :error
|
|
373
|
+
when '2B', 'AB'
|
|
374
|
+
response[:msg] = :no_data_found
|
|
375
|
+
when '2D', 'AD'
|
|
376
|
+
response[:msg] = :insufficient_leading_zeros_for_custom_writing
|
|
377
|
+
when '2F', 'AF'
|
|
378
|
+
response[:msg] = :first_lsb_char_not_one_for_custom_writing
|
|
379
|
+
when '31', 'B1'
|
|
380
|
+
response[:msg] = :unsuccessful_read_after_write_track1
|
|
381
|
+
when '32', 'B2'
|
|
382
|
+
response[:msg] = :unsuccessful_read_after_write_track2
|
|
383
|
+
when '33', 'B3'
|
|
384
|
+
response[:msg] = :unsuccessful_read_after_write_track3
|
|
385
|
+
when '3A', 'BA'
|
|
386
|
+
response[:msg] = :power_on_report
|
|
387
|
+
when '3E', 'BE'
|
|
388
|
+
response[:msg] = :card_edge_detected
|
|
389
|
+
when '3F', 'BF'
|
|
390
|
+
response[:msg] = :communications_error
|
|
391
|
+
when '5E'
|
|
392
|
+
response[:msg] = :ack_command_completed
|
|
393
|
+
when '7E'
|
|
394
|
+
response[:msg] = :command_not_supported_by_hardware
|
|
395
|
+
else
|
|
396
|
+
response[:msg] = :na
|
|
397
|
+
end
|
|
398
|
+
|
|
130
399
|
next_response_detected = false
|
|
131
400
|
last_a_cmd_r_len = a_cmd_r_len
|
|
132
|
-
print "\n"
|
|
133
401
|
keep_parsing_responses = false
|
|
134
402
|
end
|
|
135
403
|
|
|
136
|
-
|
|
404
|
+
response[:raw] = raw_byte_arr
|
|
405
|
+
response[:binary] = binary(raw_byte_arr: raw_byte_arr)
|
|
406
|
+
response[:decoded] = decode(raw_byte_arr: raw_byte_arr)
|
|
407
|
+
response
|
|
137
408
|
rescue StandardError => e
|
|
138
409
|
raise e
|
|
139
410
|
ensure
|
|
@@ -281,6 +552,123 @@ module PWN
|
|
|
281
552
|
PWN::Plugins::Serial.flush_session_data
|
|
282
553
|
end
|
|
283
554
|
|
|
555
|
+
# Supported Method Parameters::
|
|
556
|
+
# PWN::Plugins::MSR206.wait_for_swipe(
|
|
557
|
+
# msr206_obj: 'required - msr206_obj returned from #connect method'
|
|
558
|
+
# )
|
|
559
|
+
|
|
560
|
+
public_class_method def self.wait_for_swipe(opts = {})
|
|
561
|
+
msr206_obj = opts[:msr206_obj]
|
|
562
|
+
type = opts[:type].to_s.scrub.strip.chomp.to_sym
|
|
563
|
+
types_arr = %i[
|
|
564
|
+
arm_to_read
|
|
565
|
+
arm_to_read_w_speed_prompts
|
|
566
|
+
arm_to_write_no_raw
|
|
567
|
+
arm_to_write_with_raw
|
|
568
|
+
arm_to_write_with_raw_speed_prompts
|
|
569
|
+
]
|
|
570
|
+
|
|
571
|
+
raise "ERROR Unsupported type in #wait_for_swipe - #{type}. Valid types:\n#{types_arr}" unless types_arr.include?(type)
|
|
572
|
+
|
|
573
|
+
exec_resp = exec(
|
|
574
|
+
msr206_obj: msr206_obj,
|
|
575
|
+
cmd: :red_off
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
exec_resp = exec(
|
|
579
|
+
msr206_obj: msr206_obj,
|
|
580
|
+
cmd: :yellow_off
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
584
|
+
msr206_obj: msr206_obj,
|
|
585
|
+
cmd: type
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
exec_resp = exec(
|
|
589
|
+
msr206_obj: msr206_obj,
|
|
590
|
+
cmd: :green_on
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
exec_resp = PWN::Plugins::MSR206.exec(
|
|
594
|
+
msr206_obj: msr206_obj,
|
|
595
|
+
cmd: :card_edge_detect
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
print 'Ready. Please Swipe Card Now:'
|
|
599
|
+
loop do
|
|
600
|
+
exec_resp = parse_responses(
|
|
601
|
+
msr206_obj: msr206_obj,
|
|
602
|
+
cmd: :card_edge_detect
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
break if exec_resp[:msg] == :ack_command_completed
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
puts "\n*** ISO Track Format: Standard #{'*' * 17}"
|
|
609
|
+
print 'TRACK 1 >>> '
|
|
610
|
+
exec_resp = exec(
|
|
611
|
+
msr206_obj: msr206_obj,
|
|
612
|
+
cmd: :tx_iso_std_data_track1
|
|
613
|
+
)
|
|
614
|
+
puts exec_resp[:decoded]
|
|
615
|
+
puts exec_resp.inspect
|
|
616
|
+
|
|
617
|
+
# (1..3).each do |n|
|
|
618
|
+
# print ">> Track 1 (ALT DATA) ISO Track Format: #{n}\n"
|
|
619
|
+
# exec_resp = exec(
|
|
620
|
+
# msr206_obj: msr206_obj,
|
|
621
|
+
# cmd: :alt_tx_iso_std_data_track1,
|
|
622
|
+
# params: [n.to_s]
|
|
623
|
+
# )
|
|
624
|
+
# puts exec_resp.inspect
|
|
625
|
+
# end
|
|
626
|
+
|
|
627
|
+
print "\nTRACK 2 >>> "
|
|
628
|
+
exec_resp = exec(
|
|
629
|
+
msr206_obj: msr206_obj,
|
|
630
|
+
cmd: :tx_iso_std_data_track2
|
|
631
|
+
)
|
|
632
|
+
puts exec_resp[:decoded]
|
|
633
|
+
puts exec_resp.inspect
|
|
634
|
+
|
|
635
|
+
# (1..3).each do |n|
|
|
636
|
+
# print ">> Track 2 (ALT DATA) ISO Track Format: #{n}\n"
|
|
637
|
+
# exec_resp = exec(
|
|
638
|
+
# msr206_obj: msr206_obj,
|
|
639
|
+
# cmd: :alt_tx_iso_std_data_track2,
|
|
640
|
+
# params: [n.to_s]
|
|
641
|
+
# )
|
|
642
|
+
# puts exec_resp.inspect
|
|
643
|
+
# end
|
|
644
|
+
|
|
645
|
+
print "\nTRACK 3 >>> "
|
|
646
|
+
exec_resp = exec(
|
|
647
|
+
msr206_obj: msr206_obj,
|
|
648
|
+
cmd: :tx_iso_std_data_track3
|
|
649
|
+
)
|
|
650
|
+
puts exec_resp[:decoded]
|
|
651
|
+
puts exec_resp.inspect
|
|
652
|
+
|
|
653
|
+
# (1..3).each do |n|
|
|
654
|
+
# print ">> Track 3 (ALT DATA) ISO Track Format: #{n}\n"
|
|
655
|
+
# exec_resp = exec(
|
|
656
|
+
# msr206_obj: msr206_obj,
|
|
657
|
+
# cmd: :alt_tx_iso_std_data_track3,
|
|
658
|
+
# params: [n.to_s]
|
|
659
|
+
# )
|
|
660
|
+
# puts exec_resp.inspect
|
|
661
|
+
# end
|
|
662
|
+
|
|
663
|
+
rescue StandardError => e
|
|
664
|
+
raise e
|
|
665
|
+
ensure
|
|
666
|
+
exec_resp = exec(
|
|
667
|
+
msr206_obj: msr206_obj,
|
|
668
|
+
cmd: :green_off
|
|
669
|
+
)
|
|
670
|
+
end
|
|
671
|
+
|
|
284
672
|
# Supported Method Parameters::
|
|
285
673
|
# PWN::Plugins::MSR206.disconnect(
|
|
286
674
|
# msr206_obj: 'required - msr206_obj returned from #connect method'
|
|
@@ -309,9 +697,9 @@ module PWN
|
|
|
309
697
|
msr206_obj = #{self}.connect(
|
|
310
698
|
block_dev: 'optional serial block device path (defaults to /dev/ttyUSB0)',
|
|
311
699
|
baud: 'optional (defaults to 9600)',
|
|
312
|
-
data_bits: 'optional (defaults to
|
|
700
|
+
data_bits: 'optional (defaults to 8)',
|
|
313
701
|
stop_bits: 'optional (defaults to 1)',
|
|
314
|
-
parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :
|
|
702
|
+
parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :none),'
|
|
315
703
|
flow_control: 'optional - :none||:hard||:soft (defaults to :none)'
|
|
316
704
|
)
|
|
317
705
|
|
data/lib/pwn/version.rb
CHANGED
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.466
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-06-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - '='
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 3.0.
|
|
47
|
+
version: 3.0.1
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - '='
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 3.0.
|
|
54
|
+
version: 3.0.1
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: aws-sdk
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,14 +114,14 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - ">="
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 2.3.
|
|
117
|
+
version: 2.3.15
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 2.3.
|
|
124
|
+
version: 2.3.15
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: bundler-audit
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -968,14 +968,14 @@ dependencies:
|
|
|
968
968
|
requirements:
|
|
969
969
|
- - '='
|
|
970
970
|
- !ruby/object:Gem::Version
|
|
971
|
-
version: 0.9.
|
|
971
|
+
version: 0.9.28
|
|
972
972
|
type: :runtime
|
|
973
973
|
prerelease: false
|
|
974
974
|
version_requirements: !ruby/object:Gem::Requirement
|
|
975
975
|
requirements:
|
|
976
976
|
- - '='
|
|
977
977
|
- !ruby/object:Gem::Version
|
|
978
|
-
version: 0.9.
|
|
978
|
+
version: 0.9.28
|
|
979
979
|
description: https://github.com/0dayinc/pwn/README.md
|
|
980
980
|
email:
|
|
981
981
|
- request.pentest@0dayinc.com
|