pwn 0.4.463 → 0.4.466

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a39a74b8bc26847795f54fdcbd7f48eb5a38c2587da0d233e74bd96a8267c9a9
4
- data.tar.gz: fa37dda7a5e16dc6743da3930b5278d83077e2ba100d65566eef9fd39c373967
3
+ metadata.gz: b22a31f1952951d9c3bd1a8dd912b58e1b6ccf39d93a55327b10e285729e67de
4
+ data.tar.gz: a15ab49fbf548031599248380aca04bb05e9220357d771d27de63d477af33038
5
5
  SHA512:
6
- metadata.gz: e08cddc2558b06ed364a65dd058f94d75f2b02241a8adf613818c992ad038e8bb5f23b30d59e8f9061a3d1538a817697eabf4985f484f4076827e4fbbbe28ddc
7
- data.tar.gz: 2b098194d45038d7cc85ba1653a3aa85bb432de6049fcebbcc58575a982eb02b31c4757d425c984e60c88a07a6a62868c411ed52043d79dff649052e65a3c27f
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-08 06:06:43 UTC using RuboCop version 1.29.0.
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: 227
9
+ # Offense count: 234
10
10
  Lint/UselessAssignment:
11
11
  Enabled: false
12
12
 
13
- # Offense count: 246
13
+ # Offense count: 253
14
14
  # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
15
15
  Metrics/AbcSize:
16
16
  Max: 328
17
17
 
18
- # Offense count: 60
18
+ # Offense count: 63
19
19
  # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
20
20
  # IgnoredMethods: refine
21
21
  Metrics/BlockLength:
22
- Max: 194
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: 83
29
+ # Offense count: 89
30
30
  # Configuration parameters: IgnoredMethods.
31
31
  Metrics/CyclomaticComplexity:
32
32
  Max: 231
33
33
 
34
- # Offense count: 440
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: 33
39
+ # Offense count: 34
40
40
  # Configuration parameters: CountComments, CountAsOne.
41
41
  Metrics/ModuleLength:
42
42
  Max: 1186
43
43
 
44
- # Offense count: 75
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: 281
54
- # This cop supports safe auto-correction (--auto-correct).
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 auto-correction (--auto-correct).
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 auto-correction (--auto-correct).
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 auto-correction (--auto-correct-all).
74
+ # This cop supports unsafe autocorrection (--autocorrect-all).
75
75
  Style/SlicingWithRange:
76
76
  Enabled: false
77
77
 
78
- # Offense count: 531
79
- # This cop supports safe auto-correction (--auto-correct).
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.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.14'
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.27'
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.463]:001 >>> PWN.help
40
+ pwn[v0.4.466]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](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.463]:001 >>> PWN.help
55
+ pwn[v0.4.466]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
 
@@ -14,24 +14,24 @@ OptionParser.new do |options|
14
14
  opts[:block_dev] = d
15
15
  end
16
16
 
17
- options.on('-bBAUD', '--baud=DEV', '<Optional - (defaults to 9600)>') do |d|
18
- opts[:block_dev] = d
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 7)>') do |d|
22
- opts[:block_dev] = d
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 |d|
26
- opts[:block_dev] = d
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 - :even|:mark|:odd|:space|:none (defaults to :odd)>') do |d|
30
- opts[:block_dev] = d
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('-fFLOW', '--flow-control=FLOW', '<Optional - :none||:hard||:soft (defaults to :none)>') do |d|
34
- opts[:block_dev] = d
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
- serial_resp = PWN::Plugins::MSR206.exec(
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
@@ -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 7)',
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 :odd),'
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] = 7 unless 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] = :odd unless 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].to_s.scrub.strip.chomp
338
+ cmd = opts[:cmd]
104
339
 
105
340
  keep_parsing_responses = true
106
341
  next_response_detected = false
107
- all_cmd_responses = []
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
- all_cmd_responses = PWN::Plugins::Serial.response(serial_obj: msr206_obj)
118
- cmd_resp = all_cmd_responses.last
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 = all_cmd_responses.length
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
- # cmd_resp = all_cmd_responses.last
126
- # case cmd_resp
127
- # when '21', '28', '29', '2A', '2B', '2D', '2F', '3A', '31', '32', '33', '3E', '3F', '5E', '7E', '98 FE'
128
- # next_response_detected = true
129
- # end
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
- all_cmd_responses
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 7)',
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 :odd),'
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.4.463'
4
+ VERSION = '0.4.466'
5
5
  end
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.463
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-05-26 00:00:00.000000000 Z
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.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.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.14
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.14
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.27
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.27
978
+ version: 0.9.28
979
979
  description: https://github.com/0dayinc/pwn/README.md
980
980
  email:
981
981
  - request.pentest@0dayinc.com