修改icmp发包模式,更适合大规模探测。

修改报错提示,--debug时,如果10秒内没有LogSuccess的消息,每隔10秒就会打印一下当前进度
This commit is contained in:
shadow1ng 2021-02-05 14:43:07 +08:00
parent d468986428
commit 1a8964cc6e
15 changed files with 149 additions and 121 deletions

View File

@ -16,6 +16,8 @@ func FtpScan(info *common.HostInfo) (tmperr error) {
if flag == true && err == nil { if flag == true && err == nil {
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] ftp %v %v %v %v %v", info.Host, common.PORTList["ftp"], user, pass, err)
common.LogError(errlog)
tmperr = err tmperr = err
} }
} }

View File

@ -3,6 +3,8 @@ package Plugins
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"golang.org/x/net/icmp"
"log"
"net" "net"
"os" "os"
"os/exec" "os/exec"
@ -50,58 +52,52 @@ func GetSys() SystemInfo {
return sysinfo return sysinfo
} }
func isping(ip string) bool { func IcmpCheck(hostslist []string) {
IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0} conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
Time, _ := time.ParseDuration("3s") endflag := false
conn, err := net.DialTimeout("ip4:icmp", ip, Time)
if err != nil { if err != nil {
return false log.Fatal(err)
}
defer conn.Close()
_, err = conn.Write(IcmpByte)
if err != nil {
return false
} }
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 { go func() {
return false 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) for _, host := range hostslist {
num, err := conn.Read(recvBuf[0:40]) write(host, conn)
if err != nil {
return false
} }
if err := conn.SetReadDeadline(time.Now().Add(time.Second * 3)); err != nil { if len(hostslist) > 10 {
return false time.Sleep(6 * time.Second)
} else {
time.Sleep(3 * time.Second)
} }
if string(recvBuf[0:num]) != "" { endflag = true
fmt.Printf("(ICMP) Target '%s' is alive\n", ip) close(chanHosts)
return true conn.Close()
}
return false
} }
func IcmpCheck(hostslist []string, IcmpThreads int) { func write(ip string, conn *icmp.PacketConn) {
var wg sync.WaitGroup dst, _ := net.ResolveIPAddr("ip", ip)
mutex := &sync.Mutex{} IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0}
limiter := make(chan struct{}, IcmpThreads) conn.WriteTo(IcmpByte, dst)
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 ExecCommandPing(ip string, bsenv string) bool { func ExecCommandPing(ip string, bsenv string) bool {
@ -133,7 +129,7 @@ func ExecCommandPing(ip string, bsenv string) bool {
func PingCMDcheck(hostslist []string, bsenv string) { func PingCMDcheck(hostslist []string, bsenv string) {
var wg sync.WaitGroup var wg sync.WaitGroup
mutex := &sync.Mutex{} mutex := &sync.Mutex{}
limiter := make(chan struct{}, 40) limiter := make(chan struct{}, 50)
for _, host := range hostslist { for _, host := range hostslist {
wg.Add(1) wg.Add(1)
limiter <- struct{}{} limiter <- struct{}{}
@ -150,18 +146,17 @@ func PingCMDcheck(hostslist []string, bsenv string) {
} }
wg.Wait() wg.Wait()
} }
func ICMPRun(hostslist []string, IcmpThreads int, Ping bool) []string { func ICMPRun(hostslist []string, Ping bool) []string {
if SysInfo.OS == "windows" { if SysInfo.OS == "windows" {
if Ping == false { if Ping == false {
IcmpCheck(hostslist, IcmpThreads) IcmpCheck(hostslist)
} else { } else {
PingCMDcheck(hostslist, "") PingCMDcheck(hostslist, "")
} }
} else if SysInfo.OS == "linux" { } else if SysInfo.OS == "linux" {
if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" { if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" {
if Ping == false { if Ping == false {
IcmpCheck(hostslist, IcmpThreads) IcmpCheck(hostslist)
} else { } else {
PingCMDcheck(hostslist, "/bin/bash") PingCMDcheck(hostslist, "/bin/bash")
} }
@ -173,7 +168,7 @@ func ICMPRun(hostslist []string, IcmpThreads int, Ping bool) []string {
} else if SysInfo.OS == "darwin" { } else if SysInfo.OS == "darwin" {
if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" { if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" {
if Ping == false { if Ping == false {
IcmpCheck(hostslist, IcmpThreads) IcmpCheck(hostslist)
} else { } else {
PingCMDcheck(hostslist, "/bin/bash") PingCMDcheck(hostslist, "/bin/bash")
} }

View File

@ -17,6 +17,8 @@ func MssqlScan(info *common.HostInfo) (tmperr error) {
if flag == true && err == nil { if flag == true && err == nil {
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] mssql %v %v %v %v %v", info.Host, common.PORTList["mssql"], user, pass, err)
common.LogError(errlog)
tmperr = err tmperr = err
} }
} }

View File

@ -17,6 +17,8 @@ func MysqlScan(info *common.HostInfo) (tmperr error) {
if flag == true && err == nil { if flag == true && err == nil {
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] mysql %v %v %v %v %v", info.Host, common.PORTList["mysql"], user, pass, err)
common.LogError(errlog)
tmperr = err tmperr = err
} }
} }

View File

@ -17,6 +17,8 @@ func PostgresScan(info *common.HostInfo) (tmperr error) {
if flag == true && err == nil { if flag == true && err == nil {
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] psql %v %v %v %v %v", info.Host, common.PORTList["psql"], user, pass, err)
common.LogError(errlog)
tmperr = err tmperr = err
} }
} }

View File

@ -21,6 +21,8 @@ func RedisScan(info *common.HostInfo) (tmperr error) {
if flag == true && err == nil { if flag == true && err == nil {
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] redis %v %v %v %v %v", info.Host, common.PORTList["redis"], pass, err)
common.LogError(errlog)
tmperr = err 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) result := fmt.Sprintf("[+] Redis:%s %s", realhost, pass)
common.LogSuccess(result) common.LogSuccess(result)
flag = true flag = true
Expoilt(info, realhost, conn) Expoilt(realhost, conn)
} }
return flag, err return flag, err
} }
@ -72,12 +74,12 @@ func RedisUnauth(info *common.HostInfo) (flag bool, err error) {
result := fmt.Sprintf("[+] Redis:%s unauthorized", realhost) result := fmt.Sprintf("[+] Redis:%s unauthorized", realhost)
common.LogSuccess(result) common.LogSuccess(result)
flag = true flag = true
Expoilt(info, realhost, conn) Expoilt(realhost, conn)
} }
return flag, err 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) flagSsh, flagCron, err := testwrite(conn)
if err != nil { if err != nil {
return err return err
@ -85,8 +87,8 @@ func Expoilt(info *common.HostInfo, realhost string, conn net.Conn) error {
if flagSsh == true { if flagSsh == true {
result := fmt.Sprintf("Redis:%v like can write /root/.ssh/", realhost) result := fmt.Sprintf("Redis:%v like can write /root/.ssh/", realhost)
common.LogSuccess(result) common.LogSuccess(result)
if info.RedisFile != "" { if common.RedisFile != "" {
writeok, text, err := writekey(conn, info.RedisFile) writeok, text, err := writekey(conn, common.RedisFile)
if err != nil { if err != nil {
return err return err
} }
@ -102,8 +104,8 @@ func Expoilt(info *common.HostInfo, realhost string, conn net.Conn) error {
if flagCron == true { if flagCron == true {
result := fmt.Sprintf("Redis:%v like can write /var/spool/cron/", realhost) result := fmt.Sprintf("Redis:%v like can write /var/spool/cron/", realhost)
common.LogSuccess(result) common.LogSuccess(result)
if info.RedisShell != "" { if common.RedisShell != "" {
writeok, text, err := writecron(conn, info.RedisShell) writeok, text, err := writecron(conn, common.RedisShell)
if err != nil { if err != nil {
return err return err
} }

View File

@ -12,9 +12,9 @@ import (
func Scan(info common.HostInfo) { func Scan(info common.HostInfo) {
fmt.Println("scan start") fmt.Println("scan start")
Hosts, _ := common.ParseIP(info.Host, info.HostFile) Hosts, _ := common.ParseIP(info.Host, common.HostFile)
if info.Isping == false { if common.IsPing == false {
Hosts = ICMPRun(Hosts, info.IcmpThreads, info.Ping) Hosts = ICMPRun(Hosts, common.Ping)
fmt.Println("icmp alive hosts len is:", len(Hosts)) fmt.Println("icmp alive hosts len is:", len(Hosts))
} }
if info.Scantype == "icmp" { if info.Scantype == "icmp" {
@ -28,7 +28,7 @@ func Scan(info common.HostInfo) {
for _, port := range common.PORTList { for _, port := range common.PORTList {
severports = append(severports, strconv.Itoa(port)) severports = append(severports, strconv.Itoa(port))
} }
var ch = make(chan struct{}, info.Threads) var ch = make(chan struct{}, common.Threads)
var wg = sync.WaitGroup{} var wg = sync.WaitGroup{}
for _, targetIP := range AlivePorts { for _, targetIP := range AlivePorts {
info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1] 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) wg.Add(1)
go func() { go func() {
err, _ := ScanFunc(PluginList, scantype, &info) err, _ := ScanFunc(PluginList, scantype, &info)
if info.Debug { if common.LogErr {
tmperr := err[0].Interface() tmperr := err[0].Interface()
if tmperr != nil { if tmperr != nil {
tmperr1 := err[0].Interface().(error) tmperr1 := err[0].Interface().(error)
errtext := strings.Replace(tmperr1.Error(), "\n", "", -1) errtext := strings.Replace(tmperr1.Error(), "\n", "", -1)
fmt.Println(info.Host+":"+info.Ports, errtext) fmt.Println("[-] ", info.Host+":"+info.Ports, errtext)
} }
} }
wg.Done() wg.Done()

View File

@ -23,6 +23,8 @@ func SmbScan(info *common.HostInfo) (tmperr error) {
common.LogSuccess(result) common.LogSuccess(result)
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] smb %v %v %v %v %v", info.Host, 445, user, pass, err)
common.LogError(errlog)
tmperr = err tmperr = err
} }
} }

View File

@ -17,6 +17,8 @@ func SshScan(info *common.HostInfo) (tmperr error) {
if flag == true && err == nil { if flag == true && err == nil {
return err return err
} else { } else {
errlog := fmt.Sprintf("[-] ssh", info.Host, common.PORTList["ssh"], user, pass, err)
common.LogError(errlog)
tmperr = err tmperr = err
} }
} }

View File

@ -23,7 +23,7 @@ func WebTitle(info *common.HostInfo) (err error, result string) {
} }
err, result = geturl(info) err, result = geturl(info)
if info.IsWebCan || err != nil { if common.IsWebCan || err != nil {
return return
} }
@ -44,9 +44,15 @@ func geturl(info *common.HostInfo) (err error, result string) {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
DisableKeepAlives: false, DisableKeepAlives: false,
DialContext: (&net.Dialer{ 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, }).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} var client = &http.Client{Timeout: time.Duration(info.WebTimeout) * time.Second, Transport: tr}
res, err := http.NewRequest("GET", url, nil) res, err := http.NewRequest("GET", url, nil)
if err == nil { if err == nil {

View File

@ -13,9 +13,10 @@ import (
var Pocs embed.FS var Pocs embed.FS
func WebScan(info *common.HostInfo) { func WebScan(info *common.HostInfo) {
info.PocInfo.Target = info.Url var pocinfo = common.Pocinfo
err := Execute(info.PocInfo) pocinfo.Target = info.Url
if err != nil && info.Debug { err := Execute(pocinfo)
if err != nil && common.LogErr {
fmt.Println(info.Url, err) fmt.Println(info.Url, err)
} }
} }

View File

@ -28,8 +28,8 @@ func ParseUser(Info *HostInfo) {
Userdict[name] = Info.Usernames Userdict[name] = Info.Usernames
} }
} }
if Info.Userfile != "" { if Userfile != "" {
uesrs, err := Readfile(Info.Userfile) uesrs, err := Readfile(Userfile)
if err == nil { if err == nil {
for _, uesr := range uesrs { for _, uesr := range uesrs {
if uesr != "" { if uesr != "" {
@ -54,8 +54,8 @@ func ParsePass(Info *HostInfo) {
} }
Passwords = Info.Passwords Passwords = Info.Passwords
} }
if Info.Passfile != "" { if Passfile != "" {
passs, err := Readfile(Info.Passfile) passs, err := Readfile(Passfile)
if err == nil { if err == nil {
for _, pass := range passs { for _, pass := range passs {
if pass != "" { if pass != "" {
@ -88,19 +88,20 @@ func Readfile(filename string) ([]string, error) {
} }
func ParseInput(Info *HostInfo) { func ParseInput(Info *HostInfo) {
if Info.Host == "" && Info.HostFile == "" { if Info.Host == "" && HostFile == "" {
fmt.Println("Host is none") fmt.Println("Host is none")
flag.Usage() flag.Usage()
os.Exit(0) os.Exit(0)
} }
if Info.Outputfile != "" { //LogErr = Info.Debug
if TmpOutputfile != "" {
if !strings.Contains(Outputfile, "/") && !strings.Contains(Outputfile, `\`) { if !strings.Contains(Outputfile, "/") && !strings.Contains(Outputfile, `\`) {
Outputfile = getpath() + Info.Outputfile Outputfile = getpath() + TmpOutputfile
} else { } else {
Outputfile = Info.Outputfile Outputfile = TmpOutputfile
} }
} }
if Info.IsSave == true { if TmpSave == true {
IsSave = false IsSave = false
} }
} }

View File

@ -53,38 +53,23 @@ var PortlistBack = map[string]int{
} }
var Outputfile = getpath() + "result.txt" var Outputfile = getpath() + "result.txt"
var IsSave = true var IsSave = true
var DefaultPorts = "21,22,80,81,135,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9200,11211,27017" var DefaultPorts = "21,22,80,81,135,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9200,11211,27017"
type HostInfo struct { type HostInfo struct {
Host string Host string
HostFile string Ports string
Ports string Domain string
Domain string Url string
Url string Timeout int64
Timeout int64 WebTimeout int64
WebTimeout int64 Scantype string
Scantype string Command string
Ping bool Username string
Isping bool Password string
Threads int Usernames []string
IcmpThreads int Passwords []string
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
} }
type PocInfo struct { type PocInfo struct {
@ -102,3 +87,16 @@ type PocInfo struct {
ApiKey string ApiKey string
CeyeDomain 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

View File

@ -11,7 +11,7 @@ func Banner() {
/ /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ / / /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ /
/ /_\\_____\__ \ (__| | | (_| | (__| < / /_\\_____\__ \ (__| | | (_| | (__| <
\____/ |___/\___|_| \__,_|\___|_|\_\ \____/ |___/\___|_| \__,_|\___|_|\_\
fscan version: 1.4.2 fscan version: 1.4.3
` `
print(banner) print(banner)
} }
@ -19,30 +19,29 @@ func Banner() {
func Flag(Info *HostInfo) { func Flag(Info *HostInfo) {
Banner() 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.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.Ports, "p", DefaultPorts, "Select a port,for example: 22 | 1-65535 | 22,80,3306")
flag.StringVar(&Info.Command, "c", "", "exec command (ssh)") 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.Domain, "domain", "", "smb domain")
flag.StringVar(&Info.Username, "user", "", "username") flag.StringVar(&Info.Username, "user", "", "username")
flag.StringVar(&Info.Userfile, "userf", "", "username file")
flag.StringVar(&Info.Password, "pwd", "", "password") 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.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.Int64Var(&Info.WebTimeout, "wt", 3, "Set web timeout")
flag.StringVar(&Info.Scantype, "m", "all", "Select scan type ,as: -m ssh") 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.IntVar(&Threads, "t", 200, "Thread nums")
flag.StringVar(&Info.PocInfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic") flag.StringVar(&HostFile, "hf", "", "host file, -hs ip.txt")
flag.StringVar(&Info.PocInfo.Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080") flag.StringVar(&Userfile, "userf", "", "username file")
flag.IntVar(&Info.PocInfo.Num, "Num", 20, "poc rate") 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() flag.Parse()
} }

View File

@ -3,14 +3,19 @@ package common
import ( import (
"fmt" "fmt"
"os" "os"
"time"
) )
var Results = make(chan string) var Results = make(chan string)
var Woker = 0 var Woker = 0
var Start = true var Start = true
var LogSucTime int64
var LogErr bool
var LogErrTime int64
func LogSuccess(result string) { func LogSuccess(result string) {
Woker++ Woker++
LogSucTime = time.Now().Unix()
if Start { if Start {
go SaveLog() go SaveLog()
Start = false 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()
}
}
}