Merge the DECT code from DK, clean some things up
git-svn-id: file:///home/svn/framework3/trunk@7032 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
b0d1c2681f
commit
0885a7262e
|
@ -245,6 +245,7 @@ class Exploit < Msf::Module
|
||||||
|
|
||||||
# Telephony
|
# Telephony
|
||||||
require 'msf/core/exploit/dialup'
|
require 'msf/core/exploit/dialup'
|
||||||
|
require 'msf/core/exploit/dect_coa'
|
||||||
|
|
||||||
# Networks
|
# Networks
|
||||||
require 'msf/core/exploit/lorcon'
|
require 'msf/core/exploit/lorcon'
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# This modules provides methods for interacting with a Com-On-Air DECT device
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Exploit::DECT_COA
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
DECT_BAND_EMEA = 0x01
|
||||||
|
DECT_BAND_US = 0x02
|
||||||
|
DECT_BAND_BOTH = 0x03
|
||||||
|
|
||||||
|
COA_MODE_IDLE = 0x0000
|
||||||
|
COA_MODE_FP = 0x0100
|
||||||
|
COA_MODE_PP = 0x0200
|
||||||
|
COA_MODE_SNIFF = 0x0300
|
||||||
|
COA_MODE_JAM = 0x0400
|
||||||
|
COA_MODE_EEPROM = 0x0500
|
||||||
|
|
||||||
|
COA_SUBMODE_SNIFF_SCANFP = 0x0001
|
||||||
|
COA_SUBMODE_SNIFF_SCANPP = 0x0002
|
||||||
|
COA_SUBMODE_SNIFF_SYNC = 0x0003
|
||||||
|
|
||||||
|
COA_IOCTL_MODE = 0xD000
|
||||||
|
COA_IOCTL_RADIO = 0xD001
|
||||||
|
COA_IOCTL_RX = 0xD002
|
||||||
|
COA_IOCTL_TX = 0xD003
|
||||||
|
COA_IOCTL_CHAN = 0xD004
|
||||||
|
COA_IOCTL_SLOT = 0xD005
|
||||||
|
COA_IOCTL_RSSI = 0xD006
|
||||||
|
COA_IOCTL_FIRMWARE = 0xD007
|
||||||
|
COA_IOCTL_SETRFPI = 0xD008
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('INTERFACE', [true, 'The name of the Com-On-Air Interface', '/dev/coa']),
|
||||||
|
OptString.new('BAND', [true, 'DECT band', DECT_BAND_US]),
|
||||||
|
OptString.new('CHAN', [false, 'DECT channel', 0]),
|
||||||
|
OptString.new('RFPI', [false, 'RFPI for synchronous scan', nil])
|
||||||
|
], Msf::Exploit::DECT_COA
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_coa
|
||||||
|
|
||||||
|
close_coa if self.dect_device
|
||||||
|
|
||||||
|
begin
|
||||||
|
self.dect_device = File.open(datastore['INTERFACE'], "w+")
|
||||||
|
rescue ::Exception => e
|
||||||
|
print_error("Could not open the Com-On-Air device at #{datastore['INTERFACE']}")
|
||||||
|
print_error("This module only works on Linux with the appropriate hardware and driver, while running as root")
|
||||||
|
raise RuntimeError, "Could not open the Com-On-Air device: #{e}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def close_coa
|
||||||
|
self.dect_device.close if self.dect_device
|
||||||
|
self.dect_device = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def fp_scan_mode
|
||||||
|
self.dect_device.ioctl(COA_IOCTL_MODE, [COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SCANFP].pack('s'))
|
||||||
|
set_band(datastore['BAND'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def pp_scan_mode(rfpi)
|
||||||
|
self.dect_device.ioctl(COA_IOCTL_MODE, [COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SYNC].pack('S'))
|
||||||
|
print_line("#{rfpi}")
|
||||||
|
self.set_rfpi(rfpi.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_scan_mode
|
||||||
|
self.dect_device.ioctl(COA_IOCTL_MODE, [COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SCANPP].pack('s'))
|
||||||
|
set_band(datastore['BAND'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop_coa
|
||||||
|
self.dect_device.ioctl(COA_IOCTL_MODE, [COA_MODE_IDLE].pack('s'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def rfpi
|
||||||
|
self.rfpi
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_rfpi(rfpi)
|
||||||
|
self.dect_device.ioctl(COA_IOCTL_SETRFPI, [rfpi].pack('s'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def channel
|
||||||
|
self.channel.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def band
|
||||||
|
self.band.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_band(b)
|
||||||
|
self.band = b.to_i
|
||||||
|
|
||||||
|
if (band == DECT_BAND_US)
|
||||||
|
set_channel(23)
|
||||||
|
|
||||||
|
elsif (band == DECT_BAND_EMEA)
|
||||||
|
set_channel(0)
|
||||||
|
|
||||||
|
elsif (band == DECT_BAND_BOTH)
|
||||||
|
set_channel(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_channel(chan)
|
||||||
|
self.channel = chan.to_i
|
||||||
|
self.dect_device.ioctl(COA_IOCTL_CHAN, [channel].pack('i'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_channel
|
||||||
|
case band
|
||||||
|
when DECT_BAND_US
|
||||||
|
if (channel < 27)
|
||||||
|
set_channel(channel + 1)
|
||||||
|
else
|
||||||
|
set_channel(23)
|
||||||
|
end
|
||||||
|
|
||||||
|
when DECT_BAND_EMEA
|
||||||
|
if (channel < 9)
|
||||||
|
set_channel(channel + 1)
|
||||||
|
else
|
||||||
|
set_channel(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
when DECT_BAND_BOTH
|
||||||
|
if (channel < 9)
|
||||||
|
set_channel(channel + 1)
|
||||||
|
elsif (channel == 9)
|
||||||
|
set_channel(23)
|
||||||
|
elsif (channel > 9 && channel < 27)
|
||||||
|
set_channel(channel + 1)
|
||||||
|
else
|
||||||
|
set_channel(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_coa
|
||||||
|
data = select([self.dect_device], nil, nil, 0.50)
|
||||||
|
if (data != nil)
|
||||||
|
data = data[0][0].read
|
||||||
|
end
|
||||||
|
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_rfpi(data)
|
||||||
|
sprintf("%02x %02x %02x %02x %02x",data[0], data[1], data[2], data[3], data[4])
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_station(data)
|
||||||
|
{
|
||||||
|
'channel' => data[0],
|
||||||
|
'rssi' => data[1],
|
||||||
|
'rfpi_raw' => data[2,5],
|
||||||
|
'rfpi' => parse_rfpi(data[2,5])
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_call(data)
|
||||||
|
{
|
||||||
|
'channel' => data[0],
|
||||||
|
'rssi' => data[1],
|
||||||
|
'rfpi_raw' => data[2,5],
|
||||||
|
'rfpi' => parse_rfpi(data[2,5])
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def record_coa(filename)
|
||||||
|
raise RuntimeError, "DECT call recording is not supported yet"
|
||||||
|
fd = File.open(filename, 'rw')
|
||||||
|
fd.close
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_accessor :dect_device, :channel, :band
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,79 @@
|
||||||
|
require 'msf/core'
|
||||||
|
|
||||||
|
|
||||||
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
|
include Msf::Exploit::DECT_COA
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(
|
||||||
|
'Name' => 'DECT Call Scanner',
|
||||||
|
'Version' => '$Revision$',
|
||||||
|
'Description' => 'This module scans for active DECT calls',
|
||||||
|
'Author' => [ 'DK <privilegedmode@gmail.com>' ],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'References' => [ ['Dedected', 'http://www.dedected.org'] ]
|
||||||
|
)
|
||||||
|
register_options([
|
||||||
|
OptString.new('VERBOSE',[false, 'Print out verbose information during the scan', true])
|
||||||
|
], self.class )
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_results
|
||||||
|
print_line("Time\t\t\t\tRFPI\t\tChannel")
|
||||||
|
@calls.each do |rfpi, data|
|
||||||
|
print_line("#{data['time']}\t#{data['rfpi']}\t#{data['channel']}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
=begin
|
||||||
|
def record_call(data)
|
||||||
|
print_status("Synchronizing..")
|
||||||
|
pp_scan_mode(data['rfpi_raw'])
|
||||||
|
while(true)
|
||||||
|
data = poll_coa()
|
||||||
|
puts data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
=end
|
||||||
|
|
||||||
|
def run
|
||||||
|
@calls = {}
|
||||||
|
|
||||||
|
print_status("Opening interface: #{datastore['INTERFACE']}")
|
||||||
|
print_status("Using band: #{datastore['band']}")
|
||||||
|
|
||||||
|
open_coa
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
print_status("Changing to call scan mode.")
|
||||||
|
call_scan_mode
|
||||||
|
print_status("Scanning...")
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
data = poll_coa()
|
||||||
|
if (data)
|
||||||
|
parsed_data = parse_call(data)
|
||||||
|
parsed_data['time'] = Time.now
|
||||||
|
print_status("Found active call on: #{parsed_data['rfpi']}")
|
||||||
|
@calls[parsed_data['time']] = parsed_data
|
||||||
|
end
|
||||||
|
|
||||||
|
next_channel
|
||||||
|
|
||||||
|
if (datastore['VERBOSE'])
|
||||||
|
print_status("Switching to channel: #{channel}")
|
||||||
|
end
|
||||||
|
sleep(1)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
print_status("Closing interface")
|
||||||
|
stop_coa()
|
||||||
|
close_coa()
|
||||||
|
end
|
||||||
|
|
||||||
|
print_results
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,71 @@
|
||||||
|
require 'msf/core'
|
||||||
|
|
||||||
|
|
||||||
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
|
include Msf::Exploit::DECT_COA
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(
|
||||||
|
'Name' => 'DECT Base Station Scanner',
|
||||||
|
'Version' => '$Revision$',
|
||||||
|
'Description' => 'This module scans for DECT base stations',
|
||||||
|
'Author' => [ 'DK <privilegedmode@gmail.com>' ],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'References' => [ ['Dedected', 'http://www.dedected.org'] ]
|
||||||
|
)
|
||||||
|
|
||||||
|
register_options([
|
||||||
|
OptString.new('VERBOSE',[false, 'Print out verbose information during the scan', true])
|
||||||
|
], self.class )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def print_results
|
||||||
|
print_line("RFPI\t\tChannel")
|
||||||
|
@base_stations.each do |rfpi, data|
|
||||||
|
print_line("#{data['rfpi']}\t#{data['channel']}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
@base_stations = {}
|
||||||
|
|
||||||
|
print_status("Opening interface: #{datastore['INTERFACE']}")
|
||||||
|
print_status("Using band: #{datastore['band']}")
|
||||||
|
|
||||||
|
open_coa
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
print_status("Changing to fp scan mode.")
|
||||||
|
fp_scan_mode
|
||||||
|
print_status("Scanning...")
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
data = poll_coa()
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
parsed_data = parse_station(data)
|
||||||
|
if (not @base_stations.key?(parsed_data['rfpi']))
|
||||||
|
print_status("Found New RFPI: #{parsed_data['rfpi']}")
|
||||||
|
@base_stations[parsed_data['rfpi']] = parsed_data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
next_channel
|
||||||
|
|
||||||
|
if (datastore['VERBOSE'])
|
||||||
|
print_status("Switching to channel: #{channel}")
|
||||||
|
end
|
||||||
|
sleep(1)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
print_status("Closing interface")
|
||||||
|
stop_coa()
|
||||||
|
close_coa()
|
||||||
|
end
|
||||||
|
|
||||||
|
print_results
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue