scan added

This commit is contained in:
crusader 2018-08-31 21:56:36 +09:00
parent 56ed908c50
commit 92279d4944
6 changed files with 437 additions and 4 deletions

View File

@ -7,6 +7,10 @@ import (
) )
func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error { func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
if nil == targetHost || nil == discoverySession.DiscoverPort() {
return nil
}
metaIPTypeEnum := omm.ToMetaIPTypeEnum(discoverySession.Zone().MetaIPType) metaIPTypeEnum := omm.ToMetaIPTypeEnum(discoverySession.Zone().MetaIPType)
switch metaIPTypeEnum { switch metaIPTypeEnum {

View File

@ -19,10 +19,6 @@ import (
) )
func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error { func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
if nil == targetHost || nil == discoverySession.DiscoverPort() {
return nil
}
ps, err := pcap.RetainScanner(targetHost.Zone) ps, err := pcap.RetainScanner(targetHost.Zone)
if nil != err { if nil != err {
return fmt.Errorf("Discovery: Cannot retain pcap instance %v", err) return fmt.Errorf("Discovery: Cannot retain pcap instance %v", err)

View File

@ -0,0 +1,66 @@
package service
import (
"crypto/tls"
"net"
"time"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
)
type connector interface {
dial(targetPort *omd.Port) (net.Conn, error)
}
type noneConnector struct {
metaCryptoType *omm.MetaCryptoType
}
func (c *noneConnector) dial(targetPort *omd.Port) (net.Conn, error) {
addr := net.JoinHostPort(targetPort.Host.Address, targetPort.PortNumber.String())
conn, err := net.DialTimeout("tcp", addr, time.Duration(3)*time.Second)
if err != nil {
return nil, err
}
return conn, err
}
type tlsConnector struct {
metaCryptoType *omm.MetaCryptoType
}
func (c *tlsConnector) dial(targetPort *omd.Port) (net.Conn, error) {
addr := net.JoinHostPort(targetPort.Host.Address, targetPort.PortNumber.String())
dialer := &net.Dialer{
Timeout: 3 * time.Second,
}
conn, err := tls.DialWithDialer(
dialer,
"tcp",
addr,
&tls.Config{
InsecureSkipVerify: true,
ServerName: targetPort.Host.Address,
},
)
if err != nil {
return nil, err
}
return conn, err
}
func newConnectors() []connector {
return []connector{
&noneConnector{
metaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE),
},
&tlsConnector{
metaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumTLS),
},
}
}

View File

@ -1,11 +1,192 @@
package service package service
import ( import (
"fmt"
"log"
"net"
"time"
omd "git.loafle.net/overflow/model/discovery" omd "git.loafle.net/overflow/model/discovery"
osm "git.loafle.net/overflow/service_matcher-go"
ouej "git.loafle.net/overflow/util-go/encoding/json"
"git.loafle.net/overflow_scanner/probe/discovery/session" "git.loafle.net/overflow_scanner/probe/discovery/session"
"git.loafle.net/overflow_scanner/probe/internal/matcher"
) )
func scanTCP(discoverySession session.DiscoverySession, targetPort *omd.Port) error { func scanTCP(discoverySession session.DiscoverySession, targetPort *omd.Port) error {
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)
}
info := osm.NewMatchInfo(hostAddress, portNumber)
connectors := newConnectors()
buf := make([]byte, 1024)
var discoveredMatcher osm.Matcher
LOOP:
for _, _connector := range connectors {
conn, err := _connector.dial(targetPort)
if nil != err {
continue LOOP
}
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
continue LOOP
}
n, err := conn.Read(buf)
if nil != err {
n = 0
}
if 0 < n {
discoveredMatcher = hadlePrePacket(info, _connector, conn, osm.NewPacket(buf, n))
} else {
conn.Close()
discoveredMatcher = hadlePostPacket(info, _connector, targetPort, nil)
}
if nil != discoveredMatcher {
if "HTTP" == discoveredMatcher.Key() {
hsm := matcher.GetHTTPSubMatchers()
if _discoveredMatcher := hadlePostPacket(info, _connector, targetPort, hsm); _discoveredMatcher != nil {
discoveredMatcher = _discoveredMatcher
}
}
break LOOP
}
}
if nil != discoveredMatcher {
log.Printf("discovered matcher: %s(%s) %v", discoveredMatcher.Name(), discoveredMatcher.Key(), discoveredMatcher)
}
return nil
}
func hadlePrePacket(info osm.MatchInfo, _connector connector, conn net.Conn, packet *osm.Packet) osm.Matcher {
defer func() {
conn.Close()
}()
matchers := matcher.GetTCPMatchers(true)
buf := make([]byte, 1024)
var discoveredMatcher osm.Matcher
LOOP:
for _, matcher := range matchers {
if err := matcher.Match(info, 0, packet); err != nil {
continue LOOP
}
packetCount := matcher.PacketCount()
if 0 == packetCount {
return matcher
}
INNER_LOOP:
for j := 0; j < packetCount; j++ {
_packet := matcher.Packet(j)
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
return nil
}
_, err := conn.Write(_packet.Buffer)
if nil != err {
return nil
}
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
return nil
}
n, err := conn.Read(buf)
if nil != err {
return nil
}
if err := matcher.Match(info, j+1, osm.NewPacket(buf, n)); nil == err {
discoveredMatcher = matcher
} else {
discoveredMatcher = nil
break INNER_LOOP
}
}
if nil != discoveredMatcher {
return discoveredMatcher
}
}
return nil
}
func hadlePostPacket(info osm.MatchInfo, _connector connector, targetPort *omd.Port, limitedMatchers []osm.Matcher) osm.Matcher {
matchers := matcher.GetTCPMatchers(false)
if nil != limitedMatchers {
matchers = limitedMatchers
}
buf := make([]byte, 1024)
var discoveredMatcher osm.Matcher
LOOP:
for _, matcher := range matchers {
packetCount := matcher.PacketCount()
if 0 == packetCount {
continue LOOP
}
conn, err := _connector.dial(targetPort)
if nil != err {
return nil
}
INNER_LOOP:
for j := 0; j < packetCount; j++ {
_packet := matcher.Packet(j)
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
break INNER_LOOP
}
_, err := conn.Write(_packet.Buffer)
if nil != err {
break INNER_LOOP
}
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
break INNER_LOOP
}
n, err := conn.Read(buf)
if nil != err {
if !matcher.HasResponse(j) {
discoveredMatcher = matcher
}
break INNER_LOOP
}
// log.Printf("res: %s", string(buf[:n]))
if err := matcher.Match(info, j+1, osm.NewPacket(buf, n)); err == nil {
if packetCount-1 == j {
discoveredMatcher = matcher
break INNER_LOOP
}
} else {
break INNER_LOOP
}
}
conn.Close()
if nil != discoveredMatcher {
return discoveredMatcher
}
}
return nil return nil
} }

