功能目标是监听系统内所有网络请求,并读获取请求的目标Url。 SharpPcap是基于WinPcap功能构建的类库,可以用于监听网络。 使用SharpPcap需要在系统中先安装WinPcap,否则执行时会报错说没有此模块。 WinPcap下载地址:http://www.winpcap.org/install/default.htm SharpPcap项目现在已经迁移到了Github,网址:https://github.com/chmorgan/sharppcap 下载源码并整合到项目中。 编写代码:
class Program
    {

        private static Regex httpgetRegex = new Regex(@"GETs+([^srn]+)s+HTTP");
        private static Regex hostRegex = new Regex(@"Host:s*([^srn]+)");

        static void Main(string[] args)
        {

            var devices = SharpPcap.CaptureDeviceList.Instance;

            //遍历网卡设备,输出编号、名称、注释
            var x = 0;
            foreach (var f in devices)
            {
                Console.WriteLine($@"[{x++}] {f.Name}
    {f.Description}");
            }

            Console.WriteLine();
            //输入要监听的网卡设备编号
            Console.Write("-- Please choose a device to capture: ");
            x = int.Parse(Console.ReadLine());

            var device = devices[x];

            //注册截获包的处理事件
            // Register our handler function to the 'packet arrival' event
            device.OnPacketArrival +=
                new PacketArrivalEventHandler(device_OnPacketArrival);

            //开启设备以监听
            // Open the device for capturing
            int readTimeoutMilliseconds = 1000;
            if (device is AirPcapDevice)
            {
                // NOTE: AirPcap devices cannot disable local capture
                var airPcap = device as AirPcapDevice;
                airPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp, readTimeoutMilliseconds);
            }
            else if (device is WinPcapDevice)
            {
                var winPcap = device as WinPcapDevice;
                winPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp | SharpPcap.WinPcap.OpenFlags.NoCaptureLocal, readTimeoutMilliseconds);
            }
            else if (device is LibPcapLiveDevice)
            {
                var livePcapDevice = device as LibPcapLiveDevice;
                livePcapDevice.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
            }
            else
            {
                throw new System.InvalidOperationException("unknown device type of " + device.GetType().ToString());
            }

            //设置协议过滤
            // tcpdump filter to capture only TCP/IP packets
            string filter = "ip and tcp";
            device.Filter = filter;

            Console.WriteLine();
            Console.WriteLine("-- Listening on {0} {1}, hit 'Enter' to stop...",
                device.Name, device.Description);

            //开始监听
            // Start the capturing process
            device.StartCapture();

            // Wait for 'Enter' from the user.
            Console.ReadLine();

            // Stop the capturing process
            device.StopCapture();

            Console.WriteLine("-- Capture stopped.");

            // Print out the device statistics
            Console.WriteLine(device.Statistics.ToString());

            // Close the pcap device
            device.Close();
        }

        /// <summary>
        /// 截获包的处理事件
        /// Prints the time and length of each received packet
        /// </summary>
        private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            //var time = e.Packet.Timeval.Date;
            //var len = e.Packet.Data.Length;
            //Console.WriteLine("{0}:{1}:{2},{3} Len={4}",
            //    time.Hour, time.Minute, time.Second, time.Millisecond, len);
            //Console.WriteLine(e.Packet.ToString());
            //_logger.Info(e.Packet.ToString());

            //转换为TCP包
            var packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
            var tcpPacket = TcpPacket.GetEncapsulated(packet);
            //用UTF8编码解析包的内容
            var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);

        //输出包的ID信息
            Console.WriteLine($"{nameof(tcpPacket.AcknowledgmentNumber)}:{tcpPacket.AcknowledgmentNumber}  {nameof(tcpPacket.SequenceNumber)}:{tcpPacket.SequenceNumber}");

        //如果能分析到HTTP报头中的Url,则输出之
            var url = httpgetRegex.Match(datastr);
            if (url.Success)
            {
                var host = hostRegex.Match(datastr);
                if (host.Success)
                {
                    Console.WriteLine(host.Groups[1].Value + url.Groups[1].Value);
                }
            }
        }

}
运行起来: image image 这样机器上所有通过此网卡进行的TCP请求就都能截获了,如果有HTTP请求的话网址就显示出来了。(当然前提是你得选对网卡编号) SharpPcap的源码 以及 WinPcap 4.1.3安装包:http://vdisk.weibo.com/s/t2jT2xw0nMn
转载此文章时须注明转载自”SkyD(斯克迪亚)开发者博客“,并保留此文章的Url链接

作者信息

昵称
斯克迪亚

查看其所发布的所有文章

总积分
2440
注册时间
(2018年5月4日 19:06)

评论

目前还没有任何评论。

[切换到移动版页面]