掃描主要分s掃描,和tcp掃描,S掃描需要分析數據包,需要winpacp(c#爲SharpPcap),由於這種掃描雖然快但麻煩,本人也只抓到過arp與pppoe撥號的數據包,所以沒對此深入。
以下介紹的也只是tcp多線程,單網段掃描了(由於時間久了也懶得改了)
程序界面如下:
程序通過啓動另外一個線程來掃描,其中判斷ip另端主機是否存在,是通過ping(20ms超時)判斷,端口TCP連接(200ms超時)
每次只掃描一個IP,開多線程掃N個端口,由於開100個線程以上系統會很卡(公司垃圾電腦。。),自己也懶得控制每次線程數量了。
代碼如下
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using System.Net.NetworkInformation; namespace WindowsFormsApplication1 { public partial class ip端口掃描 : Form { public ip端口掃描() { System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; InitializeComponent(); textBox3.Text = "10.3.1.46"; textBox4.Text = "10.3.1.53"; } List<string> str;//結果字串 int start; int end; bool tag = true;//是否終止當前掃描的變量 private void button1_Click(object sender, EventArgs e) { this.richTextBox1.Text = "開始\n"; Regex rgx = new Regex(@"^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"); if (rgx.IsMatch(textBox3.Text) && rgx.IsMatch(textBox4.Text))//匹配正確IP { start = Int32.Parse(textBox1.Text); end = Int32.Parse(textBox2.Text); } else { MessageBox.Show("Jerry,填寫正確IP"); return; } if (end - start > 100) { MessageBox.Show("暫不接受搜索範圍超過100的端口"); return; } if (end < start) { MessageBox.Show("Jerry,別開玩笑啊!"); return; } tag = true; Thread waitT = new Thread(new ThreadStart(wait)); waitT.Start();//等待所有線程執行完畢在寫入textbox中 } public void wait() { int startIp = Int32.Parse(textBox3.Text.Split('.')[3]); int endIp = Int32.Parse(textBox4.Text.Split('.')[3]); string ip = textBox3.Text.Split('.')[0] + "." + textBox3.Text.Split('.')[1] + "." + textBox3.Text.Split('.')[2] + "."; for (int q = startIp; q <= endIp && tag == true; q++) { //---------------------ping Ping ping = new Ping(); PingReply reply = ping.Send(IPAddress.Parse(ip + q), 20); if (reply.Status == IPStatus.Success) { richTextBox1.Text += ip + q + "Ping時間" + reply.RoundtripTime + "毫秒\n"; IPHostEntry host = Dns.GetHostEntry(ip + q); richTextBox1.Text += "主機名爲" + host.HostName + "\n"; } else { richTextBox1.Text += ip + q + "不可達\n"; continue; } //---------------------end Thread[] tharr = new Thread[end - start + 1]; str = new List<string>(); for (int i = start; i <= end; i++) { Thread thread = new Thread(new ParameterizedThreadStart(Scan)); thread.Start(new IPEndPoint(IPAddress.Parse(ip + q), i));//每掃描一個端口創建一個線程 tharr[i - start] = thread; } bool iscon = true;//第一個線程等待時間 for (int i = 0; i < tharr.Length; i++) { if (tharr[i] == null) continue; while (tharr[i].IsAlive && iscon)//端口超時設置時間(目前200毫秒),一直等待此ip所有線程執行完畢才掃描下個ip { Thread.Sleep(200); iscon = false;//第一個線程給200ms等待時間,其他線程由於同步執行的,所以沒等待時間了,如果線程還沒執行完,說明此端口不可達。 } } str.Sort(); richTextBox1.Text += "開放端口: "; for (int k = 0; k < str.Count; k++) richTextBox1.Text += str[k]; richTextBox1.Text += "\n"; } if (tag == true) MessageBox.Show("掃描完成"); else { MessageBox.Show("掃描終止"); } } public void Scan(object Point) { IPEndPoint IPPoint = (IPEndPoint)Point; try { TcpClient tcp = new TcpClient(); tcp.Connect(IPPoint); if (tcp.Connected) str.Add(IPPoint.Port + ","); } catch { ; } } private void button2_Click(object sender, EventArgs e) { MessageBox.Show("目前只支持C類網段的TCP掃描\n作者Jerry", "事項"); } private void button3_Click(object sender, EventArgs e)//終止 { tag = false; } } }
運行的結果圖如下:
由於這個project還有其他功能代碼,程序也確實不咋滴,很多都可以做的更好,而且主體代碼全貼出來了,所以就不提供源代碼下載了。