scapy安装&运行
# unzip scapy-2.4.0.zip
# cd scapy-2.4.0/
# python setup.py install
# ./run_scapy
简单使用
>>> a=IP(ttl=10)
>>> a
<IP ttl=10 |>
>>> a.src
'127.0.0.1'
>>> a.dst="192.168.1.1"
>>> a
<IP ttl=10 dst=192.168.1.1 |>
>>> a.src
'192.168.0.8'
>>> del(a.ttl)
>>> a
<IP dst=192.168.1.1 |>
>>> a.ttl
64
>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=tcp |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=IPv4 |<IP frag=0 proto=tcp |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=tcp |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=IPv4 |<IP frag=0 proto=ipv4 |<IP frag=0 proto=udp |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=mobile |<TCP |>>
>>>
>>> raw(IP())
'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'
>>> IP(_)
<IP version=4 ihl=5 tos=0x0 len=20 id=1 flags= frag=0 ttl=64 proto=ip chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |>
构造IPv6报文
>>> a=Ether(dst="20:10:20:30:40:50")/IPv6(src="2400:da00:e001:1::8", dst="2400:da00:e001:1::2000")/TCP(sport=10000, dport=30000, flags="S")
>>> a.show()
>>> sendp(a, iface="eth0")
IPv6扩展头可以指定IPv6ExtHdrHopByHop、IPv6ExtHdrRouting、IPv6ExtHdrFragment、IPv6ExtHdrDestOpt
发送多个报文
>>> a=Ether(dst="20:10:20:30:40:50")/IPv6(src="2400:da00:e001:1::8", dst="2400:da00:e001:1::2000")/TCP(sport=(10000, 10099), dport=30000, flags="S")
>>> sendp(a, iface="eth0")
构造vxlan报文
>>> a=Ether(dst="00:00:5e:00:01:64", src="f8:f2:1e:03:90:a8")
>>> b=IP(src="100.64.64.20",dst="100.64.43.2")
>>> c=UDP(dport=4789)
>>> d=VXLAN(vni=291)
>>> e=Ether(dst="10:20:30:40:50:60", src="fa:16:3e:99:61:04")
>>> f=IPv6(src="2400:da00:e001:f04::4", dst="2400:da00:e001:f05::2000")
>>> g=ICMPv6EchoReply()
>>> p=a/b/c/d/e/f/g
>>> sendp(p, iface="bond0", loop=1, inter=0.1)
TCP三次握手
#!/usr/bin/env python
#! -*- coding: utf-8 -*-
# Three Way Handshaking using Scapy
from scapy.all import *
pkt = IP(src="172.16.0.135", dst="172.16.0.137")
SYN = TCP(sport=10500, dport=80, flags='S', seq=100, window=8192, options=[('MSS', 1460)])
SYNACK = sr1(pkt/SYN, iface="eth0")
my_ack = SYNACK.seq + 1
ACK = TCP(sport=10500, dport=80, flags='A', seq=101, ack=my_ack)
send(pkt/ACK)
payload = Raw(RandString(size=1460))
PUSH = TCP(sport=10500, dport=80, flags='PA', seq=101, ack=my_ack)
send(pkt/PUSH/payload)
为了阻止发送主机协议栈对接收到的syn/ack报文,自动回复rst报文,还需要配置iptables规则:
iptables -A OUTPUT -p tcp –tcp-flags RST RST -d 172.16.0.137 -j DROP