It’s hard to believe, how easy it is to capture (and to craft) LAN-Data using Python Scapy.
I need to capture CDP-Packets and to extract information like the hostname of the sender and it’s IP-Address.
As an modification of the „ARP-Monitor“-example taken from the manual Using scapy in your tools.
- Scapy Installation
- Python: Install Scapy
- Example: List all Interfaces of my Laptop
- Capture 10 Packets on a specific interface
- Capture CDP-Packets
- Decode CDP (with inactive dissector)
- Activate the CDP-Parser
- Capture again and display CDP-Information as cleartext
- Decode CDP-Hostname
- Decode CDP-Management-IP-Address
nothing special: pip install
C:\RH>pip install scapy Collecting scapy Downloading https://files.pythonhosted.org/packages/68/01/b9943984447e7ea6f8948e90c1729b78161c2bb3eef908430638ec3f7296/scapy-2.4.0.tar.gz (3.1MB) 100% |████████████████████████████████| 3.1MB 420kB/s In the tar file C:\Users\RONALD~1.HEI\AppData\Local\Temp\pip-unpack-4jm9kde1\scapy-2.4.0.tar.gz the member scapy-2.4.0/README is invalid: unable to resolve link inside archive Installing collected packages: scapy Running setup.py install for scapy ... done Successfully installed scapy-2.4.0
C:\RH>python Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from scapy.all import *
>>> ifaces INDEX IFACE IP MAC 20 VirtualBox Host-Only Ethernet Adapter 192.168.56.1 0A:00:27:00:00:14 22 Intel(R) Dual Band Wireless-AC 8265 172.20.10.2 IntelCor:BD:10:37 4 Intel(R) Ethernet Connection (4) I219-LM 47.11.17.10 BayNetwo:00:DE:11 >>> for i in ifaces.data.keys(): ... iface = ifaces.data[i] ... name = str(iface.name) ... wname = iface.data['netid'] ... mac = str(iface.mac) ... ip = str(iface.ip) ... print("DESCR:{0}, NAME:{1}, MAC:{2}, IP:{3}".format(wname,name,mac,ip)) ... DESCR:Wi-Fi, NAME:Intel(R) Dual Band Wireless-AC 8265, MAC:74:70:FD:BD:10:37, IP:172.20.10.2 DESCR:VirtualBox Host-Only Network, NAME:VirtualBox Host-Only Ethernet Adapter, MAC:0A:00:27:00:00:14, IP:192.168.56.1 DESCR:ETH_DELL, NAME:Intel(R) Ethernet Connection (4) I219-LM, MAC:00:00:81:00:DE:11, IP:47.11.17.10
The "NAME" is needed as interface-handle >>> interface="VirtualBox Host-Only Ethernet Adapter" >>> p=sniff(iface=interface, count=10) >>> p.display() 0000 Ether / IP / UDP 192.168.56.1:17500 > 255.255.255.255:17500 / Raw 0001 Ether / IP / UDP 192.168.56.1:17500 > 255.255.255.255:17500 / Raw 0002 Ether / IP / UDP 192.168.56.1:17500 > 192.168.56.255:17500 / Raw 0003 Ether / IP / UDP 192.168.56.1:17500 > 255.255.255.255:17500 / Raw 0004 Ether / IP / UDP 192.168.56.1:17500 > 255.255.255.255:17500 / Raw 0005 Ether / IP / UDP 192.168.56.100:bootps > 255.255.255.255:bootpc / BOOTP / DHCP 0006 Ether / IP / UDP 192.168.56.102:50472 > 255.255.255.255:10067 / Raw 0007 Ether / IP / UDP 192.168.56.103:49580 > 255.255.255.255:10067 / Raw 0008 Ether / IP / UDP 192.168.56.1:17500 > 255.255.255.255:17500 / Raw 0009 Ether / IP / UDP 192.168.56.1:17500 > 255.255.255.255:17500 / Raw
Capture CDP >>> p=sniff(iface=interface, count=2, filter="ether dst 01:00:0c:cc:cc:cc") >>> p <Sniffed: TCP:0 UDP:0 ICMP:0 Other:2> >>> p.display() 0000 802.3 08:00:27:c9:d5:7e > 01:00:0c:cc:cc:cc / LLC / SNAP / Raw 0001 802.3 08:00:27:c9:d5:7e > 01:00:0c:cc:cc:cc / LLC / SNAP / Raw
>>> p[0].display() ###[ 802.3 ]### dst = 01:00:0c:cc:cc:cc src = 08:00:27:c9:d5:7e len = 386 ###[ LLC ]### dsap = 0xaa ssap = 0xaa ctrl = 3 ###[ SNAP ]### OUI = 0xc code = 0x2000 ###[ Raw ]### load = '\x02\xb4\x91\x18\x00\x01\x00\x13CSR-A.lab.local\x00\x05\x01\x05Cisco IOS Software [Fuji], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.9.1, RELEASE SOFTWARE (fc2)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2018 by Cisco Systems, Inc.\nCompiled Tue 17-Jul-18 16:57 by mcpre\x00\x06\x00\x12cisco CSR1000V\x00\x02\x00\x11\x00\x00\x00\x01\x01\x01\xcc\x00\x04\xc0\xa88e\x00\x03\x00\x14GigabitEthernet2\x00\x04\x00\x08\x00\x00\x00!\x00\x07\x00\t\n\x00\x02\x00\x18\x00\x0b\x00\x05\x01\x00\x16\x00\x11\x00\x00\x00\x01\x01\x01\xcc\x00\x04\xc0\xa88e'
>>> list_contrib() avs : AVS WLAN Monitor Header status=loads bgp : BGP v0.1 status=loads carp : CARP status=loads cdp : Cisco Discovery Protocol status=loads chdlc : Cisco HDLC and SLARP status=loads coap : Constrained Application Protocol (CoAP) status=loads diameter : Diameter status=loads dtp : DTP status=loads eigrp : EIGRP status=loads etherip : EtherIP status=loads gsm_um : PPI status=loads gtp : GTP status=loads gtp_v2 : GTPv2 status=loads homeplugav : HomePlugAV Layer status=loads http2 : HTTP/2 (RFC 7540, RFC 7541) status=loads icmp_extensions : ICMP Extensions status=loads igmp : IGMP/IGMPv2 status=loads igmpv3 : IGMPv3 status=loads ikev2 : IKEv2 status=loads isis : ISIS status=loads ldp : Label Distribution Protocol (LDP) status=loads lldp : LLDP status=loads macsec : - status=? modbus : ModBus Protocol status=loads mpls : MPLS status=loads mqtt : - status=? nsh : NSH Protocol status=loads openflow : Openflow v1.0 status=loads openflow3 : Openflow v1.3 status=loads ospf : OSPF status=loads pnio : ProfinetIO base layer status=loads pnio_rtc : ProfinetIO Real-Time Cyclic (RTC) status=loads ppi : PPI status=loads ppi_cace : PPI CACE status=loads ppi_geotag : PPI GEOLOCATION status=loads ripng : RIPng status=loads rsvp : RSVP status=loads sebek : Sebek status=loads send : Secure Neighbor Discovery (SEND) (ICMPv6) status=loads skinny : Skinny Call Control Protocol (SCCP) status=loads spbm : SBPM status=loads tacacs : TACACS+ Protocol status=loads tzsp : TZSP status=loads ubberlogger : Ubberlogger dissectors status=loads vqp : VLAN Query Protocol status=loads vtp : VLAN Trunking Protocol (VTP) status=loads wpa_eapol : WPA EAPOL dissector status=loads >>> load_contrib("cdp")
>>> load_contrib("cdp") >>> p=sniff(iface=interface, count=1, filter=capturefilter) >>> >>> >>> p[0].show() ###[ 802.3 ]### dst = 01:00:0c:cc:cc:cc src = 08:00:27:c9:d5:7e len = 386 ###[ LLC ]### dsap = 0xaa ssap = 0xaa ctrl = 3 ###[ SNAP ]### OUI = 0xc code = 0x2000 ###[ Cisco Discovery Protocol version 2 ]### vers = 2 ttl = 180 cksum = 0x9118 \msg \ |###[ Device ID ]### | type = Device ID | len = 19 | val = 'CSR-A.lab.local' |###[ Software Version ]### | type = Software Version | len = 261 | val = 'Cisco IOS Software [Fuji], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.9.1, RELEASE SOFTWARE (fc2)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2018 by Cisco Systems, Inc.\nCompiled Tue 17-Jul-18 16:57 by mcpre' |###[ Platform ]### | type = Platform | len = 18 | val = 'cisco CSR1000V' |###[ Addresses ]### | type = Addresses | len = 17 | naddr = 1 | \addr \ | |###[ CDP Address IPv4 ]### | | ptype = NLPID | | plen = 1 | | proto = '\xcc' | | addrlen = 4 | | addr = 192.168.56.101 |###[ Port ID ]### | type = Port ID | len = 20 | iface = 'GigabitEthernet2' |###[ Capabilities ]### | type = Capabilities | len = 8 | cap = Router+IGMPCapable |###[ IP Prefix ]### | type = IP Prefix | len = 9 | defaultgw = 10.0.2.0 |###[ CDP Generic Message ]### | type = 0x1800 | len = 2816 | val = '\x05\x01\x00\x16\x00\x11\x00\x00\x00\x01\x01\x01\xcc\x00\x04\xc0\xa88e'
>>> device=p[0]["CDPMsgDeviceID"].val.decode() >>> device 'CSR-A.lab.local' >>> hostname=device.split(".")[0] >>> hostname 'CSR-A'
>>> ip=p[0]["CDPAddrRecordIPv4"] >>> ip.addr '192.168.56.101'