ing
This commit is contained in:
parent
18fe18ccef
commit
40f2ebad23
|
@ -27,10 +27,10 @@ type DiscoveryPort struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dp *DiscoveryPort) Contains(port int) bool {
|
func (dp *DiscoveryPort) Contains(port int) bool {
|
||||||
if dp.FirstScanRange < port {
|
if dp.FirstScanRange > port {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if dp.LastScanRange > port {
|
if dp.LastScanRange < port {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, p := range dp.ExcludePorts {
|
for _, p := range dp.ExcludePorts {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
|
import "github.com/google/gopacket"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PortTypeTCP = "TCP"
|
PortTypeTCP = "TCP"
|
||||||
PortTypeUDP = "UDP"
|
PortTypeUDP = "UDP"
|
||||||
|
@ -13,4 +15,6 @@ type Port struct {
|
||||||
ID int `json:"id,omitempty"`
|
ID int `json:"id,omitempty"`
|
||||||
PortType string `json:"portType,omitempty"`
|
PortType string `json:"portType,omitempty"`
|
||||||
PortNumber int `json:"portNumber,omitempty"`
|
PortNumber int `json:"portNumber,omitempty"`
|
||||||
|
|
||||||
|
UDPLayer gopacket.Layer
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ func handlePacketTCP(host *model.Host, dp *model.DiscoveryPort, ports map[int]*m
|
||||||
}
|
}
|
||||||
|
|
||||||
port := int(packet.SrcPort)
|
port := int(packet.SrcPort)
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: IP of TCP(%d) src %s", port, host.IP))
|
||||||
|
|
||||||
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -134,7 +134,7 @@ func handlePacketUDP(host *model.Host, dp *model.DiscoveryPort, ports map[int]*m
|
||||||
|
|
||||||
srcIP := ipLayer.(*layers.IPv4).SrcIP
|
srcIP := ipLayer.(*layers.IPv4).SrcIP
|
||||||
port := int(udp.SrcPort)
|
port := int(udp.SrcPort)
|
||||||
logging.Logger().Debug(fmt.Sprintf("Discovery: IP of UPD(%d) src %v", port, srcIP))
|
logging.Logger().Debug(fmt.Sprintf("Discovery: IP of UDP(%d) src %v", port, srcIP))
|
||||||
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,7 @@ func handlePacketUDP(host *model.Host, dp *model.DiscoveryPort, ports map[int]*m
|
||||||
p := &model.Port{
|
p := &model.Port{
|
||||||
PortType: model.PortTypeUDP,
|
PortType: model.PortTypeUDP,
|
||||||
PortNumber: port,
|
PortNumber: port,
|
||||||
|
UDPLayer: udpLayer,
|
||||||
}
|
}
|
||||||
p.Host = host
|
p.Host = host
|
||||||
ports[port] = p
|
ports[port] = p
|
||||||
|
|
38
discovery/ipv4/service.go
Normal file
38
discovery/ipv4/service.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package ipv4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
||||||
|
"github.com/google/gopacket/layers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ScanService(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
||||||
|
|
||||||
|
switch port.PortType {
|
||||||
|
case model.PortTypeTCP:
|
||||||
|
if !scanServiceTCP(port, ds, resultChan, errChan, stopChan) {
|
||||||
|
if dName, ok := layers.TCPPortNames[layers.TCPPort(port.PortNumber)]; ok {
|
||||||
|
sName := fmt.Sprintf("Not Supported Service. Perhaps %s[%d]", dName, port.PortNumber)
|
||||||
|
s := &model.Service{
|
||||||
|
ServiceName: sName,
|
||||||
|
}
|
||||||
|
s.Port = port
|
||||||
|
resultChan <- s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case model.PortTypeUDP:
|
||||||
|
if !scanServiceUDP(port, ds, resultChan, errChan, stopChan) {
|
||||||
|
if dName, ok := layers.UDPPortNames[layers.UDPPort(port.PortNumber)]; ok {
|
||||||
|
sName := fmt.Sprintf("Not Supported Service. Perhaps %s[%d]", dName, port.PortNumber)
|
||||||
|
s := &model.Service{
|
||||||
|
ServiceName: sName,
|
||||||
|
}
|
||||||
|
s.Port = port
|
||||||
|
resultChan <- s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
discovery/ipv4/service_conn.go
Normal file
68
discovery/ipv4/service_conn.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package ipv4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type serviceConnector interface {
|
||||||
|
Type() string
|
||||||
|
Dial(ip string, port int) (net.Conn, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type normalServiceConn struct {
|
||||||
|
t string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nsc *normalServiceConn) Type() string {
|
||||||
|
return nsc.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nsc *normalServiceConn) Dial(ip string, port int) (net.Conn, error) {
|
||||||
|
addr := fmt.Sprintf("%s:%d", ip, port)
|
||||||
|
conn, err := net.DialTimeout("tcp", addr, time.Duration(3)*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = conn.SetDeadline(time.Now().Add(3 * time.Second))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return conn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type tlsServiceConn struct {
|
||||||
|
t string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tsc *tlsServiceConn) Type() string {
|
||||||
|
return tsc.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tsc *tlsServiceConn) Dial(ip string, port int) (net.Conn, error) {
|
||||||
|
addr := fmt.Sprintf("%s:%d", ip, port)
|
||||||
|
dialer := &net.Dialer{
|
||||||
|
Timeout: 3 * time.Second,
|
||||||
|
}
|
||||||
|
conn, err := tls.DialWithDialer(
|
||||||
|
dialer,
|
||||||
|
"tcp",
|
||||||
|
addr,
|
||||||
|
&tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
ServerName: ip,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = conn.SetDeadline(time.Now().Add(3 * time.Second))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return conn, err
|
||||||
|
}
|
208
discovery/ipv4/service_tcp.go
Normal file
208
discovery/ipv4/service_tcp.go
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
package ipv4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"git.loafle.net/commons_go/logging"
|
||||||
|
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/service"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/service/matcher"
|
||||||
|
)
|
||||||
|
|
||||||
|
func scanServiceTCP(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
|
||||||
|
|
||||||
|
hostIP := port.Host.IP
|
||||||
|
portNumber := port.PortNumber
|
||||||
|
info := matcher.NewMatchInfo(hostIP, portNumber)
|
||||||
|
var s *model.Service
|
||||||
|
|
||||||
|
scs := []serviceConnector{
|
||||||
|
&normalServiceConn{
|
||||||
|
t: model.PortTypeTCP,
|
||||||
|
},
|
||||||
|
&tlsServiceConn{
|
||||||
|
t: model.CryptoTypeTLS,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(scs); i++ {
|
||||||
|
sc := scs[i]
|
||||||
|
|
||||||
|
conn, err := sc.Dial(hostIP, portNumber)
|
||||||
|
if err != nil {
|
||||||
|
errChan <- fmt.Errorf("Discovery: Service scan[%s] on %s:%d error has occurred %v ", sc.Type(), hostIP, portNumber, err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
rn, err := conn.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
rn = 0
|
||||||
|
}
|
||||||
|
if rn != 0 {
|
||||||
|
s = hadlePrePacket(info, sc, conn, matcher.NewPacket(buf, rn))
|
||||||
|
} else {
|
||||||
|
conn.Close()
|
||||||
|
s = hadlePostPacket(info, sc)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil != s {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil != s {
|
||||||
|
s.Port = port
|
||||||
|
resultChan <- s
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func hadlePrePacket(info matcher.MatchInfo, sc serviceConnector, conn net.Conn, packet *matcher.Packet) *model.Service {
|
||||||
|
defer func() {
|
||||||
|
conn.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan pre packet length[%d]", packet.Len))
|
||||||
|
|
||||||
|
ms := service.GetTCPMatchers(true)
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
var s *model.Service
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for i := 0; i < len(ms); i++ {
|
||||||
|
m := ms[i]
|
||||||
|
|
||||||
|
if m.Match(info, 0, packet) {
|
||||||
|
packetCount := m.PacketCount()
|
||||||
|
|
||||||
|
if 0 == packetCount {
|
||||||
|
s = &model.Service{
|
||||||
|
ServiceName: m.ServiceName(),
|
||||||
|
CryptoType: sc.Type(),
|
||||||
|
}
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
|
||||||
|
for j := 0; j < packetCount; j++ {
|
||||||
|
tPacket := m.Packet(j)
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d]", tPacket.Len))
|
||||||
|
wn, err := conn.Write(tPacket.Buffer)
|
||||||
|
if nil != err {
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet error %v", err))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if wn != tPacket.Len {
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d] not same with %d", wn, tPacket.Len))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
rn, err := conn.Read(buf)
|
||||||
|
if nil != err {
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive packet error %v", err))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Match(info, j+1, matcher.NewPacket(buf, rn)) {
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d]", rn))
|
||||||
|
found = true
|
||||||
|
} else {
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d]", rn))
|
||||||
|
found = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
s = &model.Service{
|
||||||
|
ServiceName: m.ServiceName(),
|
||||||
|
CryptoType: sc.Type(),
|
||||||
|
}
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func hadlePostPacket(info matcher.MatchInfo, sc serviceConnector) *model.Service {
|
||||||
|
ms := service.GetTCPMatchers(false)
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
var s *model.Service
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for i := 0; i < len(ms); i++ {
|
||||||
|
m := ms[i]
|
||||||
|
|
||||||
|
conn, err := sc.Dial(info.IP(), info.Port())
|
||||||
|
if err != nil {
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan socket[%s:%d] dial error %v", info.IP(), info.Port(), err))
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
|
||||||
|
packetCount := m.PacketCount()
|
||||||
|
for j := 0; j < packetCount; j++ {
|
||||||
|
tPacket := m.Packet(j)
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d]", tPacket.Len))
|
||||||
|
wn, err := conn.Write(tPacket.Buffer)
|
||||||
|
if nil != err {
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet error %v", err))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if wn != tPacket.Len {
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d] not same with %d", wn, tPacket.Len))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
rn, err := conn.Read(buf)
|
||||||
|
if nil != err {
|
||||||
|
if !m.HasResponse(j) {
|
||||||
|
s = &model.Service{
|
||||||
|
ServiceName: m.ServiceName(),
|
||||||
|
CryptoType: sc.Type(),
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive packet error %v", err))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Match(info, j, matcher.NewPacket(buf, rn)) {
|
||||||
|
if packetCount-1 == j {
|
||||||
|
s = &model.Service{
|
||||||
|
ServiceName: m.ServiceName(),
|
||||||
|
CryptoType: sc.Type(),
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d]", rn))
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf))
|
||||||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d]", rn))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
|
||||||
|
if nil != s {
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
29
discovery/ipv4/service_udp.go
Normal file
29
discovery/ipv4/service_udp.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package ipv4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/service"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/service/matcher"
|
||||||
|
)
|
||||||
|
|
||||||
|
func scanServiceUDP(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
|
||||||
|
|
||||||
|
ms := service.GetUDPMatchers()
|
||||||
|
mi := matcher.NewMatchInfo(port.Host.IP, port.PortNumber)
|
||||||
|
|
||||||
|
for i := 0; i < len(ms); i++ {
|
||||||
|
m := ms[i]
|
||||||
|
p := matcher.NewPacket(port.UDPLayer.LayerPayload(), len(port.UDPLayer.LayerPayload()))
|
||||||
|
|
||||||
|
if m.Match(mi, 0, p) {
|
||||||
|
s := &model.Service{
|
||||||
|
ServiceName: m.ServiceName(),
|
||||||
|
}
|
||||||
|
s.Port = port
|
||||||
|
resultChan <- s
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
7
discovery/ipv6/service.go
Normal file
7
discovery/ipv6/service.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package ipv6
|
||||||
|
|
||||||
|
import "git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
||||||
|
|
||||||
|
func ScanService(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,33 @@
|
||||||
package discovery
|
package discovery
|
||||||
|
|
||||||
import "git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/discovery/ipv4"
|
||||||
|
"git.loafle.net/overflow/overflow_discovery/discovery/ipv6"
|
||||||
|
)
|
||||||
|
|
||||||
func scanService(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, doneChan chan<- struct{}, stopChan chan struct{}) {
|
func scanService(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, doneChan chan<- struct{}, stopChan chan struct{}) {
|
||||||
defer func() {
|
defer func() {
|
||||||
doneChan <- struct{}{}
|
doneChan <- struct{}{}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
_, ipNet, err := net.ParseCIDR(port.Host.Zone.Network)
|
||||||
|
if nil != err {
|
||||||
|
errChan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(ipNet.IP) {
|
||||||
|
case net.IPv4len:
|
||||||
|
ipv4.ScanService(port, ds, resultChan, errChan, stopChan)
|
||||||
|
case net.IPv6len:
|
||||||
|
ipv6.ScanService(port, ds, resultChan, errChan, stopChan)
|
||||||
|
|
||||||
|
default:
|
||||||
|
errChan <- fmt.Errorf("Discovery: Not supported ip length")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ type POPMatcher struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *POPMatcher) ServiceName() string {
|
func (p *POPMatcher) ServiceName() string {
|
||||||
return "POPMatcher"
|
return "POP3"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *POPMatcher) IsPrePacket() bool {
|
func (p *POPMatcher) IsPrePacket() bool {
|
||||||
|
|
|
@ -82,8 +82,8 @@ func registerUDPMatcher(m matcher.UDPMatcher) {
|
||||||
UDPMatchers = append(UDPMatchers, m)
|
UDPMatchers = append(UDPMatchers, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTCPMatchers(ispre bool) []matcher.Matcher {
|
func GetTCPMatchers(isPrePacket bool) []matcher.Matcher {
|
||||||
if ispre {
|
if isPrePacket {
|
||||||
return TCPPrePacketMatchers
|
return TCPPrePacketMatchers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user