使用 Scapy 设置 BGP 层
Setting up BGP Layer Using Scapy
我正在尝试使用 Scapy 发送具有 BGP 层的数据包
我目前停留在这个问题的基本部分,因为我无法设置 BGP 层。我按照说明设置了常规 IP 和 TCP 层。
例如:
>>a=IP(src="192.168.1.1",dst="192.168.1.2")/TCP(sport=179,dport=50)
但是我这样做的时候出现了问题:
>>a=a/BGP()
NameError: name BGP is not defined
我在 Scapy 的 contrib 文件中看到了 BGP 实现 Github (https://github.com/secdev/scapy/blob/9201f1cf1318edd5768d7e2ee968b7fba0a24c5e/scapy/contrib/bgp.py) 所以我认为 Scapy 确实支持 BGP 实现
我是网络新手,所以我想知道您是否可以帮助我设置 BGP 层
感谢您花时间阅读本文!
只是想尝试在这里提供帮助。我对 BGP 类型数据包的经验为零,但是...我将 bgp.py 文件从您提供的 link 复制到 scapy/layers。使用 ls() 我发现了以下内容:
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
然后我可以使用 ls(BGPUpdate) 来显示:
withdrawn_len : ShortField = (None)
withdrawn : FieldListField = ([])
tp_len : ShortField = (None)
total_path : PacketListField = ([])
nlri : FieldListField = ([])
并且能够创建此数据包:
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 = []
我不确定所有不同类型的 BGP layers/packets 的用途是什么,或者社区编号将设置在何处。可能在 BGPPathAttribute(type=x) 中。类型 5 是 "LOCAL_PREF",可能对应于社区价值观。试试这个 Link.
pkt = BGPPathAttribute(type=5)
pkt.show()
###[ BGP Attribute fields ]###
flags = Transitive
type = LOCAL_PREF
attr_len = None
value = ''
总之,希望对你有所帮助。
编辑:
忘记。我还将 "bgp" 添加到 scapy/config.py 的 load_layers 部分。第 373 行。像这样:
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 的 BGP 层。当 BGP 通过 TCP 传输时。所以我们必须有一个已建立的 (3 way handshake) tcp 套接字。 TCP 通过 IP 传输。因此我们可以用下面的格式表示完整的数据包。
packet = IP Layer / TCP Layer / BGP Layer
但是BGP本身分为两部分,BGP Header和BGP Payload (EG: OPEN, UPDATE, etc )。所以上面的层表示如下。
packet = IP Layer / TCP Layer / BGP Header / BGP payload
这里的 BGP Header 指定了 BGP 的身份验证、长度和类型 Payload.To 在 scapy 中代表了整个事情,我们可以做下面的练习。 (我在这里假设您已经建立了 TCP 套接字。)
from scapy.layers.inet import IP, TCP
from scapy.contrib.bgp import BGPHeader, BGPUpdate, BGPPathAttr, BGPNLRI_IPv4
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()
使用以下变量值(用于举例)。
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'
输出如下。
###[ 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
我正在尝试使用 Scapy 发送具有 BGP 层的数据包
我目前停留在这个问题的基本部分,因为我无法设置 BGP 层。我按照说明设置了常规 IP 和 TCP 层。
例如:
>>a=IP(src="192.168.1.1",dst="192.168.1.2")/TCP(sport=179,dport=50)
但是我这样做的时候出现了问题:
>>a=a/BGP()
NameError: name BGP is not defined
我在 Scapy 的 contrib 文件中看到了 BGP 实现 Github (https://github.com/secdev/scapy/blob/9201f1cf1318edd5768d7e2ee968b7fba0a24c5e/scapy/contrib/bgp.py) 所以我认为 Scapy 确实支持 BGP 实现
我是网络新手,所以我想知道您是否可以帮助我设置 BGP 层
感谢您花时间阅读本文!
只是想尝试在这里提供帮助。我对 BGP 类型数据包的经验为零,但是...我将 bgp.py 文件从您提供的 link 复制到 scapy/layers。使用 ls() 我发现了以下内容:
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
然后我可以使用 ls(BGPUpdate) 来显示:
withdrawn_len : ShortField = (None)
withdrawn : FieldListField = ([])
tp_len : ShortField = (None)
total_path : PacketListField = ([])
nlri : FieldListField = ([])
并且能够创建此数据包:
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 = []
我不确定所有不同类型的 BGP layers/packets 的用途是什么,或者社区编号将设置在何处。可能在 BGPPathAttribute(type=x) 中。类型 5 是 "LOCAL_PREF",可能对应于社区价值观。试试这个 Link.
pkt = BGPPathAttribute(type=5)
pkt.show()
###[ BGP Attribute fields ]###
flags = Transitive
type = LOCAL_PREF
attr_len = None
value = ''
总之,希望对你有所帮助。
编辑: 忘记。我还将 "bgp" 添加到 scapy/config.py 的 load_layers 部分。第 373 行。像这样:
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 的 BGP 层。当 BGP 通过 TCP 传输时。所以我们必须有一个已建立的 (3 way handshake) tcp 套接字。 TCP 通过 IP 传输。因此我们可以用下面的格式表示完整的数据包。
packet = IP Layer / TCP Layer / BGP Layer
但是BGP本身分为两部分,BGP Header和BGP Payload (EG: OPEN, UPDATE, etc )。所以上面的层表示如下。
packet = IP Layer / TCP Layer / BGP Header / BGP payload
这里的 BGP Header 指定了 BGP 的身份验证、长度和类型 Payload.To 在 scapy 中代表了整个事情,我们可以做下面的练习。 (我在这里假设您已经建立了 TCP 套接字。)
from scapy.layers.inet import IP, TCP
from scapy.contrib.bgp import BGPHeader, BGPUpdate, BGPPathAttr, BGPNLRI_IPv4
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()
使用以下变量值(用于举例)。
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'
输出如下。
###[ 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