From 1a8964cc6edcbab0b16f005f530c439b10f98a7e Mon Sep 17 00:00:00 2001 From: shadow1ng Date: Fri, 5 Feb 2021 14:43:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9icmp=E5=8F=91=E5=8C=85?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F,=E6=9B=B4=E9=80=82=E5=90=88=E5=A4=A7?= =?UTF-8?q?=E8=A7=84=E6=A8=A1=E6=8E=A2=E6=B5=8B=E3=80=82=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8A=A5=E9=94=99=E6=8F=90=E7=A4=BA,--debug=E6=97=B6,?= =?UTF-8?q?=E5=A6=82=E6=9E=9C10=E7=A7=92=E5=86=85=E6=B2=A1=E6=9C=89LogSucc?= =?UTF-8?q?ess=E7=9A=84=E6=B6=88=E6=81=AF,=E6=AF=8F=E9=9A=9410=E7=A7=92?= =?UTF-8?q?=E5=B0=B1=E4=BC=9A=E6=89=93=E5=8D=B0=E4=B8=80=E4=B8=8B=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugins/ftp.go | 2 + Plugins/icmp.go | 95 +++++++++++++++++++++------------------------ Plugins/mssql.go | 2 + Plugins/mysql.go | 2 + Plugins/postgres.go | 2 + Plugins/redis.go | 16 ++++---- Plugins/scanner.go | 12 +++--- Plugins/smb.go | 2 + Plugins/ssh.go | 2 + Plugins/webtitle.go | 10 ++++- WebScan/WebScan.go | 7 ++-- common/Parse.go | 19 ++++----- common/config.go | 52 ++++++++++++------------- common/flag.go | 33 ++++++++-------- common/log.go | 14 +++++++ 15 files changed, 149 insertions(+), 121 deletions(-) diff --git a/Plugins/ftp.go b/Plugins/ftp.go index 245df58..eeb8dd4 100644 --- a/Plugins/ftp.go +++ b/Plugins/ftp.go @@ -16,6 +16,8 @@ func FtpScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { return err } else { + errlog := fmt.Sprintf("[-] ftp %v %v %v %v %v", info.Host, common.PORTList["ftp"], user, pass, err) + common.LogError(errlog) tmperr = err } } diff --git a/Plugins/icmp.go b/Plugins/icmp.go index fe428e2..a009b10 100644 --- a/Plugins/icmp.go +++ b/Plugins/icmp.go @@ -3,6 +3,8 @@ package Plugins import ( "bytes" "fmt" + "golang.org/x/net/icmp" + "log" "net" "os" "os/exec" @@ -50,58 +52,52 @@ func GetSys() SystemInfo { return sysinfo } -func isping(ip string) bool { - IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0} - Time, _ := time.ParseDuration("3s") - conn, err := net.DialTimeout("ip4:icmp", ip, Time) +func IcmpCheck(hostslist []string) { + conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0") + endflag := false if err != nil { - return false - } - defer conn.Close() - _, err = conn.Write(IcmpByte) - if err != nil { - return false + log.Fatal(err) } + var chanHosts = make(chan string) + go func() { + for { + if endflag == true { + return + } + msg := make([]byte, 100) + _, sourceIP, _ := conn.ReadFrom(msg) + if sourceIP != nil { + chanHosts <- sourceIP.String() + } + } + }() - if err := conn.SetReadDeadline(time.Now().Add(time.Second * 3)); err != nil { - return false - } + go func() { + for ip := range chanHosts { + if !IsContain(AliveHosts, ip) { + fmt.Printf("(icmp) Target '%s' is alive\n", ip) + AliveHosts = append(AliveHosts, ip) + } + } + }() - recvBuf := make([]byte, 40) - num, err := conn.Read(recvBuf[0:40]) - if err != nil { - return false + for _, host := range hostslist { + write(host, conn) } - if err := conn.SetReadDeadline(time.Now().Add(time.Second * 3)); err != nil { - return false + if len(hostslist) > 10 { + time.Sleep(6 * time.Second) + } else { + time.Sleep(3 * time.Second) } - if string(recvBuf[0:num]) != "" { - fmt.Printf("(ICMP) Target '%s' is alive\n", ip) - return true - } - return false - + endflag = true + close(chanHosts) + conn.Close() } -func IcmpCheck(hostslist []string, IcmpThreads int) { - var wg sync.WaitGroup - mutex := &sync.Mutex{} - limiter := make(chan struct{}, IcmpThreads) - for _, host := range hostslist { - wg.Add(1) - limiter <- struct{}{} - go func(host string) { - defer wg.Done() - if isping(host) { - mutex.Lock() - AliveHosts = append(AliveHosts, host) - mutex.Unlock() - } - <-limiter - }(host) - - } - wg.Wait() +func write(ip string, conn *icmp.PacketConn) { + dst, _ := net.ResolveIPAddr("ip", ip) + IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0} + conn.WriteTo(IcmpByte, dst) } func ExecCommandPing(ip string, bsenv string) bool { @@ -133,7 +129,7 @@ func ExecCommandPing(ip string, bsenv string) bool { func PingCMDcheck(hostslist []string, bsenv string) { var wg sync.WaitGroup mutex := &sync.Mutex{} - limiter := make(chan struct{}, 40) + limiter := make(chan struct{}, 50) for _, host := range hostslist { wg.Add(1) limiter <- struct{}{} @@ -150,18 +146,17 @@ func PingCMDcheck(hostslist []string, bsenv string) { } wg.Wait() } -func ICMPRun(hostslist []string, IcmpThreads int, Ping bool) []string { - +func ICMPRun(hostslist []string, Ping bool) []string { if SysInfo.OS == "windows" { if Ping == false { - IcmpCheck(hostslist, IcmpThreads) + IcmpCheck(hostslist) } else { PingCMDcheck(hostslist, "") } } else if SysInfo.OS == "linux" { if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" { if Ping == false { - IcmpCheck(hostslist, IcmpThreads) + IcmpCheck(hostslist) } else { PingCMDcheck(hostslist, "/bin/bash") } @@ -173,7 +168,7 @@ func ICMPRun(hostslist []string, IcmpThreads int, Ping bool) []string { } else if SysInfo.OS == "darwin" { if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" { if Ping == false { - IcmpCheck(hostslist, IcmpThreads) + IcmpCheck(hostslist) } else { PingCMDcheck(hostslist, "/bin/bash") } diff --git a/Plugins/mssql.go b/Plugins/mssql.go index 02a0da9..d549339 100644 --- a/Plugins/mssql.go +++ b/Plugins/mssql.go @@ -17,6 +17,8 @@ func MssqlScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { return err } else { + errlog := fmt.Sprintf("[-] mssql %v %v %v %v %v", info.Host, common.PORTList["mssql"], user, pass, err) + common.LogError(errlog) tmperr = err } } diff --git a/Plugins/mysql.go b/Plugins/mysql.go index 5eb6531..82e5575 100644 --- a/Plugins/mysql.go +++ b/Plugins/mysql.go @@ -17,6 +17,8 @@ func MysqlScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { return err } else { + errlog := fmt.Sprintf("[-] mysql %v %v %v %v %v", info.Host, common.PORTList["mysql"], user, pass, err) + common.LogError(errlog) tmperr = err } } diff --git a/Plugins/postgres.go b/Plugins/postgres.go index 7271b4f..6e1ab83 100644 --- a/Plugins/postgres.go +++ b/Plugins/postgres.go @@ -17,6 +17,8 @@ func PostgresScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { return err } else { + errlog := fmt.Sprintf("[-] psql %v %v %v %v %v", info.Host, common.PORTList["psql"], user, pass, err) + common.LogError(errlog) tmperr = err } } diff --git a/Plugins/redis.go b/Plugins/redis.go index 6ea5c29..766b6c0 100644 --- a/Plugins/redis.go +++ b/Plugins/redis.go @@ -21,6 +21,8 @@ func RedisScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { return err } else { + errlog := fmt.Sprintf("[-] redis %v %v %v %v %v", info.Host, common.PORTList["redis"], pass, err) + common.LogError(errlog) tmperr = err } } @@ -47,7 +49,7 @@ func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) { result := fmt.Sprintf("[+] Redis:%s %s", realhost, pass) common.LogSuccess(result) flag = true - Expoilt(info, realhost, conn) + Expoilt(realhost, conn) } return flag, err } @@ -72,12 +74,12 @@ func RedisUnauth(info *common.HostInfo) (flag bool, err error) { result := fmt.Sprintf("[+] Redis:%s unauthorized", realhost) common.LogSuccess(result) flag = true - Expoilt(info, realhost, conn) + Expoilt(realhost, conn) } return flag, err } -func Expoilt(info *common.HostInfo, realhost string, conn net.Conn) error { +func Expoilt(realhost string, conn net.Conn) error { flagSsh, flagCron, err := testwrite(conn) if err != nil { return err @@ -85,8 +87,8 @@ func Expoilt(info *common.HostInfo, realhost string, conn net.Conn) error { if flagSsh == true { result := fmt.Sprintf("Redis:%v like can write /root/.ssh/", realhost) common.LogSuccess(result) - if info.RedisFile != "" { - writeok, text, err := writekey(conn, info.RedisFile) + if common.RedisFile != "" { + writeok, text, err := writekey(conn, common.RedisFile) if err != nil { return err } @@ -102,8 +104,8 @@ func Expoilt(info *common.HostInfo, realhost string, conn net.Conn) error { if flagCron == true { result := fmt.Sprintf("Redis:%v like can write /var/spool/cron/", realhost) common.LogSuccess(result) - if info.RedisShell != "" { - writeok, text, err := writecron(conn, info.RedisShell) + if common.RedisShell != "" { + writeok, text, err := writecron(conn, common.RedisShell) if err != nil { return err } diff --git a/Plugins/scanner.go b/Plugins/scanner.go index 9c35250..0fef02c 100644 --- a/Plugins/scanner.go +++ b/Plugins/scanner.go @@ -12,9 +12,9 @@ import ( func Scan(info common.HostInfo) { fmt.Println("scan start") - Hosts, _ := common.ParseIP(info.Host, info.HostFile) - if info.Isping == false { - Hosts = ICMPRun(Hosts, info.IcmpThreads, info.Ping) + Hosts, _ := common.ParseIP(info.Host, common.HostFile) + if common.IsPing == false { + Hosts = ICMPRun(Hosts, common.Ping) fmt.Println("icmp alive hosts len is:", len(Hosts)) } if info.Scantype == "icmp" { @@ -28,7 +28,7 @@ func Scan(info common.HostInfo) { for _, port := range common.PORTList { severports = append(severports, strconv.Itoa(port)) } - var ch = make(chan struct{}, info.Threads) + var ch = make(chan struct{}, common.Threads) var wg = sync.WaitGroup{} for _, targetIP := range AlivePorts { info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1] @@ -55,12 +55,12 @@ func AddScan(scantype string, info common.HostInfo, ch chan struct{}, wg *sync.W wg.Add(1) go func() { err, _ := ScanFunc(PluginList, scantype, &info) - if info.Debug { + if common.LogErr { tmperr := err[0].Interface() if tmperr != nil { tmperr1 := err[0].Interface().(error) errtext := strings.Replace(tmperr1.Error(), "\n", "", -1) - fmt.Println(info.Host+":"+info.Ports, errtext) + fmt.Println("[-] ", info.Host+":"+info.Ports, errtext) } } wg.Done() diff --git a/Plugins/smb.go b/Plugins/smb.go index 6307b02..145cec8 100644 --- a/Plugins/smb.go +++ b/Plugins/smb.go @@ -23,6 +23,8 @@ func SmbScan(info *common.HostInfo) (tmperr error) { common.LogSuccess(result) return err } else { + errlog := fmt.Sprintf("[-] smb %v %v %v %v %v", info.Host, 445, user, pass, err) + common.LogError(errlog) tmperr = err } } diff --git a/Plugins/ssh.go b/Plugins/ssh.go index acb9a66..42b28cd 100644 --- a/Plugins/ssh.go +++ b/Plugins/ssh.go @@ -17,6 +17,8 @@ func SshScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { return err } else { + errlog := fmt.Sprintf("[-] ssh", info.Host, common.PORTList["ssh"], user, pass, err) + common.LogError(errlog) tmperr = err } } diff --git a/Plugins/webtitle.go b/Plugins/webtitle.go index 647747b..171100c 100644 --- a/Plugins/webtitle.go +++ b/Plugins/webtitle.go @@ -23,7 +23,7 @@ func WebTitle(info *common.HostInfo) (err error, result string) { } err, result = geturl(info) - if info.IsWebCan || err != nil { + if common.IsWebCan || err != nil { return } @@ -44,9 +44,15 @@ func geturl(info *common.HostInfo) (err error, result string) { TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, DisableKeepAlives: false, DialContext: (&net.Dialer{ - Timeout: time.Duration(info.WebTimeout) * time.Second, + Timeout: time.Duration(info.WebTimeout) * time.Second, + KeepAlive: time.Duration(info.WebTimeout+3) * time.Second, }).DialContext, + MaxIdleConns: 1000, + MaxIdleConnsPerHost: 1000, + IdleConnTimeout: time.Duration(info.WebTimeout+3) * time.Second, + TLSHandshakeTimeout: 5 * time.Second, } + var client = &http.Client{Timeout: time.Duration(info.WebTimeout) * time.Second, Transport: tr} res, err := http.NewRequest("GET", url, nil) if err == nil { diff --git a/WebScan/WebScan.go b/WebScan/WebScan.go index 798f4dc..5380e0a 100644 --- a/WebScan/WebScan.go +++ b/WebScan/WebScan.go @@ -13,9 +13,10 @@ import ( var Pocs embed.FS func WebScan(info *common.HostInfo) { - info.PocInfo.Target = info.Url - err := Execute(info.PocInfo) - if err != nil && info.Debug { + var pocinfo = common.Pocinfo + pocinfo.Target = info.Url + err := Execute(pocinfo) + if err != nil && common.LogErr { fmt.Println(info.Url, err) } } diff --git a/common/Parse.go b/common/Parse.go index cd8120f..382c007 100644 --- a/common/Parse.go +++ b/common/Parse.go @@ -28,8 +28,8 @@ func ParseUser(Info *HostInfo) { Userdict[name] = Info.Usernames } } - if Info.Userfile != "" { - uesrs, err := Readfile(Info.Userfile) + if Userfile != "" { + uesrs, err := Readfile(Userfile) if err == nil { for _, uesr := range uesrs { if uesr != "" { @@ -54,8 +54,8 @@ func ParsePass(Info *HostInfo) { } Passwords = Info.Passwords } - if Info.Passfile != "" { - passs, err := Readfile(Info.Passfile) + if Passfile != "" { + passs, err := Readfile(Passfile) if err == nil { for _, pass := range passs { if pass != "" { @@ -88,19 +88,20 @@ func Readfile(filename string) ([]string, error) { } func ParseInput(Info *HostInfo) { - if Info.Host == "" && Info.HostFile == "" { + if Info.Host == "" && HostFile == "" { fmt.Println("Host is none") flag.Usage() os.Exit(0) } - if Info.Outputfile != "" { + //LogErr = Info.Debug + if TmpOutputfile != "" { if !strings.Contains(Outputfile, "/") && !strings.Contains(Outputfile, `\`) { - Outputfile = getpath() + Info.Outputfile + Outputfile = getpath() + TmpOutputfile } else { - Outputfile = Info.Outputfile + Outputfile = TmpOutputfile } } - if Info.IsSave == true { + if TmpSave == true { IsSave = false } } diff --git a/common/config.go b/common/config.go index 69dee3f..5c9420c 100644 --- a/common/config.go +++ b/common/config.go @@ -53,38 +53,23 @@ var PortlistBack = map[string]int{ } var Outputfile = getpath() + "result.txt" - var IsSave = true var DefaultPorts = "21,22,80,81,135,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9200,11211,27017" type HostInfo struct { - Host string - HostFile string - Ports string - Domain string - Url string - Timeout int64 - WebTimeout int64 - Scantype string - Ping bool - Isping bool - Threads int - IcmpThreads int - Command string - Username string - Password string - Userfile string - Passfile string - Usernames []string - Passwords []string - Outputfile string - IsSave bool - RedisFile string - RedisShell string - IsWebCan bool - Debug bool - PocInfo PocInfo + Host string + Ports string + Domain string + Url string + Timeout int64 + WebTimeout int64 + Scantype string + Command string + Username string + Password string + Usernames []string + Passwords []string } type PocInfo struct { @@ -102,3 +87,16 @@ type PocInfo struct { ApiKey string CeyeDomain string } + +var TmpOutputfile string +var TmpSave bool +var IsPing bool +var Ping bool +var Pocinfo PocInfo +var IsWebCan bool +var RedisFile string +var RedisShell string +var Userfile string +var Passfile string +var HostFile string +var Threads int diff --git a/common/flag.go b/common/flag.go index 78e79d3..2cdddbd 100644 --- a/common/flag.go +++ b/common/flag.go @@ -11,7 +11,7 @@ func Banner() { / /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ - fscan version: 1.4.2 + fscan version: 1.4.3 ` print(banner) } @@ -19,30 +19,29 @@ func Banner() { func Flag(Info *HostInfo) { Banner() flag.StringVar(&Info.Host, "h", "", "IP address of the host you want to scan,for example: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12") - flag.StringVar(&Info.HostFile, "hf", "", "host file, -hs ip.txt") flag.StringVar(&Info.Ports, "p", DefaultPorts, "Select a port,for example: 22 | 1-65535 | 22,80,3306") flag.StringVar(&Info.Command, "c", "", "exec command (ssh)") - flag.IntVar(&Info.Threads, "t", 200, "Thread nums") - flag.IntVar(&Info.IcmpThreads, "it", 1100, "Icmp Threads nums") - flag.BoolVar(&Info.Isping, "np", false, "not to ping") - flag.BoolVar(&Info.Ping, "ping", false, "using ping replace icmp") - flag.BoolVar(&Info.IsSave, "no", false, "not to save output log") flag.StringVar(&Info.Domain, "domain", "", "smb domain") flag.StringVar(&Info.Username, "user", "", "username") - flag.StringVar(&Info.Userfile, "userf", "", "username file") flag.StringVar(&Info.Password, "pwd", "", "password") - flag.StringVar(&Info.Passfile, "pwdf", "", "password file") - flag.StringVar(&Info.Outputfile, "o", "result.txt", "Outputfile") flag.Int64Var(&Info.Timeout, "time", 3, "Set timeout") - flag.BoolVar(&Info.Debug, "debug", false, "debug mode will print more error info") flag.Int64Var(&Info.WebTimeout, "wt", 3, "Set web timeout") flag.StringVar(&Info.Scantype, "m", "all", "Select scan type ,as: -m ssh") - flag.StringVar(&Info.RedisFile, "rf", "", "redis file to write sshkey file (as: -rf id_rsa.pub) ") - flag.StringVar(&Info.RedisShell, "rs", "", "redis shell to write cron file (as: -rs 192.168.1.1:6666) ") - flag.BoolVar(&Info.IsWebCan, "nopoc", false, "not to scan web vul") - flag.StringVar(&Info.PocInfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic") - flag.StringVar(&Info.PocInfo.Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080") - flag.IntVar(&Info.PocInfo.Num, "Num", 20, "poc rate") + flag.IntVar(&Threads, "t", 200, "Thread nums") + flag.StringVar(&HostFile, "hf", "", "host file, -hs ip.txt") + flag.StringVar(&Userfile, "userf", "", "username file") + flag.StringVar(&Passfile, "pwdf", "", "password file") + flag.StringVar(&RedisFile, "rf", "", "redis file to write sshkey file (as: -rf id_rsa.pub) ") + flag.StringVar(&RedisShell, "rs", "", "redis shell to write cron file (as: -rs 192.168.1.1:6666) ") + flag.BoolVar(&IsWebCan, "nopoc", false, "not to scan web vul") + flag.BoolVar(&IsPing, "np", false, "not to ping") + flag.BoolVar(&Ping, "ping", false, "using ping replace icmp") + flag.StringVar(&TmpOutputfile, "o", "result.txt", "Outputfile") + flag.BoolVar(&TmpSave, "no", false, "not to save output log") + flag.BoolVar(&LogErr, "debug", false, "debug mode will print more error info") + flag.StringVar(&Pocinfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic") + flag.StringVar(&Pocinfo.Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080") + flag.IntVar(&Pocinfo.Num, "Num", 20, "poc rate") flag.Parse() } diff --git a/common/log.go b/common/log.go index 4170460..f51354e 100644 --- a/common/log.go +++ b/common/log.go @@ -3,14 +3,19 @@ package common import ( "fmt" "os" + "time" ) var Results = make(chan string) var Woker = 0 var Start = true +var LogSucTime int64 +var LogErr bool +var LogErrTime int64 func LogSuccess(result string) { Woker++ + LogSucTime = time.Now().Unix() if Start { go SaveLog() Start = false @@ -50,3 +55,12 @@ func WaitSave() { } } } + +func LogError(errinfo interface{}) { + if LogErr { + if (time.Now().Unix()-LogSucTime) > 10 && (time.Now().Unix()-LogErrTime) > 10 { + fmt.Println(errinfo) + LogErrTime = time.Now().Unix() + } + } +}