Values ​assigned in the Scapy parameters - python

How can I find out what number is assigned to a specific value in any parameter in the IP Protocol or any other Protocol?
If I set a value:
a=IP(proto=73)
I get:
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
**proto= rspf**
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
If I set another value:
a=IP(proto=12)
I get:
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= pup
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
and so on.
Some number is assigned to a value in some parameter of the package. At the moment, I'm listing every number from 1 to 100 to see what's hidden there, but it's a very long and painful process.
How to see which numbers are assigned to values?
Thanks.

scapy loads the protocol list from your system
definition of the proto field in scapy:
https://github.com/secdev/scapy/blob/master/scapy/layers/inet.py#L466
it is define as:
ByteEnumField("proto", 0, IP_PROTOS),
definition of IP_PROTOS:
https://github.com/secdev/scapy/blob/bfd9c52af61978ac872d3c0bf5eef81168d88ca9/scapy/data.py#L476
for win:
IP_PROTOS = load_protocols(os.environ["SystemRoot"] + "\\system32\\drivers\\etc\\protocol") # noqa: E501
for linux:
IP_PROTOS = load_protocols("/etc/protocols")
now, I have linux system, so for me it looks like that:
cat /etc/protocols
# Internet (IP) protocols
#
# Updated from http://www.iana.org/assignments/protocol-numbers and other
# sources.
# New protocols will be added on request if they have been officially
# assigned by IANA and are not historical.
# If you need a huge list of used numbers please install the nmap package.
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # IPv6 Hop-by-Hop Option [RFC1883]
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # Internet Group Management
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
tcp 6 TCP # transmission control protocol
egp 8 EGP # exterior gateway protocol
igp 9 IGP # any private interior gateway (Cisco)
pup 12 PUP # PARC universal packet protocol
udp 17 UDP # user datagram protocol
hmp 20 HMP # host monitoring protocol
xns-idp 22 XNS-IDP # Xerox NS IDP
rdp 27 RDP # "reliable datagram" protocol
iso-tp4 29 ISO-TP4 # ISO Transport Protocol class 4 [RFC905]
dccp 33 DCCP # Datagram Congestion Control Prot. [RFC4340]
xtp 36 XTP # Xpress Transfer Protocol
ddp 37 DDP # Datagram Delivery Protocol
idpr-cmtp 38 IDPR-CMTP # IDPR Control Message Transport
ipv6 41 IPv6 # Internet Protocol, version 6
ipv6-route 43 IPv6-Route # Routing Header for IPv6
ipv6-frag 44 IPv6-Frag # Fragment Header for IPv6
idrp 45 IDRP # Inter-Domain Routing Protocol
rsvp 46 RSVP # Reservation Protocol
gre 47 GRE # General Routing Encapsulation
esp 50 IPSEC-ESP # Encap Security Payload [RFC2406]
ah 51 IPSEC-AH # Authentication Header [RFC2402]
skip 57 SKIP # SKIP
ipv6-icmp 58 IPv6-ICMP # ICMP for IPv6
ipv6-nonxt 59 IPv6-NoNxt # No Next Header for IPv6
ipv6-opts 60 IPv6-Opts # Destination Options for IPv6
rspf 73 RSPF CPHB # Radio Shortest Path First (officially CPHB)
vmtp 81 VMTP # Versatile Message Transport
eigrp 88 EIGRP # Enhanced Interior Routing Protocol (Cisco)
ospf 89 OSPFIGP # Open Shortest Path First IGP
ax.25 93 AX.25 # AX.25 frames
ipip 94 IPIP # IP-within-IP Encapsulation Protocol
etherip 97 ETHERIP # Ethernet-within-IP Encapsulation [RFC3378]
encap 98 ENCAP # Yet Another IP encapsulation [RFC1241]
# 99 # any private encryption scheme
pim 103 PIM # Protocol Independent Multicast
ipcomp 108 IPCOMP # IP Payload Compression Protocol
vrrp 112 VRRP # Virtual Router Redundancy Protocol [RFC5798]
l2tp 115 L2TP # Layer Two Tunneling Protocol [RFC2661]
isis 124 ISIS # IS-IS over IPv4
sctp 132 SCTP # Stream Control Transmission Protocol
fc 133 FC # Fibre Channel
mobility-header 135 Mobility-Header # Mobility Support for IPv6 [RFC3775]
udplite 136 UDPLite # UDP-Lite [RFC3828]
mpls-in-ip 137 MPLS-in-IP # MPLS-in-IP [RFC4023]
manet 138 # MANET Protocols [RFC5498]
hip 139 HIP # Host Identity Protocol
shim6 140 Shim6 # Shim6 Protocol [RFC5533]
wesp 141 WESP # Wrapped Encapsulating Security Payload
rohc 142 ROHC # Robust Header Compression
Those protocol are well defined and standard, I am expecting a windows system to have very similar list.
that somewhat matches that one: https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers

