在Pcap.NET中创建有效的TCP连接

约翰

我正在尝试创建与测试服务器的有效TCP连接,以模拟GET请求。希望我已经很接近解决方案了。

使用来自真实请求的Wireshark数据,使用以下命令发送一个包时,我设法获得了SYNSYN-ACKPacketCommunicator.SendPacket()

在此处输入图片说明

但是,我似乎无法ACK露面。

前一个数据包使用构造EthernetLayer而后一个数据包(当前不起作用)使用刚才提到的数据包+ a IpV4LayerTcpLayerHttpRequestLayer

最后一个数据包TcpLayerControlBits设置为TcpControlBits.Acknowledgment尽管如此,它并没有像我的“真实” GET请求中那样显示在WireShark中。

希望我已经发布了代码的相关部分。如果没有,请告诉我。

砖匠

这是一个可行的草稿(我已经检查过)。

请将构造HttpGetSender实例时使用的值更改为所需的值。

棘手的部分是正确获取序列号和确认号。

using System;
using System.Collections.Generic;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Http;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;

namespace SendingHttpGet
{
    internal class HttpGetSender
    {
        public HttpGetSender()
        {
        }

        public MacAddress SourceMac { get; set; }
        public MacAddress DestinationMac { get; set; }
        public IpV4Address SourceIpV4 { get; set; }
        public IpV4Address DestinationIpV4 { get; set; }
        public string Host { get; set; }

        public void Run(PacketDevice device)
        {
            using (PacketCommunicator communicator = device.Open(100, // name of the device
                                                                 PacketDeviceOpenAttributes.Promiscuous,
                                                                 // promiscuous mode
                                                                 100)) // read timeout
            {
                SendSyn(communicator);
                WaitForAck(communicator);
            }
        }

        private void WaitForAck(PacketCommunicator communicator)
        {
            communicator.SetFilter("tcp and src " + DestinationIpV4 + " and dst " + SourceIpV4 + " and src port " + _destinationPort + " and dst port " + _sourcePort);
            Packet packet;
            while (true)
            {
                if (communicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                {
                    if (packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber == _expectedAckNumber)
                    {
                        _seqNumber = _expectedAckNumber;
                        _ackNumber = packet.Ethernet.IpV4.Tcp.SequenceNumber + 1;
                        SendGet(communicator);
                        break;
                    }

                }
                SendSyn(communicator);
            }
            WaitForResponse(communicator);
        }

        private void WaitForResponse(PacketCommunicator communicator)
        {
            communicator.SetFilter("tcp and src " + DestinationIpV4 + " and dst " + SourceIpV4 + " and src port " + _destinationPort + " and dst port " + _sourcePort);
            Packet packet;
            while (true)
            {
                if (communicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                {
                    Console.WriteLine("Expected ack number: " + _expectedAckNumber);
                    Console.WriteLine("Received ack number: " + packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber);
                    if (packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber == _expectedAckNumber)
                    {
                        break;
                    }

                }
                SendGet(communicator);
            }
        }

        private void SendSyn(PacketCommunicator communicator)
        {
            // Ethernet Layer
            EthernetLayer ethernetLayer = new EthernetLayer
                                              {
                                                  Source = SourceMac,
                                                  Destination = DestinationMac,
                                              };

            // IPv4 Layer
            IpV4Layer ipV4Layer = new IpV4Layer
                                      {
                                          Source = SourceIpV4,
                                          CurrentDestination = DestinationIpV4,
                                          Ttl = 128,
                                          Fragmentation =
                                              new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
                                          Identification = 1234,
                                      };

            // TCP Layer
            TcpLayer tcpLayer = new TcpLayer
                                    {
                                        SourcePort = _sourcePort,
                                        DestinationPort = _destinationPort,
                                        SequenceNumber = _seqNumber,
                                        ControlBits = TcpControlBits.Synchronize,
                                        Window = _windowSize,
                                    };

            communicator.SendPacket(PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer));
            _expectedAckNumber = _seqNumber + 1;
        }

        private void SendGet(PacketCommunicator communicator)
        {
            // Ethernet Layer
            EthernetLayer ethernetLayer = new EthernetLayer
            {
                Source = SourceMac,
                Destination = DestinationMac,
            };

            // IPv4 Layer
            IpV4Layer ipV4Layer = new IpV4Layer
            {
                Source = SourceIpV4,
                CurrentDestination = DestinationIpV4,
                Ttl = 128,
                Fragmentation =
                    new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
                Identification = 1235,
            };

            // TCP Layer
            TcpLayer tcpLayer = new TcpLayer
            {
                SourcePort = _sourcePort,
                DestinationPort = _destinationPort,
                SequenceNumber = _seqNumber,
                AcknowledgmentNumber = _ackNumber,
                ControlBits = TcpControlBits.Acknowledgment,
                Window = _windowSize,
            };

            // HTTP Layer
            HttpLayer httpLayer = new HttpRequestLayer
            {
                Uri = "/",
                Header = new HttpHeader(HttpField.CreateField("Host", Host)),
                Method = new HttpRequestMethod(HttpRequestKnownMethod.Get),
                Version = HttpVersion.Version11,
            };

            Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer, httpLayer);
            communicator.SendPacket(packet);
            _expectedAckNumber = (uint) (_seqNumber + packet.Ethernet.IpV4.Tcp.PayloadLength);
        }

