小白菜一棵,进修视频学习中!
1 ARP流量监控
- ARP攻击,使目标主机无法与外界通信:
攻击主机制造假的arp应答,并发送给局域网中除被攻击之外的所有主机。arp应答中包含被 攻击主机的IP地址和虚假的MAC地址。
攻击主机制造假的arp应答,并发送给被攻击的主机,arp应答中包含除被攻击攻击主机之外的所有主机的IP地址和虚假的MAC地址。
- ARP欺骗攻击,充当中间人,获取中间流量的信息:
以太网设备(比如网卡)都有自己全球唯一的MAC地址,它们是以MAC地址来传输以太网数据包的,但是以太网设备却识别不了IP数据包中的IP地址,所以要在以太网中进行IP通信,就需要一个协议来建立IP地址与MAC地址的对应关系,使IP数据包能够发送到一个确定的主机上。这种功能是由arp(AddressResolution Protocol)来完成的。
ARP欺骗就是破坏IP与MAC的真实对应关系。
ARP包的关键参数,psrc,hwsrc,op
op=(1/2) (who-has/is-at) (request/reply)
使用scapy监控(当IP与MAC绑定时):
# -*- coding=utf-8 -*-
import sys
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#清除报错
from ARP_Table import ARP_Table #导入合法的IP-ARP映射关系字典
from scapy.all import *
def arp_monitor_callback(pkt):
if ARP in pkt and pkt[ARP].op in (1,2): #找到op=1或2的数据包
if ARP_Table.get(pkt[ARP].psrc):#IP地址在合法的IP-ARP映射字典中
if ARP_Table[pkt[ARP].psrc] == pkt[ARP].hwsrc:#与合法的IP-ARP映射字典中MAC地址相符
print("IP地址: " + pkt[ARP].psrc + " MAC地址: " + pkt[ARP].hwsrc + " 匹配")
else:#与合法的IP-ARP映射关系字典中MAC地址不相符
print("IP地址: " + pkt[ARP].psrc + " MAC地址: " + pkt[ARP].hwsrc + " 不匹配!!!")
else:#IP地址在合法的IP-ARP映射字典中不存在
print("IP地址: " + pkt[ARP].psrc + " MAC地址: " + pkt[ARP].hwsrc + " 未找到条码!!!")
#捕获数据包,并通过方法arp_monitor_callback进行处理,filer过滤arp数据包,store=0不保存数据,iface指派接口
PTKS=sniff(prn=arp_monitor_callback, filter="arp", store=1, timeout =30,iface='eth0')
wrpcap('arp.cap',PTKS)
#保存数据包,必须设置timeout
ARP_Table.py
ARP_Table = {
"IP":"mac",
"ip":"mac"
}
2 Scapy分析PCAP包中的TCP
Python读取PCAP文件
提取所有TCP的源IP,目的IP,目的端口,并把这三元素作为字典的键,记录这三元组的会话数量。
如果数量超过3个,就报有DoS攻击发生
# -*- coding=utf-8 -*-
import logging
from scapy import *
from scapy.all import rdpcap
import sys
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#清除报错
def dos_find(filename):
pkts=rdpcap(filename)
pktlist = pkts.res
print('正在分析'+filename+'\n ***************************')
dos_dict = {}
for pkt in pktlist:
try:
if pkt[0][2].fields['flags'] == 2:
sourceip = pkt[0][1].fields['src']
desip = pkt[0][1].fields['dst']
desport = pkt[0][2].fields['dport']
socket = sourceip,desip,desport
try:
dos_dict[socket]
except:
dos_dict[socket]=1
else:
dos_dict[socket] = dos_dict[socket]+1
except:
pass
for socket,num in dos_dict.items():
if num >3:
print('可能存在来自'+str(socket[0])+' 发往'+str(socket[1])+' 端口为'+str(socket[2])+'的DOS攻击 '+'连接次数:'+str(num))
if __name__ == "__main__":
dos_find(sys.argv[1])
测试结果: