fscan/Plugins/portscan.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
}