The go language makes port scanners
- 2020-05-27 05:54:38
- OfStack
GO language prepared by TCP port scanner, my first GO program.
Git @ OSC: http: / / git oschina. net/youshusoft/GoScanner
Command to use:
Scanner startIp [endIp] port thread
Parameter description:
startIp began IP
endIp ends IP, optional, no input means only startIp is scanned
port scan port, single port: 3389; Multiple ports: 1433,3389; Continuous port: 135-3389
thread maximum number of concurrent threads, maximum 2048
The scan results are saved in result.txt in the same directory, and the previous contents are cleared every time you launch.
Example 1:
Scanner 58.96.172.22 58.96.172.220 80 512
Scan port 80 from 58.96.172.22 to 58.96.172.220 for maximum concurrent thread 512.
Example 2:
Scanner 58.96.172.22 58.96.172.220 21,5631 512
Scan ports 21 and 5631 from 58.96.172.22 to 58.96.172.220 for maximum concurrent threads 512.
Example 3:
Scanner 58.96.172.22 58.96.172.220 1-520 512
Scan ports 1 to 520 from 58.96.172.22 to 58.96.172.220 for maximum concurrent threads 512.
Example 4:
Scanner 58.96.172.22 1-520 512
Scan port 1 through 520 in 58.96.172.22, Max concurrent thread 512.
package main
import (
"fmt"
"strconv"
"flag"
"strings"
"net"
"os"
)
/**
Scan the address
*/
var ipAddrs chan string = make(chan string)
// Scan results
var result chan string = make(chan string)
// The number of threads
var thread chan int = make(chan int)
var nowThread int;
// Close the program
var clo chan bool = make(chan bool)
// Save the result
func writeResult(){
fileName := "result.txt"
fout,err := os.Create(fileName)
if err != nil{
// File creation failed
fmt.Println(fileName + " create error")
}
defer fout.Close()
s,ok := <- result
for ;ok;{
fout.WriteString(s + "\r\n")
s,ok = <- result
}
// Notification process exit
clo <- true;
}
// Start the scan thread based on the thread parameter
func runScan(){
t,ok := <- thread
nowThread = t;
if ok{
for i := 0;i < nowThread;i++{
go scan(strconv.Itoa(i))
}
}
// Waiting for thread termination
for;<-thread == 0;{
nowThread--
if nowThread == 0{
// All threads have terminated , Close result write , Exit the program
close(result)
break
}
}
}
/**
Scan the thread
*/
func scan(threadId string){
s,ok := <-ipAddrs
for;ok;{
fmt.Println("[thread-" + threadId + "] scan:" + s)
_,err := net.Dial("tcp",s)
if err == nil{
// The port is open
result <- s
}
s,ok = <-ipAddrs
}
fmt.Println("[thread-" + threadId + "] end")
thread <- 0;
}
// To obtain the 1 a 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{
// carry
ips[i] = "1"
}else{
//+1
n++
ips[i] = strconv.Itoa(n)
break
}
}
if i == -1{
// all IP The segments are carried , Illustrate this IP It is out of scope
return "";
}
ip = ""
leng := len(ips)
for i := 0;i < leng;i++{
if i == leng -1{
ip += ips[i]
}else{
ip += ips[i] + "."
}
}
return ip
}
// generate IP Address list
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
}
// Processing parameters
func processFlag(arg []string){
// start IP, The end of the IP
var startIp,endIp string
// port
var ports []int = make([]int,0)
index := 0
startIp = arg[index]
si := net.ParseIP(startIp)
if si == nil{
// start IP illegal
fmt.Println("'startIp' Setting error")
return
}
index++
endIp = arg[index]
ei := net.ParseIP(endIp)
if(ei == nil){
// End not specified IP, The only scan 1 a IP
endIp = startIp
}else{
index++
}
tmpPort := arg[index]
if strings.Index(tmpPort,"-") != -1{
// Serial port
tmpPorts := strings.Split(tmpPort,"-")
var startPort,endPort int
var err error
startPort,err = strconv.Atoi(tmpPorts[0])
if err != nil || startPort < 1 || startPort > 65535{
// The start port is not valid
return
}
if len(tmpPorts) >= 2{
// Specify end port
endPort,err = strconv.Atoi(tmpPorts[1])
if err != nil || endPort < 1 || endPort > 65535 || endPort < startPort{
// The end port is not valid
fmt.Println("'endPort' Setting error")
return
}
}else{
// An end port was not specified
endPort = 65535
}
for i := 0;startPort + i <= endPort;i++{
ports = append(ports,startPort + i)
}
}else{
//1 Two or more ports
ps := strings.Split(tmpPort,",")
for i := 0;i < len(ps);i++{
p,err := strconv.Atoi(ps[i])
if err != nil{
// Port illegal
fmt.Println("'port' Setting error")
return
}
ports = append(ports,p)
}
}
index++
t,err := strconv.Atoi(arg[index])
if(err != nil){
// Thread illegal
fmt.Println("'thread' Setting error")
return
}
// The biggest thread 2048
if t < 1{
t = 1;
}else if t > 2048{
t = 2048;
}
// Sends the number of startup threads
thread <- t
// Generate the scan address list
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{
// Parameter invalid
fmt.Println("Parameter error")
return
}
// To obtain parameters
args := make([]string,0,4)
for i := 0;i < flag.NArg();i++{
args = append(args,flag.Arg(i))
}
// Start the scan thread
go runScan()
// Start the result writing thread
go writeResult()
// Processing parameters
processFlag(args)
// Waiting for exit instruction
<- clo;
fmt.Println("Exit")
}
That's all for this article, I hope you enjoy it.