qiyesafe.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。

关键源代码

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
//首先从命令行中读取线程数和配置文件路径
//从配置文件中解析出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|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{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】:领取 人工智能数学基础 教程
本文章属于原创作品,欢迎大家转载分享,禁止修改文章的内容。尊重原创,转载请注明来自:七夜的故事 http://www.cnblogs.com/qiyeboy/
posted @   七夜的故事  阅读(8172)  评论(4编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
qiyesafe.com
点击右上角即可分享
微信分享提示