probe/discovery/target/service/service-tcp.go

285 lines
6.1 KiB
Go
Raw Normal View History

2018-08-31 10:53:33 +00:00
package service
import (
2018-08-31 12:56:36 +00:00
"fmt"
"net"
"time"
2018-08-31 10:53:33 +00:00
omd "git.loafle.net/overflow/model/discovery"
2018-09-17 14:18:49 +00:00
omm "git.loafle.net/overflow/model/meta"
2018-09-01 13:09:33 +00:00
omu "git.loafle.net/overflow/model/util"
2018-08-31 12:56:36 +00:00
osm "git.loafle.net/overflow/service_matcher-go"
ouej "git.loafle.net/overflow/util-go/encoding/json"
2018-08-31 10:53:33 +00:00
"git.loafle.net/overflow_scanner/probe/discovery/session"
2018-08-31 12:56:36 +00:00
"git.loafle.net/overflow_scanner/probe/internal/matcher"
2018-08-31 10:53:33 +00:00
)
2018-09-04 18:58:33 +00:00
const (
2018-10-23 03:09:40 +00:00
deadline = time.Millisecond * 1000
2018-09-04 18:58:33 +00:00
)
2018-08-31 10:53:33 +00:00
func scanTCP(discoverySession session.DiscoverySession, targetPort *omd.Port) error {
2018-08-31 12:56:36 +00:00
hostAddress := targetPort.Host.Address
portNumber, err := ouej.NumberToInt(targetPort.PortNumber)
if err != nil {
return fmt.Errorf("Service scan on %s:%s error has occurred %v ", hostAddress, targetPort.PortNumber, err)
}
2018-09-17 17:32:36 +00:00
2018-09-18 01:24:54 +00:00
var limitedMatchers []osm.Matcher
2018-10-23 05:16:41 +00:00
matchCtx := osm.NewMatchCtx(hostAddress, portNumber)
2018-09-18 01:24:54 +00:00
2018-09-17 17:32:36 +00:00
if omm.MetaHostTypeEnumPrinter.String() == targetPort.Host.HostType {
2018-09-18 01:24:54 +00:00
switch portNumber {
2018-09-18 03:39:00 +00:00
// case 7:
// return nil
2018-09-18 01:24:54 +00:00
case 515:
limitedMatchers = []osm.Matcher{
2018-10-23 05:16:41 +00:00
matcher.GetMatcherByKey(matchCtx, "LPD"),
2018-09-18 01:24:54 +00:00
}
case 8290:
2018-09-18 03:39:00 +00:00
discoverySession.AddServiceUnknown(
omm.ToMetaDiscovererType(omm.MetaDiscovererTypeEnumTCPMatcher),
targetPort,
)
2018-09-18 01:24:54 +00:00
return nil
case 9100:
2018-09-17 17:32:36 +00:00
return nil
}
2018-09-03 10:33:20 +00:00
}
2018-08-31 12:56:36 +00:00
connectors := newConnectors()
2018-09-03 14:14:51 +00:00
stopChan := make(chan struct{})
2018-08-31 12:56:36 +00:00
buf := make([]byte, 1024)
var discoveredMatcher osm.Matcher
2018-09-01 13:09:33 +00:00
var discoveredConnector connector
2018-08-31 12:56:36 +00:00
LOOP:
for _, _connector := range connectors {
conn, err := _connector.dial(targetPort)
if nil != err {
continue LOOP
}
2018-09-04 18:58:33 +00:00
if err := conn.SetReadDeadline(time.Now().Add(deadline)); nil != err {
2018-08-31 12:56:36 +00:00
continue LOOP
}
n, err := conn.Read(buf)
if nil != err {
n = 0
}
if 0 < n {
2018-09-18 01:24:54 +00:00
discoveredMatcher = hadlePrePacket(matchCtx, _connector, conn, osm.NewPacket(buf, n), limitedMatchers, stopChan)
2018-08-31 12:56:36 +00:00
} else {
conn.Close()
2018-09-18 01:24:54 +00:00
discoveredMatcher = hadlePostPacket(matchCtx, _connector, targetPort, limitedMatchers, stopChan)
2018-08-31 12:56:36 +00:00
}
if nil != discoveredMatcher {
2018-10-23 05:16:41 +00:00
if "HTTP" == discoveredMatcher.Key(matchCtx) {
2018-08-31 12:56:36 +00:00
hsm := matcher.GetHTTPSubMatchers()
2018-09-03 14:14:51 +00:00
if _discoveredMatcher := hadlePostPacket(matchCtx, _connector, targetPort, hsm, stopChan); _discoveredMatcher != nil {
2018-08-31 12:56:36 +00:00
discoveredMatcher = _discoveredMatcher
}
}
2018-09-01 13:09:33 +00:00
discoveredConnector = _connector
2018-08-31 12:56:36 +00:00
break LOOP
}
2018-09-03 10:33:20 +00:00
select {
case <-discoverySession.StopChan():
return nil
default:
}
2018-08-31 12:56:36 +00:00
}
if nil != discoveredMatcher {
2018-09-12 04:55:51 +00:00
s := omd.NewService(
targetPort,
discoveredConnector.metaCryptoType(),
2018-10-23 05:16:41 +00:00
discoveredMatcher.Key(matchCtx),
2018-09-12 04:55:51 +00:00
)
s.Name = discoveredMatcher.Name(matchCtx)
2018-10-23 05:16:41 +00:00
s.ServiceType = discoveredMatcher.Type(matchCtx)
2018-09-12 04:55:51 +00:00
s.ServiceVendor = discoveredMatcher.Vendor(matchCtx)
s.ServiceVersion = discoveredMatcher.Version(matchCtx)
s.DiscoveredDate = omu.NowPtr()
discoverySession.AddService(
2018-09-17 14:18:49 +00:00
omm.ToMetaDiscovererType(omm.MetaDiscovererTypeEnumTCPMatcher),
2018-09-12 04:55:51 +00:00
s,
2018-09-11 07:59:21 +00:00
matchCtx.GetAttributes(),
)
2018-09-13 10:20:58 +00:00
} else {
discoverySession.AddServiceUnknown(
2018-09-17 14:18:49 +00:00
omm.ToMetaDiscovererType(omm.MetaDiscovererTypeEnumTCPMatcher),
2018-09-13 10:20:58 +00:00
targetPort,
)
2018-08-31 12:56:36 +00:00
}
return nil
}
2018-09-18 01:24:54 +00:00
func hadlePrePacket(matchCtx *osm.MatchCtx, _connector connector, conn net.Conn, packet *osm.Packet, limitedMatchers []osm.Matcher, stopChan <-chan struct{}) osm.Matcher {
2018-08-31 12:56:36 +00:00
defer func() {
conn.Close()
}()
matchers := matcher.GetTCPMatchers(true)
2018-09-18 01:24:54 +00:00
if nil != limitedMatchers {
matchers = limitedMatchers
}
2018-08-31 12:56:36 +00:00
buf := make([]byte, 1024)
2018-10-23 06:02:07 +00:00
var (
discoveredMatcher osm.Matcher
packetCount int
_packet *osm.Packet
err error
nRead int
)
2018-08-31 12:56:36 +00:00
LOOP:
2018-09-03 14:26:43 +00:00
for _, _matcher := range matchers {
matchCtx.InitAttribute()
2018-10-23 06:02:07 +00:00
err = _matcher.Match(matchCtx, 0, packet)
if nil != err {
2018-08-31 12:56:36 +00:00
continue LOOP
}
2018-10-23 06:02:07 +00:00
packetCount = _matcher.PacketCount(matchCtx)
2018-08-31 12:56:36 +00:00
if 0 == packetCount {
2018-09-03 14:26:43 +00:00
return _matcher
2018-08-31 12:56:36 +00:00
}
INNER_LOOP:
for j := 0; j < packetCount; j++ {
2018-10-23 06:02:07 +00:00
_packet = _matcher.Packet(matchCtx, j)
2018-08-31 12:56:36 +00:00
2018-10-23 06:02:07 +00:00
err = conn.SetWriteDeadline(time.Now().Add(deadline))
if nil != err {
2018-08-31 12:56:36 +00:00
return nil
}
2018-10-23 06:02:07 +00:00
_, err = conn.Write(_packet.Buffer)
2018-08-31 12:56:36 +00:00
if nil != err {
return nil
}
2018-10-23 06:02:07 +00:00
err = conn.SetReadDeadline(time.Now().Add(deadline))
if nil != err {
2018-08-31 12:56:36 +00:00
return nil
}
2018-10-23 06:02:07 +00:00
nRead, err = conn.Read(buf)
2018-08-31 12:56:36 +00:00
if nil != err {
return nil
}
2018-10-23 06:02:07 +00:00
err = _matcher.Match(matchCtx, j+1, osm.NewPacket(buf, nRead))
if nil == err {
2018-09-03 14:26:43 +00:00
discoveredMatcher = _matcher
2018-08-31 12:56:36 +00:00
} else {
discoveredMatcher = nil
break INNER_LOOP
}
}
if nil != discoveredMatcher {
return discoveredMatcher
}
2018-09-03 14:14:51 +00:00
select {
case <-stopChan:
return nil
default:
}
2018-08-31 12:56:36 +00:00
}
return nil
}
2018-09-03 14:14:51 +00:00
func hadlePostPacket(matchCtx *osm.MatchCtx, _connector connector, targetPort *omd.Port, limitedMatchers []osm.Matcher, stopChan <-chan struct{}) osm.Matcher {
2018-08-31 12:56:36 +00:00
matchers := matcher.GetTCPMatchers(false)
if nil != limitedMatchers {
matchers = limitedMatchers
}
buf := make([]byte, 1024)
2018-10-23 06:02:07 +00:00
var (
discoveredMatcher osm.Matcher
packetCount int
_packet *osm.Packet
err error
conn net.Conn
nRead int
)
2018-08-31 12:56:36 +00:00
LOOP:
2018-09-03 14:26:43 +00:00
for _, _matcher := range matchers {
matchCtx.InitAttribute()
2018-10-23 06:02:07 +00:00
packetCount = _matcher.PacketCount(matchCtx)
2018-08-31 12:56:36 +00:00
if 0 == packetCount {
continue LOOP
}
2018-10-23 06:02:07 +00:00
conn, err = _connector.dial(targetPort)
2018-08-31 12:56:36 +00:00
if nil != err {
return nil
}
INNER_LOOP:
for j := 0; j < packetCount; j++ {
2018-10-23 06:02:07 +00:00
_packet = _matcher.Packet(matchCtx, j)
2018-08-31 12:56:36 +00:00
2018-10-23 06:02:07 +00:00
err = conn.SetWriteDeadline(time.Now().Add(deadline))
if nil != err {
2018-08-31 12:56:36 +00:00
break INNER_LOOP
}
2018-10-23 06:02:07 +00:00
_, err = conn.Write(_packet.Buffer)
2018-08-31 12:56:36 +00:00
if nil != err {
break INNER_LOOP
}
2018-10-23 06:02:07 +00:00
err = conn.SetReadDeadline(time.Now().Add(deadline))
if nil != err {
2018-08-31 12:56:36 +00:00
break INNER_LOOP
}
2018-10-23 06:02:07 +00:00
nRead, err = conn.Read(buf)
2018-08-31 12:56:36 +00:00
if nil != err {
2018-09-13 08:14:59 +00:00
// if !_matcher.HasResponse(matchCtx, j) {
// discoveredMatcher = _matcher
// }
2018-08-31 12:56:36 +00:00
break INNER_LOOP
}
2018-09-03 10:33:20 +00:00
// log.Printf("res: %s", string(buf[:n]))
2018-08-31 12:56:36 +00:00
2018-10-23 06:02:07 +00:00
err = _matcher.Match(matchCtx, j, osm.NewPacket(buf, nRead))
if err == nil {
2018-08-31 12:56:36 +00:00
if packetCount-1 == j {
2018-09-03 14:26:43 +00:00
discoveredMatcher = _matcher
2018-08-31 12:56:36 +00:00
break INNER_LOOP
}
} else {
break INNER_LOOP
}
}
conn.Close()
if nil != discoveredMatcher {
return discoveredMatcher
}
2018-09-03 14:14:51 +00:00
select {
case <-stopChan:
return nil
default:
}
2018-08-31 12:56:36 +00:00
}
2018-08-31 10:53:33 +00:00
return nil
}