Module: PWN::Plugins::SonMicroRFID

Defined in:
lib/pwn/plugins/son_micro_rfid.rb

Overview

This plugin is used for interacting with a SonMicro SM132 USB RFID Reader / Writer (PCB V3) && SM2330-USB Rev.0

Class Method Summary collapse

Class Method Details

.authorsObject

Author(s)

0day Inc. <[email protected]>



464
465
466
467
468
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 464

public_class_method def self.authors
  "AUTHOR(S):
    0day Inc. <[email protected]>
  "
end

.backup_card(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.backup_card(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'

)



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 379

public_class_method def self.backup_card(opts = {})
  son_micro_rfid_obj = opts[:son_micro_rfid_obj]
  rfid_data = read_card(son_micro_rfid_obj: son_micro_rfid_obj)
  file = ''
  backup_msg = ''
  loop do
    print 'Enter File Name to Save Backup: '
    file = gets.scrub.chomp.strip
    file_dir = File.dirname(file)
    break if Dir.exist?(file_dir)

    backup_msg = "\n****** ERROR: Directory #{file_dir} for #{file} does not exist ******"
    puts backup_msg
  end
  File.write(file, "#{JSON.pretty_generate(rfid_data)}\n")

  puts 'complete.'
  rfid_data
rescue StandardError => e
  raise e
end

.connect(opts = {}) ⇒ Object

Supported Method Parameters

son_micro_rfid_obj = PWN::Plugins::SonMicroRFID.connect(

block_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)',
baud: 'optional - (defaults to 19_200)',
data_bits: 'optional - (defaults to 8)',
stop_bits: 'optional - (defaults to 1)',
parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :none)',
flow_control: 'optional - :none||:hard||:soft (defaults to :none)'

)



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 19

public_class_method def self.connect(opts = {})
  # Default Baud Rate for this Device is 19200
  opts[:block_dev] = '/dev/ttyUSB0' unless opts[:block_dev]
  opts[:baud] = 19_200 unless opts[:baud]
  opts[:data_bits] = 8 unless opts[:data_bits]
  opts[:stop_bits] = 1 unless opts[:stop_bits]
  opts[:parity] = :none unless opts[:parity]
  opts[:flow_control] = :none unless opts[:flow_control]
  son_micro_rfid_obj = PWN::Plugins::Serial.connect(opts)
rescue StandardError => e
  disconnect(son_micro_rfid_obj: son_micro_rfid_obj) unless son_micro_rfid_obj.nil?
  raise e
end

.copy_card(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.copy_card(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'

)



406
407
408
409
410
411
412
413
414
415
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 406

public_class_method def self.copy_card(opts = {})
  son_micro_rfid_obj = opts[:son_micro_rfid_obj]
  rfid_data = read_card(son_micro_rfid_obj: son_micro_rfid_obj)
  write_card(
    son_micro_rfid_obj: son_micro_rfid_obj,
    rfid_data: rfid_data
  )
rescue StandardError => e
  raise e
end

.disconnect(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.disconnect(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'

)



454
455
456
457
458
459
460
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 454

public_class_method def self.disconnect(opts = {})
  PWN::Plugins::Serial.disconnect(
    serial_obj: opts[:son_micro_rfid_obj]
  )
rescue StandardError => e
  raise e
end

.exec(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.exec(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'
cmd: 'required - cmd returned from #list_cmds method',
params: 'optional - parameters for specific command returned from #list_params method'

)



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 243

public_class_method def self.exec(opts = {})
  son_micro_rfid_obj = opts[:son_micro_rfid_obj]
  cmd = opts[:cmd].to_s.scrub.strip.chomp
  params = opts[:params].to_s.scrub.strip.chomp

  params_bytes = []

  # Use the Mifare Panel Application to reverse enginner commands.
  case cmd.to_sym
  when :reset
    cmd_bytes = [0xFF, 0x00, 0x01, 0x80, 0x81]
  when :firmware
    cmd_bytes = [0xFF, 0x00, 0x01, 0x81, 0x82]
  when :seek_for_tag
    cmd_bytes = [0xFF, 0x00, 0x01, 0x82, 0x83]
  when :select_tag
    cmd_bytes = [0xFF, 0x00, 0x01, 0x83, 0x84]
  when :authenticate
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x00]
  when :read_block
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x01]
  when :write_block
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x02]
  when :write_value
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x03]
  when :write_four_byte_block
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x04]
  when :write_key
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x05]
  when :increment
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x06]
  when :decrement
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x00, 0x07]
  when :antenna_power
    cmd_bytes = [0xFF, 0x00, 0x02, 0x90]
    case params.to_sym
    when :off
      params_bytes = [0x00, 0x92]
    when :on
      params_bytes = [0x01, 0x93]
    when :reset
      params_bytes = [0x02, 0x94]
    else
      raise "Unsupported Parameters: #{params} for #{cmd}.  Supported parameters for #{cmd} are:\n#{list_params(cmd: cmd)}\n\n\n"
    end
  when :read_port
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01]
  when :write_port
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x08]
  when :halt
    cmd_bytes = [0xFF, 0x00, 0x01, 0x93, 0x94]
  when :set_baud_rate
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x09]
  when :sleep
    # Last two bytes not correct
    cmd_bytes = [0xFF, 0x00, 0x01, 0x0a]
  when :poll_buffer
    cmd_bytes = [0xFF, 0x00, 0x01, 0xB0, 0xB1]
  else
    raise "Unsupported Command: #{cmd}.  Supported commands are:\n#{list_cmds}\n\n\n"
  end

  # If parameters to a command are set, append them.
  cmd_bytes += params_bytes unless params_bytes.empty?
  # Execute the command.
  PWN::Plugins::Serial.request(
    serial_obj: son_micro_rfid_obj,
    payload: cmd_bytes
  )

  # Parse commands response(s).
  # Return an array of hashes.
  parse_responses(
    son_micro_rfid_obj: son_micro_rfid_obj,
    cmd: cmd.to_sym
  )