View File

@ -0,0 +1,182 @@
package service
import (
"encoding/json"
"net"
"reflect"
"testing"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
osm "git.loafle.net/overflow/service_matcher-go"
"git.loafle.net/overflow_scanner/probe/discovery/session"
"git.loafle.net/overflow_scanner/probe/discovery/types"
)
func Test_scanTCP(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: 1024,
IncludeTCP: true,
DiscoverService: &omd.DiscoverService{},
},
},
)
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(),
}
targetPort80 := &omd.Port{
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
PortNumber: json.Number("80"),
Host: targetHost,
}
targetPort139 := &omd.Port{
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
PortNumber: json.Number("139"),
Host: targetHost,
}
targetPort443 := &omd.Port{
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
PortNumber: json.Number("443"),
Host: targetHost,
}
targetPort445 := &omd.Port{
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
PortNumber: json.Number("445"),
Host: targetHost,
}
targetPort548 := &omd.Port{
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
PortNumber: json.Number("548"),
Host: targetHost,
}
type args struct {
discoverySession session.DiscoverySession
targetPort *omd.Port
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "80",
args: args{
discoverySession: s,
targetPort: targetPort80,
},
wantErr: false,
},
{
name: "139",
args: args{
discoverySession: s,
targetPort: targetPort139,
},
wantErr: false,
},
{
name: "443",
args: args{
discoverySession: s,
targetPort: targetPort443,
},
wantErr: false,
},
{
name: "445",
args: args{
discoverySession: s,
targetPort: targetPort445,
},
wantErr: false,
},
{
name: "548",
args: args{
discoverySession: s,
targetPort: targetPort548,
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := scanTCP(tt.args.discoverySession, tt.args.targetPort); (err != nil) != tt.wantErr {
t.Errorf("scanTCP() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_hadlePrePacket(t *testing.T) {
type args struct {
info osm.MatchInfo
_connector connector
conn net.Conn
packet *osm.Packet
}
tests := []struct {
name string
args args
want osm.Matcher
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := hadlePrePacket(tt.args.info, tt.args._connector, tt.args.conn, tt.args.packet); !reflect.DeepEqual(got, tt.want) {
t.Errorf("hadlePrePacket() = %v, want %v", got, tt.want)
}
})
}
}
func Test_hadlePostPacket(t *testing.T) {
type args struct {
info osm.MatchInfo
_connector connector
targetPort *omd.Port
limitedMatchers []osm.Matcher
}
tests := []struct {
name string
args args
want osm.Matcher
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := hadlePostPacket(tt.args.info, tt.args._connector, tt.args.targetPort, tt.args.limitedMatchers); !reflect.DeepEqual(got, tt.want) {
t.Errorf("hadlePostPacket() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -7,6 +7,10 @@ import (
) )
func Scan(discoverySession session.DiscoverySession, targetPort *omd.Port) error { func Scan(discoverySession session.DiscoverySession, targetPort *omd.Port) error {
if nil == targetPort || nil == discoverySession.DiscoverService() {
return nil
}
metaPortTypeEnum := omm.ToMetaPortTypeEnum(targetPort.MetaPortType) metaPortTypeEnum := omm.ToMetaPortTypeEnum(targetPort.MetaPortType)
switch metaPortTypeEnum { switch metaPortTypeEnum {