tcp scan by connection added
This commit is contained in:
parent
92279d4944
commit
99166af860
|
@ -11,6 +11,9 @@ import (
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/protocol/snmp"
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/snmp"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/protocol/upnp"
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/upnp"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/target/host"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/target/port"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/target/service"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -218,5 +221,71 @@ func (d *ofDiscoverer) complexDiscover(s session.DiscoverySession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) hierarchyDiscover(s session.DiscoverySession) {
|
func (d *ofDiscoverer) hierarchyDiscover(s session.DiscoverySession) {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
discoveredChan := make(chan interface{})
|
||||||
|
s.SetDiscoveryDelegator(discoveredChan)
|
||||||
|
defer func() {
|
||||||
|
s.SetDiscoveryDelegator(nil)
|
||||||
|
close(discoveredChan)
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case target, ok := <-discoveredChan:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch target.(type) {
|
||||||
|
case *omd.Host:
|
||||||
|
d.SendMessage(s.DiscoveryRequest(), types.DiscoveryMessageTypeHost, target, nil)
|
||||||
|
if nil != s.DiscoverPort() {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
port.Scan(s, target.(*omd.Host))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
case *omd.Port:
|
||||||
|
d.SendMessage(s.DiscoveryRequest(), types.DiscoveryMessageTypePort, target, nil)
|
||||||
|
if nil != s.DiscoverService() {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
service.Scan(s, target.(*omd.Port))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
case *omd.Service:
|
||||||
|
d.SendMessage(s.DiscoveryRequest(), types.DiscoveryMessageTypeService, target, nil)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if nil != s.DiscoverHost() {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
host.Scan(s)
|
||||||
|
}()
|
||||||
|
} else if nil != s.DiscoverPort() {
|
||||||
|
if nil != s.Host() {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
port.Scan(s, s.Host())
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
} else if nil != s.DiscoverService() {
|
||||||
|
if nil != s.Port() {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
service.Scan(s, s.Port())
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
116
discovery/protocol/tcp/connection/connection.go
Normal file
116
discovery/protocol/tcp/connection/connection.go
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package connection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
omm "git.loafle.net/overflow/model/meta"
|
||||||
|
omu "git.loafle.net/overflow/model/util"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"golang.org/x/sync/semaphore"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultUlimit = 1024
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
if nil == targetHost || nil == discoverySession.DiscoverPort() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dp := discoverySession.DiscoverPort()
|
||||||
|
|
||||||
|
lock := semaphore.NewWeighted(Ulimit())
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
timeout := 500 * time.Millisecond
|
||||||
|
ports := make(map[int]*omd.Port)
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for portNumber := dp.FirstScanRange; portNumber < dp.LastScanRange; portNumber++ {
|
||||||
|
if nil != dp.ExcludePorts {
|
||||||
|
for _, exPortNumber := range dp.ExcludePorts {
|
||||||
|
if portNumber == exPortNumber {
|
||||||
|
continue Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.Acquire(context.TODO(), 1)
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
go func(port int) {
|
||||||
|
defer func() {
|
||||||
|
lock.Release(1)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
scanPort(discoverySession, ports, targetHost, port, timeout)
|
||||||
|
}(portNumber)
|
||||||
|
|
||||||
|
timer := time.NewTimer(time.Microsecond * 100)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-timer.C:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanPort(discoverySession session.DiscoverySession, ports map[int]*omd.Port, targetHost *omd.Host, port int, timeout time.Duration) {
|
||||||
|
addr := net.JoinHostPort(targetHost.Address, strconv.Itoa(port))
|
||||||
|
conn, err := net.DialTimeout("tcp", addr, timeout)
|
||||||
|
dp := discoverySession.DiscoverPort()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "too many open files") {
|
||||||
|
time.Sleep(timeout)
|
||||||
|
scanPort(discoverySession, ports, targetHost, port, timeout)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Close()
|
||||||
|
|
||||||
|
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p := &omd.Port{
|
||||||
|
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
|
||||||
|
PortNumber: json.Number(strconv.Itoa(port)),
|
||||||
|
DiscoveredDate: omu.NowPtr(),
|
||||||
|
}
|
||||||
|
p.Host = targetHost
|
||||||
|
|
||||||
|
ports[port] = p
|
||||||
|
|
||||||
|
log.Printf("port: %v", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ulimit() int64 {
|
||||||
|
out, err := exec.Command("ulimit", "-n").Output()
|
||||||
|
if nil != err {
|
||||||
|
return defaultUlimit
|
||||||
|
}
|
||||||
|
|
||||||
|
s := strings.TrimSpace(string(out))
|
||||||
|
|
||||||
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
|
if nil != err {
|
||||||
|
return defaultUlimit
|
||||||
|
}
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
107
discovery/protocol/tcp/connection/connection_test.go
Normal file
107
discovery/protocol/tcp/connection/connection_test.go
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
package connection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
omm "git.loafle.net/overflow/model/meta"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestScan(t *testing.T) {
|
||||||
|
s := session.NewMockDiscoverySession(
|
||||||
|
"testRequester",
|
||||||
|
types.DiscoveryRequestTypeHost,
|
||||||
|
&omd.Zone{
|
||||||
|
Network: "192.168.1.0/24",
|
||||||
|
Iface: "enp3s0",
|
||||||
|
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
||||||
|
Address: "192.168.1.101",
|
||||||
|
Mac: "44:8a:5b:f1:f1:f3",
|
||||||
|
},
|
||||||
|
&omd.DiscoverHost{
|
||||||
|
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
||||||
|
FirstScanRange: "192.168.1.1",
|
||||||
|
LastScanRange: "192.168.1.254",
|
||||||
|
DiscoveryConfig: &omd.DiscoveryConfig{},
|
||||||
|
DiscoverPort: &omd.DiscoverPort{
|
||||||
|
FirstScanRange: 1,
|
||||||
|
LastScanRange: 65535,
|
||||||
|
IncludeTCP: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
targetHost := &omd.Host{
|
||||||
|
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
||||||
|
Name: "atGame",
|
||||||
|
Address: "192.168.1.1",
|
||||||
|
Mac: "00:11:32:7f:20:61",
|
||||||
|
Zone: s.Zone(),
|
||||||
|
}
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
discoverySession session.DiscoverySession
|
||||||
|
targetHost *omd.Host
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "1",
|
||||||
|
args: args{
|
||||||
|
discoverySession: s,
|
||||||
|
targetHost: targetHost,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := Scan(tt.args.discoverySession, tt.args.targetHost); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Scan() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_scanPort(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
discoverySession session.DiscoverySession
|
||||||
|
ports map[int]*omd.Port
|
||||||
|
targetHost *omd.Host
|
||||||
|
port int
|
||||||
|
timeout time.Duration
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
scanPort(tt.args.discoverySession, tt.args.ports, tt.args.targetHost, tt.args.port, tt.args.timeout)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUlimit(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
want int64
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := Ulimit(); got != tt.want {
|
||||||
|
t.Errorf("Ulimit() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package tcp
|
package syn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
omd "git.loafle.net/overflow/model/discovery"
|
|
@ -1,4 +1,4 @@
|
||||||
package tcp
|
package syn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
|
@ -1,4 +1,4 @@
|
||||||
package tcp
|
package syn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
59
discovery/target/host/host.go
Normal file
59
discovery/target/host/host.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/arp"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/internal/pcap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scan(discoverySession session.DiscoverySession) error {
|
||||||
|
targetHosts := discoverySession.TargetHosts()
|
||||||
|
if nil == targetHosts || 0 == len(targetHosts) || nil == discoverySession.DiscoverHost() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
zone := discoverySession.Zone()
|
||||||
|
|
||||||
|
var privileged bool
|
||||||
|
|
||||||
|
_, err := pcap.RetainScanner(zone)
|
||||||
|
if nil == err {
|
||||||
|
pcap.ReleaseScanner(zone)
|
||||||
|
privileged = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if privileged {
|
||||||
|
return privilegedScan(discoverySession)
|
||||||
|
}
|
||||||
|
|
||||||
|
return unprivilegedScan(discoverySession)
|
||||||
|
}
|
||||||
|
|
||||||
|
func privilegedScan(discoverySession session.DiscoverySession) error {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
arp.Scan(discoverySession)
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
icmp.Scan(discoverySession)
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unprivilegedScan(discoverySession session.DiscoverySession) error {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
61
discovery/target/port/port.go
Normal file
61
discovery/target/port/port.go
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package port
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/tcp/connection"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/tcp/syn"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/internal/pcap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
if nil == targetHost || nil == discoverySession.DiscoverPort() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
zone := discoverySession.Zone()
|
||||||
|
|
||||||
|
var privileged bool
|
||||||
|
|
||||||
|
_, err := pcap.RetainScanner(zone)
|
||||||
|
if nil == err {
|
||||||
|
pcap.ReleaseScanner(zone)
|
||||||
|
privileged = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if privileged {
|
||||||
|
return privilegedScan(discoverySession, targetHost)
|
||||||
|
}
|
||||||
|
|
||||||
|
return unprivilegedScan(discoverySession, targetHost)
|
||||||
|
}
|
||||||
|
|
||||||
|
func privilegedScan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
syn.Scan(discoverySession, targetHost)
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unprivilegedScan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
connection.Scan(discoverySession, targetHost)
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user