Related

Recognize telnet protocol with Scapy python

I am reading a Pcap file with Scapy. How can I recognize if, in this pcap file, there is a packet that uses the Telnet protocol?
I see that Scapy can write 'telnet' into dport/sport only if 1 of those ports is 23, but if I am using another port for Telnet, how do I recognize this with Scapy?
#TimRoberts stated in the comments that "Telnet is indistinguishable from other TCP protocols." This is true to some extent, because all TCP packets use the same structure, which is outlined in multiple Internet Engineering Task Force (IETF) Request for Comments (RFC) documents:
RFC 791 - Internet Protocol (IP)
RFC 793 - Transmission Control Protocol (TCP)
Here is the structure of a TCP packet.
Common application protocols such as Hypertext Transfer Protocol (HTTP), File Transfer Protocol (FTP) and Telnet all use this structure.
Concerning the application protocol Telnet. As you already know the official port assignment for the telnet protocol is port 23. Most vendors adhere to this port standard, which is why "Scapy can write 'telnet' into dport/sport only if 1 of those ports is 23."
This is the TCP layer from a Telnet session using port 23:
Layer TCP:
Source Port: 1254
Destination Port: 23
Stream index: 0
TCP Segment Len: 0
Sequence number: 0 (relative sequence number)
Sequence number (raw): 72603759
Next sequence number: 1 (relative sequence number)
Acknowledgment number: 0
Acknowledgment number (raw): 0
1010 .... = Header Length: 40 bytes (10)
Flags: 0x002 (SYN)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...0 .... = Acknowledgment: Not set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
Expert Info (Chat/Sequence): Connection establish request (SYN): server port 23
Connection establish request (SYN): server port 23
Severity level: Chat
Group: Sequence
.... .... ...0 = Fin: Not set
TCP Flags: \xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7S\xc2\xb7
Window size value: 32120
Calculated window size: 32120
Checksum: 0x5d40 [unverified]
Checksum Status: Unverified
Urgent pointer: 0
Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
TCP Option - Maximum segment size: 1460 bytes
Kind: Maximum Segment Size (2)
Length: 4
MSS Value: 1460
TCP Option - SACK permitted
TCP Option - Timestamps: TSval 1444389, TSecr 0
Timestamp value: 1444389
Timestamp echo reply: 0
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 0 (multiply by 1)
Shift count: 0
Multiplier: 1
Timestamps
Time since first frame in this TCP stream: 0.000000000 seconds
Time since previous frame in this TCP stream: 0.000000000 seconds
Kind: SACK Permitted (4)
Kind: Time Stamp Option (8)
Kind: No-Operation (1)
Kind: Window Scale (3)
Length: 2
Length: 10
Length: 3
This is the TCP layer from a Telnet session using port 3005:
Layer TCP:
Source Port: 52187
Destination Port: 3005
Stream index: 0
TCP Segment Len: 0
Sequence number: 0 (relative sequence number)
Sequence number (raw): 1355255000
Next sequence number: 1 (relative sequence number)
Acknowledgment number: 0
Acknowledgment number (raw): 0
1011 .... = Header Length: 44 bytes (11)
Flags: 0x002 (SYN)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...0 .... = Acknowledgment: Not set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
Expert Info (Chat/Sequence): Connection establish request (SYN): server port 3005
Connection establish request (SYN): server port 3005
Severity level: Chat
Group: Sequence
.... .... ...0 = Fin: Not set
TCP Flags: \xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7S\xc2\xb7
Window size value: 65535
Calculated window size: 65535
Checksum: 0x0afb [unverified]
Checksum Status: Unverified
Urgent pointer: 0
Options: (24 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), Timestamps, SACK permitted, End of Option List (EOL)
TCP Option - Maximum segment size: 1460 bytes
Kind: Maximum Segment Size (2)
Length: 4
MSS Value: 1460
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 6 (multiply by 64)
Shift count: 6
Multiplier: 64
TCP Option - Timestamps: TSval 3609205717, TSecr 0
Timestamp value: 3609205717
Timestamp echo reply: 0
TCP Option - SACK permitted
TCP Option - End of Option List (EOL)
Timestamps
Time since first frame in this TCP stream: 0.000000000 seconds
Time since previous frame in this TCP stream: 0.000000000 seconds
Kind: No-Operation (1)
Kind: Window Scale (3)
Kind: No-Operation (1)
Kind: No-Operation (1)
Kind: Time Stamp Option (8)
Kind: SACK Permitted (4)
Kind: End of Option List (0)
Length: 3
Length: 10
Length: 2
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
This is the TCP layer from a FTP session using port 21:
Layer TCP:
Source Port: 35974
Destination Port: 21
Stream index: 0
TCP Segment Len: 0
Sequence number: 0 (relative sequence number)
Sequence number (raw): 29473206
Next sequence number: 1 (relative sequence number)
Acknowledgment number: 0
Acknowledgment number (raw): 0
1010 .... = Header Length: 40 bytes (10)
Flags: 0x002 (SYN)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...0 .... = Acknowledgment: Not set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
Expert Info (Chat/Sequence): Connection establish request (SYN): server port 21
Connection establish request (SYN): server port 21
Severity level: Chat
Group: Sequence
.... .... ...0 = Fin: Not set
TCP Flags: \xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7S\xc2\xb7
Window size value: 32648
Calculated window size: 32648
Checksum: 0x8fda [unverified]
Checksum Status: Unverified
Urgent pointer: 0
Options: (20 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), Timestamps
TCP Option - Maximum segment size: 1380 bytes
Kind: Maximum Segment Size (2)
Length: 4
MSS Value: 1380
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 0 (multiply by 1)
Shift count: 0
Multiplier: 1
TCP Option - Timestamps: TSval 1657560000, TSecr 0
Timestamp value: 1657560000
Timestamp echo reply: 0
Timestamps
Time since first frame in this TCP stream: 0.000000000 seconds
Time since previous frame in this TCP stream: 0.000000000 seconds
Kind: No-Operation (1)
Kind: Window Scale (3)
Kind: No-Operation (1)
Kind: No-Operation (1)
Kind: Time Stamp Option (8)
Length: 3
Length: 10
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
This is the TCP layer from a SSH session using port 22:
Layer TCP:
Source Port: 57732
Destination Port: 22
Stream index: 0
TCP Segment Len: 0
Sequence number: 0 (relative sequence number)
Sequence number (raw): 71043058
Next sequence number: 1 (relative sequence number)
Acknowledgment number: 0
Acknowledgment number (raw): 0
1011 .... = Header Length: 44 bytes (11)
Flags: 0x002 (SYN)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...0 .... = Acknowledgment: Not set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
Expert Info (Chat/Sequence): Connection establish request (SYN): server port 22
Connection establish request (SYN): server port 22
Severity level: Chat
Group: Sequence
.... .... ...0 = Fin: Not set
TCP Flags: \xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7S\xc2\xb7
Window size value: 65535
Calculated window size: 65535
Checksum: 0xd079 [unverified]
Checksum Status: Unverified
Urgent pointer: 0
Options: (24 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), Timestamps, SACK permitted, End of Option List (EOL)
TCP Option - Maximum segment size: 1460 bytes
Kind: Maximum Segment Size (2)
Length: 4
MSS Value: 1460
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 6 (multiply by 64)
Shift count: 6
Multiplier: 64
TCP Option - Timestamps: TSval 1452973307, TSecr 0
Timestamp value: 1452973307
Timestamp echo reply: 0
TCP Option - SACK permitted
TCP Option - End of Option List (EOL)
Timestamps
Time since first frame in this TCP stream: 0.000000000 seconds
Time since previous frame in this TCP stream: 0.000000000 seconds
Kind: No-Operation (1)
Kind: Window Scale (3)
Kind: No-Operation (1)
Kind: No-Operation (1)
Kind: Time Stamp Option (8)
Kind: SACK Permitted (4)
Kind: End of Option List (0)
Length: 3
Length: 10
Length: 2
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
As previously stated these TCP layers are almost indistinguishable. So trying to use the TCP layer alone would be hard to determine a Telnet session over a port other than port 23. So trying to use Scapy to identify these sessions without doing a more in-depth packet analysis would be extremely hard.
You could potential analyze the data layer of a TCP packet to determine if a connection is or isn't a Telnet session. This again requires substantial effort unless you have done some level of traffic analysis.
Using the Python module pyshark you extract content from the Data layer.
Telnet session over port 23:
import pyshark
# the pcap is a Telnet session over port 23
capture = pyshark.FileCapture('telnet-raw.pcap')
for packet in capture:
if hasattr(packet, 'tcp'):
layers = packet.layers
# 0 1 2 3
# [<ETH Layer>, <IP Layer>, <TCP Layer>, <DATA Layer>]
if len(layers) > 3:
payload = packet.tcp.payload
The payload output is in hex
truncated...
ff:fb:01:ff:fa:21:02:ff:f0:ff:fc:01
ff:fd:01:ff:fe:01
ff:fa:22:03:05:80:00:11:80:00:12:80:00:ff:f0
0d:0a:4f:70:65:6e:42:53:44:2f:69:33:38:36:20:28:6f:6f:66:29:20:28:74:74:79:70:31:29:0d:0a:0d:0a
6c:6f:67:69:6e:3a:20
ff:fc:22:ff:fd:01
truncated...
The 4th and 5th hex strings in the output are an important piece to deciphering what type of TCP connection might be occurring.
import binascii
hex_data = '0d:0a:4f:70:65:6e:42:53:44:2f:69:33:38:36:20:28:6f:6f:66:29:20:28:74:74:79:70:31:29:0d:0a:0d:0a6c:6f:67:69:6e:3a:20 '
hex_string = ' '.join(hex_data.split('0d:0a')).replace(':', '')
hex_list = hex_string.split()
for item in hex_list:
decoded_string = binascii.unhexlify(item)
print(decoded_string)
# output
b'OpenBSD/i386 (oof) (ttyp1)'
b'login: '
After decoding the hex we can see that authentication is occurring over port 23.
Telnet session over port 3005:
import pyshark
# the pcap is a Telnet session over port 3005
capture = pyshark.FileCapture('telnet-pcap-1.pcapng')
for packet in capture:
if hasattr(packet, 'tcp'):
layers = packet.layers
# 0 1 2 3
# [<ETH Layer>, <IP Layer>, <TCP Layer>, <DATA Layer>]
if len(layers) > 3:
payload = packet.tcp.payload
The payload output is in hex
ff:fb:01:ff:fb:03:ff:fd:18:ff:fd:1f
ff:fd:01:ff:fd:03:ff:fb:18:ff:fb:1f:ff:fa:1f:00:97:00:2f:ff:f0
0d:0a:55:73:65:72:20:41:63:63:65:73:73:20:56:65:72:69:66:69:63:61:74:69:6f:6e:0d:0a:0d:0a:55:73:65:72:6e:61:6d:65:3a:20
ff:fa:18:01:ff:f0
ff:fa:18:00:58:54:45:52:4d:2d:32:35:36:43:4f:4c:4f:52:ff:f0
truncated...
The 3rd hex string in the output is an important piece to deciphering what type of TCP connection might be occurring.
import binascii
hex_data = '0d:0a:55:73:65:72:20:41:63:63:65:73:73:20:56:65:72:69:66:69:63:61:74:69:6f:6e:0d:0a:0d:0a:55:73:65:72:6e:61:6d:65:3a:20'
# removing line breaks from the hex string
hex_string = ' '.join(hex_data.split('0d:0a')).replace(':', '')
hex_list = hex_string.split()
for item in hex_list:
decoded_string = binascii.unhexlify(item)
print(decoded_string)
# output
b'User Access Verification'
b'Username: '
After decoding the hex we can see that some type of authentication is occurring over port 3005. Additional analysis would be required to determine if this session is a Telnet session or some other session.
Try doing
for pkt in PcapReader('your_file.pcap'):
# you can try printing summary to see the packet
print(pkt.summary())
# should print something like
# IP / TCP 10.1.99.25:ftp_data > 10.1.99.2:telnet S
pkt_src = pkt[IP].src
pky_type = pkt[IP].type
pkt_payload = pkt[TCP].payload
if [...]
you could print the pkt dictionary to see under which key the telnet string could be falling into and do some pattern matching
I saw the recommendation to do directly PcapReader as not to take memory with rdpcap in another stackoverflow answer but I lost the link

