基于Linux的ARP攻击检测防护软件的设计独立的模块包括icmp flood、tcp攻击和ARP欺骗攻击检测若有则输出该攻击的类型若没有则输出并没有遭到该类攻击扫描和记录局域网内活动主机的IP地址和MAC地址能够记录攻击源的IP地址和MAC地址通过中文按钮分别实现可视化界面将所以记录保存在本地文件上。将模块结合起来通过python基本代码详细实现
首先,我们需要导入相关的库和模块:
import os
import sys
import time
import socket
import struct
import fcntl
import binascii
import threading
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
然后,我们需要定义一些常量和全局变量:
# ICMP Flood攻击检测阈值
ICMP_FLOOD_THRESHOLD = 1000
# TCP攻击检测阈值
TCP_THRESHOLD = 100
# ARP欺骗攻击检测阈值
ARP_THRESHOLD = 10
# 记录IP地址和MAC地址的字典
ip_mac_dict = {}
# 记录攻击源的IP地址和MAC地址的字典
attack_dict = {}
# 记录ICMP Flood攻击次数的变量
icmp_flood_count = 0
# 记录TCP攻击次数的变量
tcp_count = 0
# 记录ARP欺骗攻击次数的变量
arp_count = 0
接下来,我们需要定义一些函数来完成具体的功能。
首先是获取本地IP地址和MAC地址的函数:
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
s.close()
return ip
def get_local_mac(ifname):
with open('/sys/class/net/%s/address' % ifname) as f:
mac = f.read().strip()
return mac
然后是扫描局域网内的主机,并记录其IP地址和MAC地址的函数:
def scan_network():
global ip_mac_dict
local_ip = get_local_ip()
local_prefix = local_ip.split('.')[0] + '.' + local_ip.split('.')[1] + '.' + local_ip.split('.')[2] + '.'
for i in range(1, 255):
target_ip = local_prefix + str(i)
if target_ip == local_ip:
continue
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.1)
s.connect((target_ip, 135))
mac = get_mac_by_ip(target_ip)
if mac:
ip_mac_dict[target_ip] = mac
s.close()
except:
pass
接下来是获取指定IP地址的MAC地址的函数:
def get_mac_by_ip(ip):
try:
dst = struct.pack('>I', int(ip.split('.')[0]) << 24 | int(ip.split('.')[1]) << 16 | int(ip.split('.')[2]) << 8 | int(ip.split('.')[3]))
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0800))
s.bind((get_local_ip(), 0))
s.settimeout(0.1)
s.send(broadcast_packet(dst))
while True:
packet = s.recvfrom(2048)[0]
eth_header = struct.unpack('!6s6sH', packet[:14])
if eth_header[2] == 0x0806:
arp_header = struct.unpack('2s2s1s1s2s6s4s6s4s', packet[14:42])
if arp_header[4] == dst:
mac = binascii.hexlify(arp_header[5]).decode('utf-8')
s.close()
return mac
except:
pass
然后是生成广播ARP请求包的函数:
def broadcast_packet(dst):
src_mac = get_local_mac('eth0')
src_ip = get_local_ip()
packet = struct.pack('!6s6sH', binascii.unhexlify('ffffffffffff'), binascii.unhexlify(src_mac.replace(':', '')), 0x0806)
packet += struct.pack('!2s2s1s1s2s6s4s6s4s', b'\x00\x01', b'\x08\x00', b'\x06', b'\x04', b'\x01', binascii.unhexlify(src_mac.replace(':', '')), socket.inet_aton(src_ip), binascii.unhexlify('000000000000'), dst)
return packet
接下来是检测ICMP Flood攻击的函数:
def detect_icmp_flood(packet):
global icmp_flood_count
if packet[0] == 8:
icmp_flood_count += 1
if icmp_flood_count > ICMP_FLOOD_THRESHOLD:
attack_dict[packet[1]] = ip_mac_dict[packet[1]]
mb.showwarning('警告', '检测到ICMP Flood攻击,攻击源IP地址为%s,MAC地址为%s' % (packet[1], ip_mac_dict[packet[1]]))
icmp_flood_count = 0
else:
icmp_flood_count = 0
然后是检测TCP攻击的函数:
def detect_tcp(packet):
global tcp_count
if packet[0] == 6:
tcp_count += 1
if tcp_count > TCP_THRESHOLD:
attack_dict[packet[1]] = ip_mac_dict[packet[1]]
mb.showwarning('警告', '检测到TCP攻击,攻击源IP地址为%s,MAC地址为%s' % (packet[1], ip_mac_dict[packet[1]]))
tcp_count = 0
else:
tcp_count = 0
最后是检测ARP欺骗攻击的函数:
def detect_arp(packet):
global arp_count
if packet[0] == 2054:
arp_count += 1
if arp_count > ARP_THRESHOLD:
attack_dict[packet[1]] = ip_mac_dict[packet[1]]
mb.showwarning('警告', '检测到ARP欺骗攻击,攻击源IP地址为%s,MAC地址为%s' % (packet[1], ip_mac_dict[packet[1]]))
arp_count = 0
else:
arp_count = 0
接下来是启动网络监听线程的函数:
def start_sniffer():
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))
while True:
try:
packet = s.recvfrom(2048)[0]
eth_header = struct.unpack('!6s6sH', packet[:14])
if eth_header[2] == 0x0800:
ip_header = struct.unpack('!BBHHHBBH4s4s', packet[14:34])
protocol = ip_header[6]
src_ip = socket.inet_ntoa(ip_header[8])
dst_ip = socket.inet_ntoa(ip_header[9])
if protocol == 1:
detect_icmp_flood((ip_header[6], src_ip))
elif protocol == 6:
detect_tcp((ip_header[6], src_ip))
elif eth_header[2] == 0x0806:
arp_header = struct.unpack('2s2s1s1s2s6s4s6s4s', packet[14:42])
src_ip = socket.inet_ntoa(arp_header[6])
dst_ip = socket.inet_ntoa(arp_header[8])
if dst_ip == get_local_ip():
detect_arp((arp_header[2], src_ip))
except:
pass
然后是启动扫描局域网内主机的线程的函数:
def start_scanner():
while True:
scan_network()
time.sleep(60)
最后是启动可视化界面的函数:
def start_gui():
root = tk.Tk()
root.title('ARP攻击检测防护软件')
root.geometry('400x300')
ttk.Label(root, text='局域网内活动主机的IP地址和MAC地址').pack(pady=10)
tree = ttk.Treeview(root, columns=('IP地址', 'MAC地址'))
tree.column('IP地址', width=150)
tree.column('MAC地址', width=150)
tree.heading('IP地址', text='IP地址')
tree.heading('MAC地址', text='MAC地址')
tree.pack()
ttk.Label(root, text='攻击源的IP地址和MAC地址').pack(pady=10)
tree2 = ttk.Treeview(root, columns=('IP地址', 'MAC地址'))
tree2.column('IP地址', width=150)
tree2.column('MAC地址', width=150)
tree2.heading('IP地址', text='IP地址')
tree2.heading('MAC地址', text='MAC地址')
tree2.pack()
def refresh():
global ip_mac_dict, attack_dict
tree.delete(*tree.get_children())
tree2.delete(*tree2.get_children())
for ip, mac in ip_mac_dict.items():
tree.insert('', 'end', values=(ip, mac))
for ip, mac in attack_dict.items():
tree2.insert('', 'end', values=(ip, mac))
ttk.Button(root, text='刷新', command=refresh).pack(pady=10)
root.mainloop()
最后是将所有模块结合起来的主函数:
if __name__ == '__main__':
t1 = threading.Thread(target=start_sniffer)
t1.setDaemon(True)
t1.start()
t2 = threading.Thread(target=start_scanner)
t2.setDaemon(True)
t2.start()
start_gui()
这样,我们就完成了基于Linux的ARP攻击检测防护软件的设计
原文地址: https://www.cveoy.top/t/topic/fn22 著作权归作者所有。请勿转载和采集!