新思想

C# 端口扫描 源代码

C# 端口扫描 源代码

PortScan

 

portscan

 

一、基本扫描

using System;
using System.Net;
using System.Net.Sockets;

namespace SimplePortScan
{
    class SimplePortScan
    {
        static void Main(string[] args)
        {
            //private readonly int[] ports = new int[] { 21, 22, 23, 25, 53, 80, 110, 118, 135, 143, 156, 161, 443, 445, 465, 587, 666, 990, 991, 993, 995, 1080, 1433, 1434, 1984, 2049, 2483, 2484, 3128, 3306, 3389, 4662, 4672, 5222, 5223, 5269, 5432, 5500, 5800, 5900, 8000, 8008, 8080 };
            //private string[] explain = new string[] {"FTP", "SSH", "Telnet", "SMTP", "DNS", "HTTP", "POP3", "SQL 服务", "RPC(远程过程调用)", "IMAP4",
            //    "SQL", "SNMP", "HTTPS or QQ", "SMB", "SMTP over SSL", "SMTP", "Games", "FTP Protocol (control)over TLS / SSL", "NAS(Netnews Admin System)", "IMAP",
            //    "POP3", "SOCKS proxy", "Microsoft SQL 服务器", "Microsoft SQL 监视器", "network monitoring tool", "NFS Server", "Oracle database listening port for unsecure client connections to the listener", "Oracle database listening port for SSL client connections to the listener",  "HTTP", "mysql",
            //    "远程桌面协议(RDP)", "eMule", "eMule", "XMPP / Jabber - client connection", "XMPP / Jabber - default port for SSL Client Connection", "XMPP / Jabber - server connection", "PostgreSQL", "VNC remote desktop protocol - for incoming listening viewer", "VNC remote desktop protocol - for use over HTTP", "VNC remote desktop protocol",
            //    "QQ", "HTTP", "HTTP" };

            // FTP, SSH, Telnet, SMTP, HTTP, POP3, RPC, SMB, SMTP, IMAP, POP3
            int[] ports = new int[] { 21, 22, 23, 25, 80, 110, 135, 445, 587, 993, 995 };

            Random rand = new Random((int)DateTime.Now.Ticks);
            Console.WriteLine("开始扫描 . . . ");
            foreach (int port in ports)
            {
                Socket scanSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                //超时设置,可惜不起作用
                //scanSocket.ReceiveTimeout = 1000;
                //scanSocket.SendTimeout = 1000;

                //寻找一个未使用的端口进行绑定
                do
                {
                    try
                    {
                        scanSocket.Bind(new IPEndPoint(IPAddress.Any, rand.Next(65535)));
                        break;
                    }
                    catch
                    {
                        //绑定失败  
                    }
                } while (true);

                try
                {
                    scanSocket.Connect(IPAddress.Parse(args[0]), port);
                    if (scanSocket.Connected)
                        Console.WriteLine("{0}:{1} <-> {2}:{3} \t端口 {4,5}\t打开.", ((IPEndPoint)scanSocket.LocalEndPoint).Address, ((IPEndPoint)scanSocket.LocalEndPoint).Port, ((IPEndPoint)scanSocket.RemoteEndPoint).Address, ((IPEndPoint)scanSocket.RemoteEndPoint).Port, port);
                    //else    // 不会执行
                    //    Console.WriteLine("{0}:{1} <-> {2}:{3} \t端口 {4,5}\t关闭.", ((IPEndPoint)scanSocket.LocalEndPoint).Address, ((IPEndPoint)scanSocket.LocalEndPoint).Port, ((IPEndPoint)scanSocket.RemoteEndPoint).Address, ((IPEndPoint)scanSocket.RemoteEndPoint).Port, port);

                    //关闭套接字
                    scanSocket.Close();
                }
                catch
                {
                    Console.WriteLine("端口 {0,5}\t关闭.", port);
                    //关闭套接字
                    scanSocket.Close();
                    continue;
                }
            }
            Console.WriteLine("扫描结束!");
            //Console.ReadKey();
        }
    }
}

 

二、多线程扫描

