mirror of https://github.com/qwqdanchun/fscan.git
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
package Plugins
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/shadow1ng/fscan/common"
|
|
"net"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
func ProbeHosts(host string, ports <-chan int, respondingHosts chan<- string, done chan<- bool, adjustedTimeout int64) {
|
|
for port := range ports {
|
|
con, err := net.DialTimeout("tcp4", fmt.Sprintf("%s:%d", host, port), time.Duration(adjustedTimeout)*time.Second)
|
|
if err == nil {
|
|
con.Close()
|
|
address := host + ":" + strconv.Itoa(port)
|
|
result := fmt.Sprintf("%s open", address)
|
|
common.LogSuccess(result)
|
|
respondingHosts <- address
|
|
}
|
|
}
|
|
done <- true
|
|
}
|
|
|
|
func ScanAllports(address string, probePorts []int, threads int, adjustedTimeout int64) ([]string, error) {
|
|
ports := make(chan int, 20)
|
|
results := make(chan string)
|
|
done := make(chan bool, threads)
|
|
|
|
for worker := 0; worker < threads; worker++ {
|
|
go ProbeHosts(address, ports, results, done, adjustedTimeout)
|
|
}
|
|
|
|
for _, port := range probePorts {
|
|
ports <- port
|
|
}
|
|
close(ports)
|
|
|
|
var responses = []string{}
|
|
for {
|
|
select {
|
|
case found := <-results:
|
|
responses = append(responses, found)
|
|
case <-done:
|
|
threads--
|
|
if threads == 0 {
|
|
return responses, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TCPportScan(hostslist []string, ports string, timeout int64) []string {
|
|
var AliveAddress []string
|
|
probePorts := common.ParsePort(ports)
|
|
lm := 20
|
|
if len(hostslist) > 5 && len(hostslist) <= 50 {
|
|
lm = 40
|
|
} else if len(hostslist) > 50 && len(hostslist) <= 100 {
|
|
lm = 50
|
|
} else if len(hostslist) > 100 && len(hostslist) <= 150 {
|
|
lm = 60
|
|
} else if len(hostslist) > 150 && len(hostslist) <= 200 {
|
|
lm = 70
|
|
} else if len(hostslist) > 200 {
|
|
lm = 75
|
|
}
|
|
|
|
thread := 10
|
|
if len(probePorts) > 500 && len(probePorts) <= 4000 {
|
|
thread = len(probePorts) / 100
|
|
} else if len(probePorts) > 4000 && len(probePorts) <= 6000 {
|
|
thread = len(probePorts) / 200
|
|
} else if len(probePorts) > 6000 && len(probePorts) <= 10000 {
|
|
thread = len(probePorts) / 350
|
|
} else if len(probePorts) > 10000 && len(probePorts) < 50000 {
|
|
thread = len(probePorts) / 400
|
|
} else if len(probePorts) >= 50000 && len(probePorts) <= 65535 {
|
|
thread = len(probePorts) / 500
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
mutex := &sync.Mutex{}
|
|
limiter := make(chan struct{}, lm)
|
|
for _, host := range hostslist {
|
|
wg.Add(1)
|
|
limiter <- struct{}{}
|
|
go func(host string) {
|
|
defer wg.Done()
|
|
if aliveAdd, err := ScanAllports(host, probePorts, thread, timeout); err == nil && len(aliveAdd) > 0 {
|
|
mutex.Lock()
|
|
AliveAddress = append(AliveAddress, aliveAdd...)
|
|
mutex.Unlock()
|
|
}
|
|
<-limiter
|
|
}(host)
|
|
}
|
|
wg.Wait()
|
|
return AliveAddress
|
|
}
|