Packet sniffing getting only private IP addresses with raw socket

I'm trying to code a packet sniffer that detects the different websites that are visited by the devices connected to my wifi. The problem is that I'm only getting private IPs, here are the counted IPs I get from a 1 hour sniffing :
IPS Number_Of_Values
224.0.0.251 1068
192.168.1.255 387
255.255.255.255 32
224.0.0.22 28
224.0.0.1 28
192.168.1.111 6
192.168.1.115 5
224.0.1.187 2
Here is a part of the sniffer, ethernet_frame is getting mac addresses and proto, ipv4_packet unpacks the IP header and gets the IPs (source and target) and finally get_packets proceeds to the different unpackings:
def ethernet_frame(data):
dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])
return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:]
def ipv4_packet(data):
version_header_length = data[0]
version = version_header_length >> 4
header_length = (version_header_length & 15) * 4
ttl, proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20])
return version, header_length, ttl, proto, ipv4(src), ipv4(target), data[header_length:]
def get__packets():
conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
while True:
raw_data, addr = conn.recvfrom(65536)
dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data)
# 8 for ipv4
if eth_proto == 8:
(version, header_length, ttl, proto, src_ip, target_ip, data) = ipv4_packet(data)
Why am I only getting private IPs? How can I get websites IPs? If it's not possible, how to get the http header from a TCP packet in order to get the url?
(I'm coding it on my raspberry pi 4 - Linux)

Can't connect to modbus RTU over TCP. What is wrong?

Prove that device is working: ./modpoll -m enc -p4660 -t4:float -r60 -a3 192.168.1.1:
Protocol configuration: Encapsulated RTU over TCP
Slave configuration...: address = 3, start reference = 60, count = 1
Communication.........: 192.168.1.1, port 4660, t/o 1.00 s, poll rate 1000 ms
Data type.............: 32-bit float, output (holding) register table
TRACELOG: Set poll delay 0
TRACELOG: Set port 4660
TRACELOG: Open connection to 192.168.1.1
TRACELOG: Configuration: 1000, 1000, 0
-- Polling slave... (Ctrl-C to stop)
TRACELOG: Read multiple floats 3 60
TRACELOG: Send(6): 03 03 00 3B 00 02
TRACELOG: Recv(9): 03 03 04 6E 08 42 F7 35 FF
[60]: 123.714905
And how I try to get the connection with pymodbus library:
from pymodbus.client.sync import ModbusTcpClient
from pymodbus.transaction import ModbusRtuFramer
ModbusTcpClient(host='192.168.1.1', port=4660, framer=ModbusRtuFramer, timeout=5)
client.connect() # returns True
client.read_holding_registers(60, count=3, unit=0x03)
And get this result:
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] 192.168.1.1:4660
Modbus Error: [Connection] 192.168.1.1:4660
What I'm doing wrong?

