GO語言編寫的TCP端口掃描器,本人的第一個GO程序。
Git@OSC:http://git.oschina.net/youshusoft/GoScanner
使用命令:
Scanner startIp [endIp] port thread
參數說明:
startIp 開始IP
endIp 結束IP,可選,不輸入表示只掃描startIp
port 掃描端口,單個端口:3389;多個端口:1433,3389;連續端口:135-3389
thread 最大并發線程數,最高2048
掃描結果保存在同目錄下的 result.txt 中,每次啟動都會清掉之前的內容。
例子一:
Scanner 58.96.172.22 58.96.172.220 80 512
掃描58.96.172.22到58.96.172.220中的80端口,最大并發線程512。
例子二:
Scanner 58.96.172.22 58.96.172.220 21,5631 512
掃描58.96.172.22到58.96.172.220中的21和5631端口,最大并發線程512。
例子三:
Scanner 58.96.172.22 58.96.172.220 1-520 512
掃描58.96.172.22到58.96.172.220中的1到520端口,最大并發線程512。
例子四:
Scanner 58.96.172.22 1-520 512
掃描58.96.172.22中的1到520端口,最大并發線程512。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
package main import ( "fmt" "strconv" "flag" "strings" "net" "os" ) /** 掃描地址 */ var ipAddrs chan string = make(chan string) //掃描結果 var result chan string = make(chan string) //線程數 var thread chan int = make(chan int ) var nowThread int ; //關閉程序 var clo chan bool = make(chan bool) //保存結果 func writeResult(){ fileName := "result.txt" fout,err := os.Create(fileName) if err != nil{ //文件創建失敗 fmt.Println(fileName + " create error" ) } defer fout.Close() s,ok := <- result for ;ok;{ fout.WriteString(s + "\r\n" ) s,ok = <- result } //通知進程退出 clo <- true ; } //根據線程參數啟動掃描線程 func runScan(){ t,ok := <- thread nowThread = t; if ok{ for i := 0 ;i < nowThread;i++{ go scan(strconv.Itoa(i)) } } //等待線程終止 for ;<-thread == 0 ;{ nowThread-- if nowThread == 0 { //全部線程已終止,關閉結果寫入,退出程序 close(result) break } } } /** 掃描線程 */ func scan(threadId string){ s,ok := <-ipAddrs for ;ok;{ fmt.Println( "[thread-" + threadId + "] scan:" + s) _,err := net.Dial( "tcp" ,s) if err == nil{ //端口開放 result <- s } s,ok = <-ipAddrs } fmt.Println( "[thread-" + threadId + "] end" ) thread <- 0 ; } //獲取下一個IP func nextIp(ip string) string{ ips := strings.Split(ip, "." ) var i int ; for i = len(ips) - 1 ;i >= 0 ;i--{ n,_ := strconv.Atoi(ips[i]) if n >= 255 { //進位 ips[i] = "1" } else { //+1 n++ ips[i] = strconv.Itoa(n) break } } if i == - 1 { //全部IP段都進行了進位,說明此IP本身已超出范圍 return "" ; } ip = "" leng := len(ips) for i := 0 ;i < leng;i++{ if i == leng - 1 { ip += ips[i] } else { ip += ips[i] + "." } } return ip } //生成IP地址列表 func processIp(startIp,endIp string) []string{ var ips = make([]string, 0 ) for ;startIp != endIp;startIp = nextIp(startIp){ if startIp != "" { ips = append(ips,startIp) } } ips = append(ips,startIp) return ips } //處理參數 func processFlag(arg []string){ //開始IP,結束IP var startIp,endIp string //端口 var ports [] int = make([] int , 0 ) index := 0 startIp = arg[index] si := net.ParseIP(startIp) if si == nil{ //開始IP不合法 fmt.Println( "'startIp' Setting error" ) return } index++ endIp = arg[index] ei := net.ParseIP(endIp) if (ei == nil){ //未指定結束IP,即只掃描一個IP endIp = startIp } else { index++ } tmpPort := arg[index] if strings.Index(tmpPort, "-" ) != - 1 { //連續端口 tmpPorts := strings.Split(tmpPort, "-" ) var startPort,endPort int var err error startPort,err = strconv.Atoi(tmpPorts[ 0 ]) if err != nil || startPort < 1 || startPort > 65535 { //開始端口不合法 return } if len(tmpPorts) >= 2 { //指定結束端口 endPort,err = strconv.Atoi(tmpPorts[ 1 ]) if err != nil || endPort < 1 || endPort > 65535 || endPort < startPort{ //結束端口不合法 fmt.Println( "'endPort' Setting error" ) return } } else { //未指定結束端口 endPort = 65535 } for i := 0 ;startPort + i <= endPort;i++{ ports = append(ports,startPort + i) } } else { //一個或多個端口 ps := strings.Split(tmpPort, "," ) for i := 0 ;i < len(ps);i++{ p,err := strconv.Atoi(ps[i]) if err != nil{ //端口不合法 fmt.Println( "'port' Setting error" ) return } ports = append(ports,p) } } index++ t,err := strconv.Atoi(arg[index]) if (err != nil){ //線程不合法 fmt.Println( "'thread' Setting error" ) return } //最大線程2048 if t < 1 { t = 1 ; } else if t > 2048 { t = 2048 ; } //傳送啟動線程數 thread <- t //生成掃描地址列表 ips := processIp(startIp,endIp) il := len(ips) for i := 0 ; i < il;i++{ pl := len(ports) for j := 0 ;j < pl;j++{ ipAddrs <- ips[i] + ":" + strconv.Itoa(ports[j]) } } close(ipAddrs) } func main(){ flag.Parse() if flag.NArg() != 3 && flag.NArg() != 4 { //參數不合法 fmt.Println( "Parameter error" ) return } //獲取參數 args := make([]string, 0 , 4 ) for i := 0 ;i < flag.NArg();i++{ args = append(args,flag.Arg(i)) } //啟動掃描線程 go runScan() //啟動結果寫入線程 go writeResult() //參數處理 processFlag(args) //等待退出指令 <- clo; fmt.Println( "Exit" ) } |
以上所述就是本文的全部內容了,希望大家能夠喜歡。