using System;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace ThreadPortScan
{
    class ThreadPortScan
    {
        private readonly int N = 10;
        private IPAddress ip;
        // FTP, SSH, Telnet, SMTP, DNS, HTTP, POP3, SQL, RPC, IMAP4, SQL, SNMP, HTTP over TLS/SSL or QQ, SMB, SMTP over SSL, SMTP, Games, FTP Protocol (control)over TLS / SSL, NAS(Netnews Admin System), IMAP, POP3, Microsoft SQL 服务器, Microsoft SQL 监视器, network monitoring tool, NFS Server, Oracle database listening port for unsecure client connections to the listener, Oracle database listening port for SSL client connections to the listener, mysql, 遠端桌面協定(RDP), eMule, eMule, XMPP / Jabber - client connection, XMPP / Jabber - default port for SSL Client Connection, XMPP / Jabber - server connection, PostgreSQL, VNC remote desktop protocol - for incoming listening viewer, VNC remote desktop protocol - for use over HTTP, VNC remote desktop protocol, QQ, HTTP, HTTP
        private readonly int[] ports = new int[] { 21, 22, 23, 25, 53, 80, 110, 118, 135, 143, 156, 161, 443, 445, 465, 587, 666, 990, 991, 993, 995, 1080, 1433, 1434, 1984, 2049, 2483, 2484, 3128, 3306, 3389, 4662, 4672, 5222, 5223, 5269, 5432, 5500, 5800, 5900, 8000, 8008, 8080 };
        private string[] explain = new string[] {"FTP", "SSH", "Telnet", "SMTP", "DNS", "HTTP", "POP3", "SQL 服务", "RPC(远程过程调用)", "IMAP4",
            "SQL", "SNMP", "HTTPS or QQ", "SMB", "SMTP over SSL", "SMTP", "Games", "FTP Protocol (control)over TLS / SSL", "NAS(Netnews Admin System)", "IMAP",
            "POP3", "SOCKS proxy", "Microsoft SQL 服务器", "Microsoft SQL 监视器", "network monitoring tool", "NFS Server", "Oracle database listening port for unsecure client connections to the listener", "Oracle database listening port for SSL client connections to the listener",  "HTTP", "mysql",
            "远程桌面协议(RDP)", "eMule", "eMule", "XMPP / Jabber - client connection", "XMPP / Jabber - default port for SSL Client Connection", "XMPP / Jabber - server connection", "PostgreSQL", "VNC remote desktop protocol - for incoming listening viewer", "VNC remote desktop protocol - for use over HTTP", "VNC remote desktop protocol",
            "QQ", "HTTP", "HTTP" };
        private Random rand = new Random((int)DateTime.Now.Ticks);

        private void scanport(object s)
        {
            int start;
            int.TryParse(s.ToString(), out start);
            for (int port = start; port < ports.Length; port += N)
            {
                Socket scanSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

                //寻找一个未使用的端口进行绑定
                //do
                //{
                //    try
                //    {
                //        scanSocket.Bind(new IPEndPoint(IPAddress.Any, rand.Next(65535)));
                //        break;
                //    }
                //    catch
                //    {
                //        //绑定失败  
                //    }
                //} while (true);

                try
                {
                    scanSocket.Connect(ip, ports[port]);
                    if (scanSocket.Connected)
                        Console.WriteLine("{0}:{1} <-> {2}:{3} \t端口 {4,5} 打开. \t{5}.", ((IPEndPoint)scanSocket.LocalEndPoint).Address, ((IPEndPoint)scanSocket.LocalEndPoint).Port, ((IPEndPoint)scanSocket.RemoteEndPoint).Address, ((IPEndPoint)scanSocket.RemoteEndPoint).Port, ports[port], explain[port]);
                    //else    // 不会执行
                        //Console.WriteLine("{0}:{1} <-> {2}:{3} \t端口 {4,5} 关闭. \t{5}.", ((IPEndPoint)scanSocket.LocalEndPoint).Address, ((IPEndPoint)scanSocket.LocalEndPoint).Port, ((IPEndPoint)scanSocket.RemoteEndPoint).Address, ((IPEndPoint)scanSocket.RemoteEndPoint).Port, ports[port], explain[port]);

                    //关闭套接字
                    scanSocket.Close();
                }
                catch
                {
                    Console.WriteLine("端口 {0,5} 关闭.", ports[port]);
                    //关闭套接字
                    scanSocket.Close();
                    continue;
                }
            }
        }

        static void Main(string[] args)
        {
            ThreadPortScan ps = new ThreadPortScan();

            IPAddress.TryParse(args[0], out ps.ip);
            Console.WriteLine("开始扫描 . . . ");
            Thread[] sp = new Thread[ps.N];

            for (int i = 0; i < ps.N; i++)
            {
                sp[i] = new Thread(new ParameterizedThreadStart(ps.scanport));
                //sp[i].IsBackground = true;
                sp[i].Start(i);
            }
            //Console.WriteLine("扫描结束!");
            //Console.ReadKey();
        }
    }
}

 

