More CDP cleanup. Loop, cleaner packet construction, style

bug/bundler_fix
Jon Hart 2014-11-10 11:53:07 -08:00
parent 0dac2de3fd
commit f54fc3da87
1 changed files with 52 additions and 51 deletions

View File

@ -11,15 +11,16 @@ class Metasploit3 < Msf::Auxiliary
def initialize def initialize
super( super(
'Name' => 'CDP Discovery and Spoofing', 'Name' => 'Send Cisco Discovery Protocol (CDP) Packets',
'Description' => 'This module captures and sends Cisco Discovery Protocol (CDP) packets for discovery', 'Description' => 'This module sends Cisco Discovery Protocol (CDP) packets',
'Author' => 'Fatih Ozavci <viproy.com/fozavci>', 'Author' => 'Fatih Ozavci <viproy.com/fozavci>',
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Actions' => [ 'Actions' => [
['Spoof', { 'Description' => 'Sends spoofed CDP packets' }] ['Spoof', { 'Description' => 'Sends CDP packets' }]
], ],
'DefaultAction' => 'Spoof' 'DefaultAction' => 'Spoof'
) )
register_options( register_options(
[ [
OptString.new('SMAC', [false, "MAC Address for MAC Spoofing"]), OptString.new('SMAC', [false, "MAC Address for MAC Spoofing"]),
@ -32,6 +33,7 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('SOFTWARE', [true, "Software of the device", "SCCP75.9-3-1SR2-1S"]), OptString.new('SOFTWARE', [true, "Software of the device", "SCCP75.9-3-1SR2-1S"]),
OptBool.new('FULL_DUPLEX', [true, 'True iff full-duplex, false otherwise', true]) OptBool.new('FULL_DUPLEX', [true, 'True iff full-duplex, false otherwise', true])
], self.class) ], self.class)
deregister_options('RHOST') deregister_options('RHOST')
end end
@ -56,35 +58,30 @@ class Metasploit3 < Msf::Auxiliary
begin begin
open_pcap open_pcap
case action.name @run = true
when 'Spoof' cdp_packet = build_cdp
do_spoof print_status("Sending CDP messages on #{interface}")
else while @run
# this should never happen capture.inject(cdp_packet.to_s)
fail ArgumentError, "Invalid action #{action.name}" Rex.sleep(60)
end end
ensure ensure
close_pcap close_pcap
end end
end end
def do_spoof def build_cdp
print_status("Sending CDP message on #{interface}") cdp = ''
p = prep_cdp # Preparation of the CDP content # CDP version
cdp << "\x02"
# Injecting packet to the network # TTL (180s)
l = PacketFu::Inject.new(iface: interface) cdp << "\xB4"
cdp_length = ["%04X" % (p.length + 8).to_s].pack('H*') # checksum, empty for now
dot3 = PacketFu::EthHeader.mac2str("01:00:0C:CC:CC:CC") + PacketFu::EthHeader.mac2str(smac) + cdp_length cdp << "\x00\x00"
llc = "\xAA\xAA\x03\x00\x00\x0c\x20\x00"
l.array_to_wire(array: [dot3 + llc + p])
end
def prep_cdp
# device ID # device ID
p = tlv(1, datastore['DEVICE_ID']) cdp << tlv(1, datastore['DEVICE_ID'])
# port ID # port ID
p << tlv(3, datastore['PORT']) cdp << tlv(3, datastore['PORT'])
# TODO: implement this correctly # TODO: implement this correctly
# capabilities = datastore['CAPABILITIES'] || "Host" # capabilities = datastore['CAPABILITIES'] || "Host"
# CAPABILITIES # CAPABILITIES
@ -95,47 +92,51 @@ class Metasploit3 < Msf::Auxiliary
# define CDP_CAP_LEVEL2_SRB 0x04 # define CDP_CAP_LEVEL2_SRB 0x04
# define CDP_CAP_LEVEL2_TRBR 0x02 # define CDP_CAP_LEVEL2_TRBR 0x02
# define CDP_CAP_LEVEL3_ROUTER 0x01 # define CDP_CAP_LEVEL3_ROUTER 0x01
p << tlv(4, "\x00\x00\x00\x41") cdp << tlv(4, "\x00\x00\x00\x41")
# software version # software version
p << tlv(5, datastore['SOFTWARE']) cdp << tlv(5, datastore['SOFTWARE'])
# platform # platform
p << tlv(6, datastore['PLATFORM']) cdp << tlv(6, datastore['PLATFORM'])
# VTP management domain # VTP management domain
p << tlv(9, datastore['VTPDOMAIN']) if datastore['VTPDOMAIN'] cdp << tlv(9, datastore['VTPDOMAIN']) if datastore['VTPDOMAIN']
# random 1000-7000 power consumption in mW # random 1000-7000 power consumption in mW
p << tlv(0x10, [1000 + rand(6000)].pack('n')) cdp << tlv(0x10, [1000 + rand(6000)].pack('n'))
# duplex # duplex
p << tlv(0x0b, datastore['FULL_DUPLEX'] ? "\x01" : "\x00") cdp << tlv(0x0b, datastore['FULL_DUPLEX'] ? "\x01" : "\x00")
# VLAn query. TOD: figure out this field, use tlv, make configurable # VLAn query. TODO: figure out this field, use tlv, make configurable
p << "\x00\x0F\x00\b \x02\x00\x01" cdp << "\x00\x0F\x00\b \x02\x00\x01"
# VDP version # compute and replace the checksum
version = "\x02" cdp[2, 2] = [compute_cdp_checksum(cdp)].pack('n')
# TTL (180s)
ttl = "\xB4" # Build and return the final packet, which is 802.3 + LLC + CDP.
checksum = cdpchecksum(version + ttl + "\x00\x00" + p) # 802.3
version + ttl + checksum + p PacketFu::EthHeader.mac2str("01:00:0C:CC:CC:CC") +
PacketFu::EthHeader.mac2str(smac) +
[cdp.length + 8].pack('n') +
# LLC
"\xAA\xAA\x03\x00\x00\x0c\x20\x00" +
# CDP
cdp
end end
def tlv(t, v) def tlv(t, v)
[ t, v.length + 4 ].pack("nn") + v [ t, v.length + 4 ].pack("nn") + v
end end
def cdpchecksum(p) def compute_cdp_checksum(cdp)
num_shorts = p.length / 2 num_shorts = cdp.length / 2
cs = 0 checksum = 0
c = p.length remaining = cdp.length
p.unpack("S#{num_shorts}").each do |x| cdp.unpack("S#{num_shorts}").each do |short|
cs += x checksum += short
c -= 2 remaining -= 2
end end
cs += p[p.length - 1].getbyte(0) << 8 if c == 1 checksum += cdp[cdp.length - 1].getbyte(0) << 8 if remaining == 1
cs = (cs >> 16) + (cs & 0xffff) checksum = (checksum >> 16) + (checksum & 0xffff)
cs = ~((cs >> 16) + cs) & 0xffff checksum = ~((checksum >> 16) + checksum) & 0xffff
cs = ([cs].pack("S*")).unpack("n*")[0] ([checksum].pack("S*")).unpack("n*")[0]
[ "%02X" % cs ].pack('H*')
end end
end end