在本地网络上嗅探Android设备的TCP数据包

时间:2019-07-02 09:18:07

标签: c# packet packet-sniffers packet-capture pcapdotnet

我正在使用C#和PcapDotNet编写数据包嗅探器,我已经成功实现了该功能,并且能够从笔记本电脑捕获所有TCP数据包,问题是如果我瞄准了我的android设备,那么我根本就不会收到任何数据包, 我是网络的初学者,所以我认为我可能会缺少一些东西。

这是我的数据包处理程序代码,我使用的是ObjectListView和一个模型对象,其中包含要列出的所有信息,并且我的网络适配器处于混杂模式,带有Berkeley过滤器,仅使用端口号443和80,其中包含来自特定Mac地址的数据(无SYN,FIN,仅ACK数据包)

代码:

        private void PacketHandler(PcapDotNet.Packets.Packet packet)
        {
            if (packet == null) { return; }
            if (packet.Ethernet == null) { return; }
            if (packet.Ethernet.IpV4 == null) { return; }
            if (packet.Ethernet.IpV4.Tcp == null) { return; }
            if (packet.Ethernet.IpV4.Tcp.Http == null) { return; }

            var acpacket = new AcceptedPacket(); //Model Object
            acpacket.Packet = packet;
            try
            {
                HttpDatagram http = packet.Ethernet.IpV4.Tcp.Http;
                if (packet.Ethernet.Source.ToString() == targetmac)
                {
                    if (http.IsRequest && http.IsValid)
                    {
                        if (materialListView1.InvokeRequired)
                        {
                            materialListView1.BeginInvoke(new Action(() => { 
                            materialListView1.AddObject(acpacket); }));
                        }
                        else
                        {
                            materialListView1.AddObject(acpacket);
                        }
                        ListofAcceptedPackets.Add(acpacket);
                    }
                }
            }
            catch (Exception ex)
            {
                MetroMessageBox.Show(this, ex.Message, "Error", 
                MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
            }
        }

这就是我打开适配器的方式:

    using (communicator =
  selectedDevice.Open(65536,PacketDeviceOpenAttributes.Promiscuous,
   1000))
    {
        if (communicator.DataLink.Kind != 
        DataLinkKind.Ethernet)
        {
            if (MetroMessageBox.Show(this, "Only Ethernet is supported in this operation!","Error", MessageBoxButtons.OK,MessageBoxIcon.Error) == DialogResult.OK)
                    {
                    return;
                    }
        }

        using (BerkeleyPacketFilter filter = communicator.CreateFilter($"tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) and ether src {targetmac.ToLower()} or tcp port 443 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) and ether src {targetmac.ToLower()}"))
        {
        communicator.SetFilter(filter);
        }

        flag = true;


        Packet packet;
        do
        {
            PacketCommunicatorReceiveResult result = 
            communicator.ReceivePacket(out packet);
            switch (result)
            {
                case 
                PacketCommunicatorReceiveResult.Timeout:
                continue;

                case 
                PacketCommunicatorReceiveResult.Ok:
                {
                    PacketHandler(packet);
                }
                    break;

                default:
                    break;
            }
        } while (flag);

}     

我也尝试了没有任何过滤器的情况,无法到达android设备数据包。 这样就可以从我自己的设备以外的网络上的其他设备捕获TCP数据包吗?还是我的实现有问题?

编辑:尝试了更多之后,我能够从android设备成功获取TCP数据包,但仅在同时实施ARP Cache Poisoning的同时,因为该设备认为我是网关。所以我的问题是,可以在没有ARP缓存中毒的情况下完成此操作,因为我认为这对于数据包嗅探器来说有点激进。

1 个答案:

答案 0 :(得分:0)

我终于可以通过应用ARP缓存中毒使其工作,而下面的代码可以将任何设备的数据包重定向到目的地,这样您就可以捕获网络上任何设备的数据包,而又不会失去Internet访问权限用于此设备。

代码:

   private void StartSniffer()
        {

            RawCapture rawCapture;
            do
            {
                if ((rawCapture = capturedevice.GetNextPacket()) != null)
                {
                    EthernetPacket Packet = PacketDotNet.Packet.ParsePacket(rawCapture.LinkLayerType, rawCapture.Data) as EthernetPacket;
                    if (Packet == null) { return; }

                    AcceptedPacket acPacket = new AcceptedPacket();
                    acPacket.Packet = Packet;

                    if (Packet.SourceHwAddress.Equals(TargetMAC))
                    {
                        Packet.SourceHwAddress = capturedevice.MacAddress;
                        Packet.DestinationHwAddress = GatewayMAC;
                        capturedevice.SendPacket(Packet);

                        if (acPacket.TCPPacket != null &&
                            ((acPacket.Type.Equals("HTTPS") && acPacket.TCPPacket.PayloadData != null) ||
                             (acPacket.Type.Equals("HTTP") && acPacket.TCPPacket.PayloadData != null)))
                        {

                            materialListView1.BeginInvoke(new Action(() =>
                            {
                                materialListView1.AddObject(acPacket);

                                if (materialListView1.Items.Count > 15 && !ResizeDone)
                                {
                                    olvColumn8.MaximumWidth = 65;
                                    olvColumn8.MinimumWidth = 65;
                                    olvColumn8.Width = 65;
                                    ResizeDone = true;
                                }

                                ListofAcceptedPackets.Add(acPacket);

                            }));

                        }
                    }

                    else if (Packet.SourceHwAddress.Equals(GatewayMAC))
                    {
                        IPv4Packet IPV4 = Packet.Extract(typeof(IPv4Packet)) as IPv4Packet;

                        if (IPV4.DestinationAddress.Equals(Target))
                        {
                            Packet.SourceHwAddress = capturedevice.MacAddress;
                            Packet.DestinationHwAddress = TargetMAC;
                            capturedevice.SendPacket(Packet);
                        }

                        if (Properties.Settings.Default.PacketDirection == "Inbound")
                        {
                            if (acPacket.TCPPacket != null &&
                                ((acPacket.Type.Equals("HTTPS") && acPacket.TCPPacket.PayloadData != null) ||
                                 (acPacket.Type.Equals("HTTP") && acPacket.TCPPacket.PayloadData != null)))
                            {
                                materialListView1.BeginInvoke(new Action(() =>
                                {
                                    materialListView1.AddObject(acPacket);

                                    if (materialListView1.Items.Count > 15 && !ResizeDone)
                                    {
                                        olvColumn8.MaximumWidth = 65;
                                        olvColumn8.MinimumWidth = 65;
                                        olvColumn8.Width = 65;
                                        ResizeDone = true;
                                    }

                                    ListofAcceptedPackets.Add(acPacket);


                                }));
                            }
                        }
                    }
                }

            } while (snifferStarted);

这是捕获设备的设置:

 try
    {
        snifferStarted = true;
        if (capturedevice != null)
        {
            capturedevice.Open(DeviceMode.Promiscuous, 1000);

                capturedevice.Filter = $"(ip and ether src {targetmac.ToLower()}) or (ip and ether src {gatewayMAC.ToLower()} and dst net {Target})";

            new Thread(() => { StartSniffer(); }).Start();
        }
        else
        {
            MetroMessageBox.Show(this, "No Capture Device is selected!", "Error", MessageBoxButtons.OK,
                MessageBoxIcon.Error);
        }
    }
    catch (Exception exception)
    {
        MetroMessageBox.Show(this, exception.Message, "Error", MessageBoxButtons.OK,
            MessageBoxIcon.Error);
    }

注意:这是使用Packet.Net而非PcapDotNet完成的。