三、超时处理

// 对于C# Socket没有超时设置的选项,默认情况下进行Socket连接,返回连接失败信息需要20-30s时间,严重影响用户体验

using System;
using System.Net;
using System.Net.Sockets;

namespace TimeoutPortScan
{
    class TimeoutPortScan
    {
        private IPAddress ip;

        // FTP, SSH, Telnet, SMTP, DNS, HTTP, POP3, SQL, RPC, IMAP4, SQL, SNMP, HTTP over TLS/SSL or QQ, SMB, SMTP over SSL, SMTP, Games, FTP Protocol (control)over TLS / SSL, NAS(Netnews Admin System), IMAP, POP3, Microsoft SQL 服务器, Microsoft SQL 监视器, network monitoring tool, NFS Server, Oracle database listening port for unsecure client connections to the listener, Oracle database listening port for SSL client connections to the listener, mysql, 遠端桌面協定(RDP), eMule, eMule, XMPP / Jabber - client connection, XMPP / Jabber - default port for SSL Client Connection, XMPP / Jabber - server connection, PostgreSQL, VNC remote desktop protocol - for incoming listening viewer, VNC remote desktop protocol - for use over HTTP, VNC remote desktop protocol, QQ, HTTP, HTTP
        private readonly int[] ports = new int[] { 21, 22, 23, 25, 53, 80, 110, 118, 135, 143, 156, 161, 443, 445, 465, 587, 666, 990, 991, 993, 995, 1080, 1433, 1434, 1984, 2049, 2483, 2484, 3128, 3306, 3389, 4662, 4672, 5222, 5223, 5269, 5432, 5500, 5800, 5900, 8000, 8008, 8080 };
        private string[] explain = new string[] {"FTP", "SSH", "Telnet", "SMTP", "DNS", "HTTP", "POP3", "SQL 服务", "RPC(远程过程调用)", "IMAP4",
            "SQL", "SNMP", "HTTPS or QQ", "SMB", "SMTP over SSL", "SMTP", "Games", "FTP Protocol (control)over TLS / SSL", "NAS(Netnews Admin System)", "IMAP",
            "POP3", "SOCKS proxy", "Microsoft SQL 服务器", "Microsoft SQL 监视器", "network monitoring tool", "NFS Server", "Oracle database listening port for unsecure client connections to the listener", "Oracle database listening port for SSL client connections to the listener",  "HTTP", "mysql",
            "远程桌面协议(RDP)", "eMule", "eMule", "XMPP / Jabber - client connection", "XMPP / Jabber - default port for SSL Client Connection", "XMPP / Jabber - server connection", "PostgreSQL", "VNC remote desktop protocol - for incoming listening viewer", "VNC remote desktop protocol - for use over HTTP", "VNC remote desktop protocol",
            "QQ", "HTTP", "HTTP" };

        public bool Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
        {
            Socket scanSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            try
            {
                IAsyncResult result = scanSocket.BeginConnect(remoteEndPoint, null, null);
                //bool success = result.AsyncWaitHandle.WaitOne();
                bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(timeoutMSec), false);

                if (result.IsCompleted && scanSocket.Connected)
                {
                    scanSocket.EndConnect(result);
                    return true;
                    //throw new SocketException();
                }
                else
                    return false;
            }
            finally
            {
                scanSocket.Close();
            }
        }

        static void Main(string[] args)
        {
            TimeoutPortScan ps = new TimeoutPortScan();

            IPAddress.TryParse(args[0], out ps.ip);
            Console.WriteLine("开始扫描 . . . ");

            for (int num = 0; num < ps.ports.Length; num++)
            {
                if (ps.Connect(new IPEndPoint(ps.ip, ps.ports[num]), 200))
                    Console.WriteLine("端口 {0,5} 打开 . . . \t {1}", ps.ports[num], ps.explain[num]);
                //Console.WriteLine("{0}:{1} <-> {2}:{3} \t端口 {4,5} 打开. \t.", ((IPEndPoint)scanSocket.LocalEndPoint).Address, ((IPEndPoint)scanSocket.LocalEndPoint).Port, ((IPEndPoint)scanSocket.RemoteEndPoint).Address, ((IPEndPoint)scanSocket.RemoteEndPoint).Port, ((IPEndPoint)scanSocket.RemoteEndPoint).Port);
                //else
                //    Console.WriteLine("端口 {0,5} 关闭.", ps.ports[num]);
            }
        }
    }
}

 

