golang高性能端口扫描

Posted qiyeboy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang高性能端口扫描相关的知识,希望对你有一定的参考价值。

前言

最近有个小项目的需要,使用golang写了个端口扫描工具,不得不说golang的效率确实比python快的太多了。在使用一段时间golang之后,感觉有三个方面是优于python的:

  1. 一个方面是性能优越

  2. 第二方面是兼容性好

  3. 第三方面是可以跨平台编译成本地二进制文件,发布项目很方便。

接下来我把这个工具的源代码,以及使用方式给大家给大家分享一下。

PortScan

工具名称:PortScan

  1. 采用Go语言开发,支持从config.txt文件中读取目的ip和端口,对指定的目的服务器进行端口扫描

  2. config.txt支持配置端口列表,默认为22、36000、56000、3306

  3. 在服务器上连接目的服务器端口,仅做一次TCP三次握手

PortScan参数如下

技术分享图片

 

参数说明:

  •  -c:用来指定config文件路径

  •  -limit:用来指定扫描端口的并发数,默认为1000

 

首先生成一个config.txt文件,内容如下:

 技术分享图片

ip共有255个,端口有10个,也就是说总共要进行2550次TCP连接。

 

接着使用go build PortScan.go命令,生成一个本地二进制文件PortScan.exe,然后执行命令:

PortScan.exe -c config.txt

技术分享图片

最后的结果存储到result.txt文件中,大致用时是30s。

关键源代码

//首先从命令行中读取线程数和配置文件路径
//从配置文件中解析出ip和port
//配置文件格式为
// [ip]
// 127.0.0.1
// [port]
// 22
// 36000
// 56000
// 3306
//根据开启的线程数对指定ip和端口进行tcp连接
//如果端口开启,把ip:port按照格式返回

func Scanner(configFile string, functionid string, sendInfoFile string,limit int){

	runtime.GOMAXPROCS(runtime.NumCPU())
	data, err := ioutil.ReadFile(configFile)
	portlist := make([]string,0,10)

	if err != nil{
		log.Fatal(err)
		panic(err)
	}
	
	ip_index := bytes.Index(data,[]byte("[ip]"))

	port_index := bytes.Index(data,[]byte("[port]"))

	if ip_index < 0{

		Info.Println("文件格式有误: missing [ip]")
		return
	}

	if port_index <0{

		portlist = append(portlist,"22")
		portlist = append(portlist,"36000")
		portlist = append(portlist,"56000")
		portlist = append(portlist,"3306")

	}else{
		reg_port := regexp.MustCompile(`d+`)
		var ports [][]byte

		if ip_index>port_index{
			ports = reg_port.FindAll(data[:ip_index],-1)

		}else{

			ports = reg_port.FindAll(data[port_index:],-1)
		}
		

		for _,v := range(ports){
			
			portlist = append(portlist,string(v))

		} 
	
	}
	

	
	reg_ip := regexp.MustCompile(`((25[0-5]|2[0-4]d|((1d{2})|([1-9]?d))).){3}(25[0-5]|2[0-4]d|((1d{2})|([1-9]?d)))`)

	ips := reg_ip.FindAll(data,-1)

	input := make(chan []byte, len(ips))

	result := make(chan string, len(ips))

	defer close(input)
	defer close(result)
	
	for _, v := range(ips){
		input <- v
	}
	//控制多少并发
	for i:=0; i<limit;i++{
		//这个时候可以启动扫描函数
		go ScanPort(portlist,input,result)
	}
   
   
	for i :=0; i< len(ips);i++{

		//将扫描的结果输出
		ip_result,ok:= <-result

		if !ok {
			break;
		}

	}
	
}

func ScanPort(portlist []string,intput chan []byte,result chan string ) {

	for{
		task,ok := <-intput

		if !ok{

			return
		}
		ip := string(task)
		Info.Println("scaning ",ip,"port",portlist)
		port_str :=""
		for i:=0; i<len(portlist); i++{
			_, err  := net.DialTimeout("tcp", ip+":"+portlist[i], time.Second*3)

			if err != nil{
				continue
			}
			port_str+=portlist[i]+" "

		}

		if len(port_str) >0{
			//说明有打开的端口
			// Info.Println(ip+":"+port_str+"open")
			result <- ip+"----"+"1"+"----"+"open port:"+port_str

		}else{

			result <- ip+"----"+"0"+"----"+"ok"
		}

	}

}

 

最后

关注公众号:七夜安全博客

技术分享图片

  • 回复【1】:领取 Python数据分析 教程大礼包
  • 回复【2】:领取 Python Flask 全套教程
  • 回复【3】:领取 某学院 机器学习 教程
  • 回复【4】:领取 爬虫 教程
  • 回复【5】:领取 编译原理 教程 
  • 回复【6】:领取 渗透测试 教程 
  • 回复【7】:领取 人工智能数学基础 教程

以上是关于golang高性能端口扫描的主要内容,如果未能解决你的问题,请参考以下文章

端口扫描(go)

Go语言(Golang)编写 TCP 端口扫描器

golang goroutine例子[golang并发代码片段]

golang代码片段(摘抄)

python高性能代码之多线程优化

代码片段 - Golang 实现简单的 Web 服务器