rescue StandardError => e
  raise e
ensure
  # Flush Responses for Next Request
  PWN::Plugins::Serial.flush_session_data
end

.helpObject

Display Usage for this Module



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 472

public_class_method def self.help
  puts "USAGE:
    son_micro_rfid_obj = #{self}.connect(
      block_dev: 'optional serial block device path (defaults to /dev/ttyUSB0)',
      baud: 'optional (defaults to 19_200)',
      data_bits: 'optional (defaults to 8)',
      stop_bits: 'optional (defaults to 1)',
      parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :odd),'
      flow_control: 'optional - :none||:hard||:soft (defaults to :none)'
    )

    cmds = #{self}.list_cmds

    params = #{self}.list_params(
      cmd: 'required - cmd returned from #list_cmds method',
    )

    parsed_cmd_resp_arr = #{self}.exec(
      son_micro_rfid_obj: 'required son_micro_rfid_obj returned from #connect method',
      cmd: 'required - cmd returned from #list_cmds method',
      params: 'optional - parameters for specific command returned from #list_params method'
    )

    #{self}.disconnect(
      son_micro_rfid_obj: 'required son_micro_rfid_obj returned from #connect method'
    )

    #{self}.authors
  "
end

.list_cmdsObject

Supported Method Parameters

cmds = PWN::Plugins::SonMicroRFID.list_cmds



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 35

public_class_method def self.list_cmds
  # Returns an Array of Symbols
  cmds = %i[
    reset
    firmware
    seek_for_tag
    select_tag
    authenticate
    read_block
    write_block
    write_value
    write_four_byte_block
    write_key
    increment
    decrement
    antenna_power
    read_port
    write_port
    halt
    set_baud_rate
    sleep
    poll_buffer
  ]
rescue StandardError => e
  raise e
end

.list_params(opts = {}) ⇒ Object

Supported Method Parameters

params = PWN::Plugins::SonMicroRFID.list_params(

cmd: 'required - cmd returned from #list_cmds method',

)



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 66

public_class_method def self.list_params(opts = {})
  cmd = opts[:cmd].to_s.scrub.strip.chomp

  case cmd.to_sym
  when :reset
    params = %i[reset_not_implemented]
  when :firmware
    params = %i[firmware_not_implemented]
  when :seek_for_tag
    params = %i[seek_for_tag_no_params_required]
  when :select_tag
    params = %i[select_tag_no_params_required]
  when :authenticate
    params = %i[authenticate_not_implemented]
  when :read_block
    params = %i[read_block_not_implemented]
  when :write_block
    params = %i[write_block_not_implemented]
  when :write_value
    params = %i[write_value_not_implemented]
  when :write_four_byte_block
    params = %i[write_four_byte_block_not_implemented]
  when :write_key
    params = %i[write_key_not_implemented]
  when :increment
    params = %i[increment_not_implemented]
  when :decrement
    params = %i[decrement_not_implemented]
  when :antenna_power
    params = %i[off on reset]
  when :read_port
    params = %i[antenna_power_not_implemented]
  when :write_port
    params = %i[write_port_not_implemented]
  when :halt
    params = %i[halt_not_implemented]
  when :set_baud_rate
    params = %i[set_baud_rate_not_implemented]
  when :sleep
    params = %i[sleep_not_implemented]
  when :poll_buffer
    params = %i[poll_buffer_not_implemented]
  else
    raise "Unsupported Command: #{cmd}.  Supported commands are:\n#{list_cmds}\n\n\n"
  end

  params
rescue StandardError => e
  raise e
end

.load_card_from_file(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.load_card_from_file(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'

)



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 422

public_class_method def self.load_card_from_file(opts = {})
  son_micro_rfid_obj = opts[:son_micro_rfid_obj]
  file = ''
  restore_msg = ''
  loop do
    print 'Enter File Name to Restore to Card: '
    file = gets.scrub.chomp.strip
    break if File.exist?(file)

    restore_msg = "\n****** ERROR: #{file} does not exist ******"
    puts restore_msg
  end

  rfid_data = JSON.parse(
    File.read(file),
    symbolize_names: true
  )

  # TODO: Save Original Card Contents
  write_card(
    son_micro_rfid_obj: son_micro_rfid_obj,
    rfid_data: rfid_data
  )
rescue StandardError => e
  raise e
end

.read_card(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.read_card(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'

)



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 342

public_class_method def self.read_card(opts = {})
  son_micro_rfid_obj = opts[:son_micro_rfid_obj]
  print 'Reader Activated.  Please Scan Card...'
  exec_resp = exec(
    son_micro_rfid_obj: son_micro_rfid_obj,
    cmd: :seek_for_tag
  )

  rfid_data = exec_resp.last
  puts "#{rfid_data[:resp_code_desc]} >>> #{rfid_data[:tag_id]}"

  rfid_data
rescue StandardError => e
  raise e
end

.write_card(opts = {}) ⇒ Object

Supported Method Parameters

PWN::Plugins::SonMicroRFID.write_card(

son_micro_rfid_obj: 'required - son_micro_rfid_obj returned from #connect method'

)



363
364
365
366
367
368
369
370
371
372
# File 'lib/pwn/plugins/son_micro_rfid.rb', line 363

public_class_method def self.write_card(opts = {})
  son_micro_rfid_obj = opts[:son_micro_rfid_obj]
  rfid_data = opts[:rfid_data]
  # TODO: write card
  puts rfid_data.inspect

  rfid_data
rescue StandardError => e
  raise e
end