C# 端口扫描


Jan 12 2015

C# 端口扫描

首页 » 渗透编程 » C# 端口扫描   

1.端口扫描原理

主要是利用套接字,来和远程主机的逐个端口进行连接,如果连接上说明该端口是开放的,否则是关闭的。当然现在各种安全技术发展迅速,使得这种方法扫描的端口可能不太准确,但是总得从最基本的学起吧~~

实现起来也不难,关键是看执行效率如何,如果使用传统的逐个端口扫描,效率很低,即使是扫描本机,平均每个端口也需要1秒左右。提高效率的方法有很多如多线程、异步扫描。我采用的是异步扫描方式,其实这种方式也是一种多线程的方式,只是线程是交由系统创建的。

 

2.程序效果截图

 1335431704_5043.jpg

3.源代码

说明:下面代码使用的是原始的Socket,也可以使用C#提供的高级类TcpClient,这样可能做起来会方便点。

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

namespace PortScan
{
    class Program
    {
        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();
            }
        }

        #region 从命令行参数 中提取端口 + static bool GetPortRange(string[] args, out int startPort, out int endPort)
       
        /// <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] == "/help"))
            {
                Console.WriteLine("Scan port from startPort to endPort of the host specified by the IPAddress.");
                Console.WriteLine("Command Format:");
                Console.WriteLine("PortScan IPAddress startPort endPort");
                Console.WriteLine("For example:");
                Console.WriteLine("PortScan 127.0.0.1 1 1024");
                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;
            }
        }
        #endregion

        /// <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("Begin Scan...");
            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("port {0,5}\tClosed.\n{1}", port, ex.Message);
                    continue;
                }
              
            }

            Console.WriteLine("Port Scan Completed!");
        }

        /// <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("port {0,5}\tOpen.", port);
            }
            else
            {
                //Console.WriteLine("port {0,5}\tClosed.", port); 
            }
            //关闭套接字
            scanSocket.Close();
        }
    }
}

4.进化成WinForm

本来是打算直接拿WinForm来说的,但是WinForm里面有许多无关代码,所以又写了个Console的示例(也就是上面的程序),下面是用WinForm写的,原理与上面一样,只是界面友好一点而已。

1335432192_9880.jpg

http://blog.csdn.net/xiaohui_hubei/article/details/7515103


如果您喜欢本博客,欢迎点击图片定订阅到邮箱填写您的邮件地址,订阅我们的精彩内容:

正文部分到此结束

文章标签: 渗透编程 端口扫描器

版权声明:若无特殊注明,本文皆为( mOon )原创,转载请保留文章出处。

也许喜欢: «K8_Struts2_0day远程代码漏洞利用工具+JspShell_0524[K8] | 狗新功能禁止iis运行程序绕过»

你肿么看?

你还可以输入 250/250 个字

 微笑 大笑 拽 大哭 亲亲 流汗 喷血 奸笑 囧 不爽 晕 示爱 害羞 吃惊 惊叹 爱你 吓死了 呵呵

评论信息框

这篇文章还没有收到评论,赶紧来抢沙发吧~