四、异步扫描

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections;

namespace AsyncPortScan
{
    class AsyncPortScan
    {
        static void Main(string[] args)
        {
            IPAddress ip;
            int startPort, endPort;
            if (GetPortRange(args, out ip, out startPort, out endPort) == true)  // 提取命令行参数
                Scan(ip, startPort, endPort);   // 端口扫描
                // Console.ReadKey();
        }

        /// <summary>
        /// 从命令行参数中提取端口
        /// </summary>
        /// <param name="args">命令行参数</param>
        /// <param name="ip">输出 IP地址</param>
        /// <param name="startPort">输出 起始端口号</param>
        /// <param name="endPort">输出 终止端口号</param>
        /// <returns>提取成功返回true,否则返回false</returns>
        private static bool GetPortRange(string[] args, out IPAddress ip, out int startPort, out int endPort)
        {
            ip = null;
            startPort = endPort = 0;
            // 帮助命令
            if (args.Length != 0 && (args[0] == "/?" || args[0] == "/h" || args[0] == "/help"))
            {
                Console.WriteLine("扫面指定 ip 的主机的从 开始端口 到 结束端口 之间的端口.");
                Console.WriteLine("命令格式: PortScanCmd IPAddress startPort endPort");
                Console.WriteLine("例如: PortScanCmd 127.0.0.1 1 1280");
                return false;
            }

            if (args.Length == 3)
            {
                // 解析端口号成功
                if (IPAddress.TryParse(args[0], out ip) && int.TryParse(args[1], out startPort) && int.TryParse(args[2], out endPort))
                {
                    return true;
                }
                else
                {
                    Console.WriteLine("参数格式不正确!");
                    return false;
                }
            }
            else
            {
                Console.WriteLine("参数数目不正确!");
                return false;
            }
        }

        /// <summary>
        /// 端口 扫描
        /// </summary>
        /// <param name="ip">扫描的 IP地址</param>
        /// <param name="startPort">起始端口号</param>
        /// <param name="endPort">终止端口号</param>
        static void Scan(IPAddress ip, int startPort, int endPort)
        {
            Random rand = new Random((int)DateTime.Now.Ticks);
            Console.WriteLine("开始扫描 . . . ");
            for (int port = startPort; port < endPort; port++)
            {
                Socket scanSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                //寻找一个未使用的端口进行绑定
                do
                {
                    try
                    {
                        scanSocket.Bind(new IPEndPoint(IPAddress.Any, rand.Next(65535)));
                        break;
                    }
                    catch
                    {
                        //绑定失败
                    }
                } while (true);

                try
                {
                    scanSocket.BeginConnect(new IPEndPoint(ip, port), ScanCallBack, new ArrayList() { scanSocket, port });
                }
                catch
                {
                    // Console.WriteLine("端口 {0,5}\t关闭.\n{1}", port, ex.Message);
                    continue;
                }

            }

            Console.WriteLine("扫描结束!");
        }

        /// <summary>
        /// BeginConnect的回调函数
        /// </summary>
        /// <param name="result">异步Connect的结果</param>
        static void ScanCallBack(IAsyncResult result)
        {
            // 解析 回调函数输入 参数
            ArrayList arrList = (ArrayList)result.AsyncState;
            Socket scanSocket = (Socket)arrList[0];
            int port = (int)arrList[1];
            // 判断端口是否开放
            if (result.IsCompleted && scanSocket.Connected)
            {
                Console.WriteLine("端口 {0,5}\t打开.", port);
            }
            else
            {
                //Console.WriteLine("端口 {0,5}\t关闭.", port); 
            }
            // 关闭套接字
            scanSocket.Close();
        }
    }
}

源程序下载

执行程序下载

posted on 2015-12-10 22:02  新思想  阅读(2863)  评论(2)    收藏  举报

导航