Setting up BGP Layer Using Scapy

I am trying to use Scapy to send packets that have a BGP layer
I am currently stuck on a rudimentary part of this problem because I am unable to set up the BGP layer. I followed the instructions to set up the regular IP and TCP Layer.
Eg:
>>a=IP(src="192.168.1.1",dst="192.168.1.2")/TCP(sport=179,dport=50)
But the problem arises when I do this:
>>a=a/BGP()
NameError: name BGP is not defined
I have seen the BGP implementations in the contrib file from Scapy Github (https://github.com/secdev/scapy/blob/9201f1cf1318edd5768d7e2ee968b7fba0a24c5e/scapy/contrib/bgp.py) so I think Scapy does support BGP implementations
I am new to networking so I was wondering if you could help me set up the BGP layer
Thanks for taking the time to read this!
We want a BGP Layer using scapy. As BGP travels over TCP. So we must have a established (3 way handshake) tcp socket. And TCP travels over IP. Thus we can represent full packet in the below format.
packet = IP Layer / TCP Layer / BGP Layer
But BGP itself is divided in two parts, BGP Header and BGP Payload (EG: OPEN, UPDATE, etc ). So the above layer is represented as given below.
packet = IP Layer / TCP Layer / BGP Header / BGP payload
Here BGP Header specifies authentication, length and type of BGP Payload.To represent whole thing in scapy, we can do the following excercise. (I am assuming here that you have an established TCP socket.)
from scapy.layers.inet import IP, TCP
from scapy.contrib.bgp import BGPHeader, BGPUpdate, BGPPathAttr, BGPNLRI_IPv4, BGPPALocalPref
base = IP(src=src_ipv4_addr, dst=dst_ipv4_addr, proto=6, ttl=255) # proto=6 represents that, TCP will be travelling above this layer. This is simple IPV4 communication.
tcp = TCP(sport=established_port, dport=179, seq=current_seq_num, ack=expected_seq_num, flags='PA') # dport=179 means, we are communicating with bgp port of the destination router/ host. sport is a random port over which tcp is established. seq and ack are the sequence number and acknowledgement numbers. flags = PA are the PUSH and ACK flags.
hdr = BGPHeader(type=2, marker=0xffffffffffffffffffffffffffffffff) # type=2 means UPDATE packet will be the BGP Payload, marker field is for authentication. max hex int (all f) are used for no auth.
up = BGPUpdate(path_attr=[BGPPathAttr(type_flags=64, type_code=5, attribute=BGPPALocalPref(local_pref=100))], nlri=BGPNLRI_IPv4(prefix=NLRI_PREFIX)) # update packet consist of path attributes and NLRI (Network layer reachability information), type_code in path attributes is for which type of path attribute it is. [more][3]
packet = base / tcp / hdr / up
packet.show2()
Using the following variable values (for example purpose).
src_ipv4_addr = '10.110.99.2' # eth0
dst_ipv4_addr = '10.110.99.50'
established_port = 1223
expected_seq_num=1000 # ack
current_seq_num=1500 # seq
NLRI_PREFIX = '10.110.99.0/24'
Output will be following.
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 74
id = 1
flags =
frag = 0
ttl = 255
proto = tcp
chksum = 0xe09c
src = 10.110.99.2
dst = 10.110.99.50
\options \
###[ TCP ]###
sport = 1223
dport = bgp
seq = 1500
ack = 1000
dataofs = 5
reserved = 0
flags = PA
window = 8192
chksum = 0x102d
urgptr = 0
options = []
###[ HEADER ]###
marker = 0xffffffffffffffffffffffffffffffff
len = 34
type = UPDATE
###[ UPDATE ]###
withdrawn_routes_len= 0
\withdrawn_routes\
path_attr_len= 7
\path_attr \
|###[ BGPPathAttr ]###
| type_flags= Transitive
| type_code = LOCAL_PREF
| attr_len = 4
| \attribute \
| |###[ LOCAL_PREF ]###
| | local_pref= 100
\nlri \
|###[ IPv4 NLRI ]###
| prefix = 10.110.99.0/24
Just going to try and help here. I have zero experience with BGP type packets, but... I copied the bgp.py file from the link you provided into scapy/layers. Using ls() I found the following:
BGPAuthenticationData : BGP Authentication Data
BGPErrorSubcodes : BGP Error Subcodes
BGPHeader : BGP header
BGPNotification : BGP Notification fields
BGPOpen : BGP Open Header
BGPOptionalParameter : BGP Optional Parameters
BGPPathAttribute : BGP Attribute fields
BGPUpdate : BGP Update fields
I could then use say ls(BGPUpdate) to show this:
withdrawn_len : ShortField = (None)
withdrawn : FieldListField = ([])
tp_len : ShortField = (None)
total_path : PacketListField = ([])
nlri : FieldListField = ([])
and was able to create this packet:
pkt = pkt = IP()/TCP()/BGPUpdate()
pkt.show()
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = tcp
chksum = None
src = 127.0.0.1
dst = 127.0.0.1
\options \
###[ TCP ]###
sport = ftp_data
dport = http
seq = 0
ack = 0
dataofs = None
reserved = 0
flags = S
window = 8192
chksum = None
urgptr = 0
options = {}
###[ BGP Update fields ]###
withdrawn_len= None
withdrawn = []
tp_len = None
\total_path\
nlri = []
I'm not sure what all of the different types of BGP layers/packets are used for or where the Communities Number would be set. Possibly in BGPPathAttribute(type=x). Type 5 is "LOCAL_PREF" which may correspond to Community Values. Try this Link.
pkt = BGPPathAttribute(type=5)
pkt.show()
###[ BGP Attribute fields ]###
flags = Transitive
type = LOCAL_PREF
attr_len = None
value = ''
Anyway, hope that helps a little.
Edit:
Forgot. I also added "bgp" to the load_layers section of scapy/config.py. Line 373. Like this:
load_layers = ["l2", "inet", "dhcp", "dns", "dot11", "gprs", "hsrp", "inet6", "ir", "isakmp", "l2tp",
"mgcp", "mobileip", "netbios", "netflow", "ntp", "ppp", "radius", "rip", "rtp",
"sebek", "skinny", "smb", "snmp", "tftp", "x509", "bluetooth", "dhcp6", "llmnr", "sctp", "vrrp",
"ipsec","bgp"]

Scapy fails to filter certain packets

I have got a simple sniff function set up with scapy which forwards the packet to a handshake function (I have a webserver set up on port 102. However some weird errors have come by, then I decided to print pkt.show(), what I discovered was that some packages DID come through the filter somehow.
My sniff function:
a=sniff(filter="port 102", count=10, prn=handshake)
This packet manages to come through:
###[ Ethernet ]###
dst = 84:8f:69:f5:fe:ac
src = b8:27:eb:92:a3:3b
type = 0x800
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 44
id = 1
flags =
frag = 0L
ttl = 64
proto = tcp
chksum = 0xe6c6
src = 192.168.137.178
dst = 192.168.137.1
\options \
###[ TCP ]###
sport = iso_tsap
dport = 2426
seq = 605952828
ack = 605952829
dataofs = 6L
reserved = 0L
flags = SA
window = 8192
chksum = 0x5b7c
urgptr = 0
options = [('MSS', 1460)]
As you can see the destination port is 2426, which is definetely not port 102.
Have I done something dumb?
The source port in the enclosed packet is iso_tsap which is 102. If you want to filter by the destination port try the filter "dst port 102". If you need something a bit more sophisticated, here is the syntax of BPF, which is used by scapy.

Categories

Resources