阅读量: 78
Scapy
一、基础
1.介绍
-
监听数据包(与wireshark相同),分析流量,编辑流量数据包(链路层,网络层,传输层),应用层 也可以编辑,但是意义不大
-
scapy提供两种操作方式:基于命令行进行交互,直接在python代码中调用。
2.命令
show_interfaces() # 显示所有网卡
sniff(count=10) # 在所有网卡监听,一共10个数据包
pkg=sniff(count=10)
pkg[0].show() # 显示第一个数据包的信息
pkg.summary() # 显示捕获到的数据包的摘要
pkg=sniff(count=8,filter=*icmp*) # 只监听8个icmp的数据包
3.sniff参数
sniff(count=0,
store=1,
offline=None,
prn=None,
filter=None,
L2socket=None,
timeout=None,
opened_socket=None,
stop_filter=None,
iface=None)
# 参数含义
count:指定最多嗅探多少个符合要求的报文,设置为0时则一直捕获
store:指定保存抓取的数据包或者丢弃,1为保存,0为丢弃
offline:从pcap文件中读取数据包,而不进行嗅探,默认为None
prn:为每个数据包定义一个回调函数,回调函数会在捕获到符合 filter 的报文时被调用,通常使用 lambda 表达式来编写
filter:用来筛选抓取的信息,其用法与常见抓包软件WireShark 等相同,遵循 BPF 语法
L2socket:使用给定的L2socket
timeout:在给定的事件后停止嗅探,默认为None
opened_socket:对指定的对象使用.recv进行读取
stop_filter:定义一个函数,决定在抓到指定的数据之后停止
iface:指定抓包的网卡,不指定则代表所有网卡
二、数据包编辑
-
编辑Ping数据包
send(IP(dst="192.168.101.9")/ICMP())
send(IP(dst="192.168.101.9")/ICMP()/"hello,world") # 附加数据hello,world
# 发送并接收回应,将回应赋值给pkg
pkg=sr1(IP(dst="192.168.101.9")/ICMP()/"hello,world")
-
编辑ARP数据包
pkg=sr1(ARP(psrc="192.168.101.2",pdst="192.168.101.9"))
三、网络扫描
import threading, socket
from scapy.sendrecv import sr1
from scapy.layers.l2 import ARP
# 配置日志记录的级别为ERROR级别
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
# 扫描IP
def scapy_ip(start):
for i in range(start, start+20)
ip = f'192.168.101.{i}
try:
pkg = ARP(psrc='192.168.101.2',pdst=ip)
reply = sr1(pkg.timeout=3,verbose=False)
print(f"{ip}在线,MAC地址为{reply[ARP],hwsrc}")
# socket_port(ip)
for i in range(1,10241,50):
threding.Thread(target=scapy_port, args=(ip,i)),start()
except:
pass
# 使用socket扫描端口的方法
def socket_port(ip):
for port in range(1, 65536):
try:
s = socket.socket()
s.settimeout(0.5)
s.connect((ip,port))
print(f" 端口{port}开放.")
s.close()
except ConnectionRefusedError:
pass
except socket.timeout;
pass
# 使用scapy构造基于半连接扫描端口的方法
def scapy_port(ip,start):
pkg = IP(src='192.168.101.2', dst=ip)/TCP(dport=port, flags='s')
reply = sr1(pkg,timeout=0.7,verbose=False) # 设置超时时间,取消将信息在屏幕显示
for port in range(start,start+50):
try:
if reply[TCP].flags == 0x12:
print(f" 端口{port}开放")
except:
pass
time.sleep(3)
if __name__ == '__main__':
# 使用多线程扫描
for i in range(1,255,20):
threding.Thread(target=scapy_ip, args=(i,)),start()
四、完成三次握手
-
三次握手必要:源IP,源端口,协议,目标IP,目标端口,标志位
seq = random.randint(10000, 20000)
sport = rangom.randint(2049, 4096)
pkg1 = IP(dst='192.168.101.9')/TCP(sport=sport,dport=80,flags='S',seq=seq)
reply = sr1(pkg)
seq = reply[TCP].ack
ack = reply[TCP].sreq + 1
pkg2 = IP(dst='192.168.101.9')/TCP(sport=sport,dport=80,flags='A',seq=seq)
sr1(pkg2)