        private ushort _sourcePort = (ushort) (4123 + new Random().Next() % 1000);
        private ushort _destinationPort = 80;
        private uint _seqNumber = (uint) new Random().Next();
        private uint _expectedAckNumber;
        private ushort _windowSize = 8192;
        private uint _ackNumber;
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            // Retrieve the device list from the local machine
            IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;

            if (allDevices.Count == 0)
            {
                Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
                return;
            }

            // Print the list
            for (int i = 0; i != allDevices.Count; ++i)
            {
                LivePacketDevice device = allDevices[i];
                Console.Write((i + 1) + ". " + device.Name);
                if (device.Description != null)
                    Console.WriteLine(" (" + device.Description + ")");
                else
                    Console.WriteLine(" (No description available)");
            }

            int deviceIndex = 0;
            do
            {
                Console.WriteLine("Enter the interface number (1-" + allDevices.Count + "):");
                string deviceIndexString = Console.ReadLine();
                if (!int.TryParse(deviceIndexString, out deviceIndex) ||
                    deviceIndex < 1 || deviceIndex > allDevices.Count)
                {
                    deviceIndex = 0;
                }
            } while (deviceIndex == 0);

            // Take the selected adapter
            PacketDevice selectedDevice = allDevices[deviceIndex - 1];

            HttpGetSender sender = new HttpGetSender
                                       {
                                           SourceMac = new MacAddress("your:host:mac:address:1:2"),
                                           DestinationMac = new MacAddress("gateway:mac:address:1:2:3"),
                                           SourceIpV4 = new IpV4Address("your.host.ip.address"),
                                           DestinationIpV4 = new IpV4Address("target.host.ip.address"),
                                           Host = "targethost.com",
                                       };

            sender.Run(selectedDevice);
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Pcap.NET中创建有效的TCP连接

来自分类Dev

从pcap文件中提取TCP有效负载

来自分类Dev

tcpdump或pcap中的加密有效负载

来自分类Dev

tcpdump或pcap中的加密有效负载

来自分类Dev

使用pcap记录TCP对话

来自分类Dev

'/'真的是可以通过pcap查找的有效设备吗?

来自分类Dev

使用Scapy从pcap文件中提取有效负载中的特定字节

来自分类Dev

“ tcpdump -w 1.pcap”有效,但“ tcpdump -C 100 -w 1.pcap”-权限被拒绝

来自分类Dev

“ tcpdump -w 1.pcap”有效,但“ tcpdump -C 100 -w 1.pcap”-权限被拒绝

来自分类Dev

Android Shark(tcpdump)创建无效的pcap

来自分类Dev

pcap.net mac地址设置

来自分类Dev

Pcap.Net获取网关地址

来自分类Dev

使用Pcap.Net获取Packete网址

来自分类Dev

在Ubuntu上安装perl net :: pcap

来自分类Dev

CPAN:无法安装Net / Pcap.pm

来自分类Dev

是否有Cassandra PCAP分析仪

来自分类Dev

无法在Visual Studio中编译PCAP程序

来自分类Dev

pcap_loop中的回调方法

来自分类Dev

pcap文件中数据包的方向

来自分类Dev

从Scapy中的PCAP文件获取IP地址

来自分类Dev

从pcap文件中删除radiotap标头

来自分类Dev

在python中解析原始.pcap流

来自分类Dev

无法在Visual Studio中编译PCAP程序

来自分类Dev

在纯C中解析.pcap文件

来自分类Dev

从pcap捕获中提取数据有效载荷

来自分类Dev

确定由tcpdump创建的pcap文件中的数据包层

来自分类Dev

在pcap.net中捕获icmp数据包

来自分类Dev

更改pcap.net C#中的ip

来自分类Dev

在.NET中创建有效的数据包嗅探器