本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。
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。
- 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")
- }
以上所述就是本文的全部內容了,希望大家能夠喜歡。
新聞熱點
疑難解答