What!!! so fast

高性能端口扫描

前言

不要以为我是标题党,真的是so fast。。。最近有个小项目的需要,使用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]
10.27.3.1
10.27.3.2
10.27.3.3
10.27.3.4
10.27.3.5
10.27.3.6
......
10.27.3.254
127.0.0.1
[port]
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309

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

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

PortScan.exe -c config.txt

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

第三节

源代码

端口扫描核心函数

package main
import (

    "fmt"
    "io/ioutil"
    "bufio"
    "log"
    "regexp"
    "net"
    "runtime"
    "time"
    "bytes"
    "flag"
    "os"
    "strings"

)

var(


    P = fmt.Println

)

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

func Scanner(configFile 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{

        P("文件格式有误: 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)

    }

    result_str := ""

    for i :=0; i< len(ips);i++{

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

        if !strings.Contains(ip_result,"ok"){
            P(ip_result)
            result_str += ip_result+"\n"


        }

        if !ok {


            break;
        }

    }

    f,err := os.Create("result.txt")
    if err !=nil{

        P(err)
        return
    }
    defer f.Close()
    w := bufio.NewWriter(f)

    fmt.Fprintln(w, result_str)

    w.Flush()

}

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

    for{

        task,ok := <-intput

        if !ok{

            return
        }
        ip := string(task)
        P("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{
            //说明有打开的端口
            // P(ip+":"+port_str+"open")
            result <- ip+"----"+"1"+"----"+"open port:"+port_str

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

    }

}

完整源代码和生成的二进制文件会在知识星球中分享。

原文发布于微信公众号 - 七夜安全博客(qiye_safe)

原文发表时间:2018-08-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native发布APP之签名打包APK

React Native发布APP之签名打包APK ---- 用React Native开发好APP之后,如何将APP发布以供用户使用呢?一款APP的发布流程...

30150
来自专栏Java后端技术栈

QQ登录网站接入功能实现--非官方文档搬运

最近第一次使用QQ登录功能,期间遇到这种问题,在网上找了很多资料,大多都是官方的搬运,并没有真正的干料,可能是个人能力问题,遇到了各种麻烦,折腾了几天,最终弄好...

17340
来自专栏IT笔记

MVC与三层架构有什么区别

首先,声明一下,三层是三层,MVC是MVC,这俩是毫无关系的。 三层是从整个应用程序架构的角度来分的三层(如果程序需要,还可以分多层)。 三层架构通常包括表示层...

37780
来自专栏张高兴的博客

张高兴的 UWP 开发笔记:应用内启动应用 (UWP Launch UWP)

37090
来自专栏月色的自留地

新麦装机问题汇

14730
来自专栏Android干货

Android项目实战(三十八):2017最新 将AndroidLibrary提交到JCenter仓库(图文教程)

29170
来自专栏张戈的专栏

WordPress启用memcached动态缓存以及报错解决

张戈博客目前用的是Nginx 的 fastcgi 缓存方案,属于纯净态缓存模式,所以前台登录态什么的基本都没了。如果要兼顾前台登录态,又想速度快,有没有解决方案...

61090
来自专栏菩提树下的杨过

MRTG FOR WINDOWS 安装指南

MRTG(Multi Router Traffic Grapher),通常讲是一个监控网络链路流量负载的开源软件,它可以从所有运行SNMP协议的设备上(包括服务...

352100
来自专栏恰童鞋骚年

.NET Core微服务之基于Consul实现服务治理(续)

上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧。

18350
来自专栏黑泽君的专栏

day07_Tomcat服务器与http学习笔记

    WEB,在英语中web即表示网页的意思,它用于表示Internet主机上(服务器)供外界访问的资源。

13210

扫码关注云+社区

领取腾讯云代金券