This commit is contained in:
jackdaw@loafle.com 2017-04-10 20:14:12 +09:00
commit eb02693cf5
57 changed files with 5525 additions and 0 deletions

61
.gitignore vendored Normal file
View File

@ -0,0 +1,61 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Go template
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/

View File

@ -0,0 +1,342 @@
package activedirectory
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
AD_MESSAGE_ID = 0x99
AD_MESSAGE_ID_QUIT = 0x89
LDAP_VERSION3 = 3
LDAP_SUCCESS = 0x00
LDAP_REQ_BIND = 0x60
LDAP_RES_SEARCH_ENTRY = 0x64
LDAP_REQ_UNBIND = 0x42
LDAP_REQ_SEARCH = 0x63
LDAP_SCOPE_BASE = 0x00
LDAP_DEREF_NEVER = 0x00
LDAP_FILTER_PRESENT = 0x87
LDAP_RES_BIND = 0x61
LDAP_AUTH_SIMPLE = 0x80
AD_TYPE_STR = "supportedCapabilities"
)
type AD_SENDaaa struct {
DefaultCode uint8
PackLenFlag uint8
PacketLen uint32
NextType1 uint8
NextTypeLength1 uint8
MessageId uint32
ProtocolOp uint8
PtLenFlag uint8
PtPacketLen uint32
NextType2 uint8
NextTypeLength2 uint8
Version uint8
NextType3 uint8
NextTypeLength3 uint8
Auth uint8
AuthLength uint8
}
type AD_SEND struct {
DefaultCode uint8
PackLenFlag uint8
PacketLen uint32
NextType1 uint8
NextType1Len uint8
MessageId uint32
ProtocolOp uint8
PtPackLenFlag uint8
PtPacketLen uint32
NextType2 uint8
NextType2Len uint8
NextType3 uint8
NextType3Len uint8
Scope uint8
NextType4 uint8
NextType4Len uint8
DerefAliases uint8
NextType5 uint8
NextType5Len uint8
SizeLimit uint8
NextType6 uint8
NextType6Len uint8
TimeLimit uint8
NextType7 uint8
NextType7Len uint8
TypesOnly uint8
Filter1 uint8
PresentLen uint8
Present [11]byte
DefaultCode2 uint8
Pack2LenFlag uint8
Packet2Len uint32
UnknwonCode8 uint8
ItemLength uint8
AttributeDescription [21]byte
}
type AD_QUIT struct {
DefaultCode uint8
PackLenFlag uint8
PacketLength uint32
NextType1 uint8
NextTypeLength1 uint8
MessageId uint32
ProtocolOp uint8
PtLenFlag uint8
PtPacketLen uint32
}
type AD_RECV struct {
DefaultCode uint8
PackLenFlag uint8
PacketLength uint32
NextType1 uint8
NextType1Len uint8
MessageId uint16
ProtocolOp uint8
PtPackLenFlag uint8
PtPacketLen uint32
NextType2 uint8
NextType2Len uint8
UnknwonCode21 uint8
UnknwonCode22 uint8
UnknwonCode23 uint8
UnknwonCode24 uint8
UnknwonCode25 uint8
UnknwonCode26 uint8
UnknwonCode31 uint8
UnknwonCode32 uint8
UnknwonCode33 uint8
UnknwonCode34 uint8
UnknwonCode35 uint8
UnknwonCode36 uint8
UnknwonCode37 uint8
TypeLength uint8
}
type ActiveDirectoryMatcher struct {
sendPackets []*packet.Packet
}
func (ad *ActiveDirectoryMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
buf := new(bytes.Buffer)
buf.Write(packet.Buffer)
adRecv := AD_RECV{}
binary.Read(buf, binary.BigEndian, &adRecv)
if adRecv.MessageId != AD_MESSAGE_ID {
return false
}
if adRecv.ProtocolOp != LDAP_RES_SEARCH_ENTRY {
return false
}
///AD_TYPE_STR
//
//if(packet->readCount_ < sizeof(AD_RECV) + recv->typeLength) {
// return false;
//}
//char* type = new char[recv->typeLength];
//memcpy(type, packet->buffer_+sizeof(AD_RECV), recv->typeLength);
//std::string typeStr = type;
//
//delete[] type;
//if(typeStr.compare(AD_TYPE_STR) != 0) {
//return false;
//}
return true
}
func (ad *ActiveDirectoryMatcher) PacketCount() int {
return len(ad.sendPackets)
}
func (ad *ActiveDirectoryMatcher) Packet(index int) *packet.Packet {
return ad.sendPackets[index]
}
func (ad *ActiveDirectoryMatcher) ServiceName() string {
return "ActiveDirectory"
}
func (ad *ActiveDirectoryMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (ad *ActiveDirectoryMatcher) IsNoResponse(index int) bool {
if index == 1 {
return true
}
return false
}
func (ad *ActiveDirectoryMatcher) IsPrePacket() bool {
return false
}
func NewActiveDirectoryMatcher() *ActiveDirectoryMatcher {
ls := AD_SEND{
DefaultCode: 0x30,
PackLenFlag: 0x84,
PacketLen: 0x47,
NextType1: 0x02,
NextType1Len: 0x04,
MessageId: AD_MESSAGE_ID,
ProtocolOp: LDAP_REQ_SEARCH,
PtPackLenFlag: 0x84,
PtPacketLen: 0x3b,
NextType2: 0x04,
NextType2Len: 0x00,
NextType3: 0x0a,
NextType3Len: 0x01,
Scope: LDAP_SCOPE_BASE,
NextType4: 0x0a,
NextType4Len: 0x01,
DerefAliases: LDAP_DEREF_NEVER,
NextType5: 0x02,
NextType5Len: 0x01,
SizeLimit: 0,
NextType6: 0x02,
NextType6Len: 0x01,
TimeLimit: 0x78,
NextType7: 0x01,
NextType7Len: 0x01,
TypesOnly: 0,
Filter1: LDAP_FILTER_PRESENT,
PresentLen: 0x0b,
//Present :0000,
DefaultCode2: 0x30,
Pack2LenFlag: 0x84,
Packet2Len: 0x17,
UnknwonCode8: 0x04,
ItemLength: 0x15,
//AttributeDescription:,
}
copy(ls.Present[:], "objectclass")
copy(ls.AttributeDescription[:], AD_TYPE_STR)
mCache := new(bytes.Buffer)
binary.Write(mCache, binary.BigEndian, ls)
sendByte1 := mCache.Bytes()
adm := ActiveDirectoryMatcher{
//sendPackets: make([][]byte, 2),
}
pp := packet.NewPacket(sendByte1, len(sendByte1))
adm.sendPackets = append(adm.sendPackets, pp)
aq := AD_QUIT{
DefaultCode: 0x30,
PackLenFlag: 0x84,
PacketLength: 0x0c,
NextType1: 0x02,
NextTypeLength1: 0x04,
MessageId: AD_MESSAGE_ID_QUIT,
ProtocolOp: LDAP_REQ_UNBIND,
PtLenFlag: 0x84,
PtPacketLen: 0x00,
}
lqBuffer := new(bytes.Buffer)
binary.Write(lqBuffer, binary.BigEndian, aq)
quBytes := lqBuffer.Bytes()
pp2 := packet.NewPacket(quBytes, len(quBytes))
adm.sendPackets = append(adm.sendPackets, pp2)
return &adm
}

View File

@ -0,0 +1,77 @@
package activedirectory
import (
"crypto/tls"
"net"
"testing"
)
func TestADNor(t *testing.T) {
client, err := net.Dial("tcp", "192.168.1.1:389")
if err != nil {
t.Log(err)
}
defer client.Close()
dDRun(client, t)
}
func TestADTLS(t *testing.T) {
conn, err := tls.Dial(
"tcp",
"192.168.1.1:636",
&tls.Config{
InsecureSkipVerify: true,
ServerName: "192.168.1.1",
},
)
if err != nil {
t.Log(err)
return
}
defer conn.Close()
dDRun(conn, t)
}
func dDRun(client net.Conn, t *testing.T) {
//lm := NewActiveDirectoryMatcher()
//
//port := types.NewPort("389", types.NewHost("192.168.1.1"), types.TYPE_TCP)
//
//var ipport string
//ipport = port.Host.Ip + ":" + string(port.Port)
//
//fmt.Println(ipport)
//
//fmt.Println(lm.PacketCount())
//
//for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// fmt.Println(pack)
//
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 1024)
//
// read, _ := client.Read(bytes)
//
// fmt.Println(bytes)
//
// b := lm.Match(ii, packet.NewPacket(bytes, read), scanInfo)
//
// if b {
// fmt.Println("Good")
// }
//
//}
//
//t.Log(scanInfo)
}

View File

@ -0,0 +1,105 @@
package cassandra
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
COMPRESSION = "COMPRESSION"
CQL_VERSION = "CQL_VERSION"
)
type cassandra struct {
Version uint8
Flags uint8
Stream uint16
Opcode uint8
Length uint32
}
type CassandraMatcher struct {
packets []*packet.Packet
}
func NewCassandraMatcher() *CassandraMatcher {
cassMatcher := &CassandraMatcher{}
c := cassandra{
Version: 4,
Flags: 0,
Stream: 0,
Opcode: 5,
Length: 0,
}
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, c)
cassMatcher.packets = append(cassMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return cassMatcher
}
func (t *CassandraMatcher) ServiceName() string {
return "Cassandra"
}
func (t *CassandraMatcher) PacketCount() int {
return len(t.packets)
}
func (t *CassandraMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *CassandraMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *CassandraMatcher) IsNoResponse(index int) bool {
return false
}
func (t *CassandraMatcher) IsPrePacket() bool {
return false
}
func (t *CassandraMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
c := cassandra{}
if err := binary.Read(reader, binary.BigEndian, &c); err != nil {
return false
}
if c.Version != 0x84 {
return false
}
if c.Flags != 0x00 {
return false
}
if c.Stream != 0x00 {
return false
}
if c.Opcode != 0x06 {
return false
}
var itemcount uint16
if binary.Read(reader, binary.BigEndian, &itemcount) != nil {
return false
}
if itemcount != 0 && itemcount != 2 {
return false
}
return true
}

View File

@ -0,0 +1,74 @@
package cassandra
//
//import (
// "crypto/tls"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestCassandra(t *testing.T) {
//
// m := NewCassandraMatcher()
//
// conn, err := net.Dial("tcp", "192.168.1.104:9042")
// if err != nil {
// t.Error(err)
// return
// }
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("Cassandra found")
// return
// }
//
// t.Error("Cassandra not found")
// }
//
//}
//
//func TestCassandraTLS(t *testing.T) {
//
// m := NewCassandraMatcher()
//
// conn, err := tls.Dial(
// "tcp",
// "192.168.1.104:9042",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.104",
// },
// )
// if err != nil {
// t.Fatal(err)
// }
//
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("Cassandra found")
// return
// }
//
// t.Error("Cassandra not found")
// }
//
//}

188
matcher/dhcp/dhcp.go Normal file
View File

@ -0,0 +1,188 @@
package dhcp
//
//import (
// "bytes"
// "encoding/binary"
// "fmt"
// log "github.com/cihub/seelog"
// "loafle.com/overflow/commons_go/matcher"
// "net"
// "time"
//)
//
//const (
// MAGIC_COOKIE uint32 = 0x63825363
// OPT_CODE_SERVER_IDENTIFIER uint8 = 54
// OPT_CODE_SUBNET_MASK uint8 = 1
// OPT_CODE_ROUTER uint8 = 3
// OPT_CODE_DNS uint8 = 6
//)
//
//type dhcpDiscover struct {
// MsgType byte
// HwType byte
// HwAddrLen byte
// Hops byte
// Xid uint32
// Secs uint16
// BootpFlags uint16
// ClientIp uint32
// YourIp uint32
// NextServerIp uint32
// RelayAgentIp uint32
// ClientMacAddr [6]byte
// ClientHwAddrPadding [10]byte
// ServerHostName [64]byte
// BootFileName [128]byte
// MagicCookie uint32
// Mtype byte
// MtypeLen byte
// MtypeVal byte
// Opts [200]byte
// End byte
// Padding [16]byte
//}
//
//func DiscoverDHCP(zone *types.DiscoveryZone) {
// err := sendDHCPDiscovery()
// if err != nil {
// log.Error(err)
// return
// }
// recvDHCPOffer(zone)
//}
//
//func sendDHCPDiscovery() error {
// dhcp := dhcpDiscover{
// MsgType: 0x01,
// HwType: 0x01,
// HwAddrLen: 0x06,
// Hops: 0x00,
// Xid: 0x00000000,
// Secs: 0x0000,
// ClientIp: 0x00000000,
// YourIp: 0x00000000,
// NextServerIp: 0x00000000,
// RelayAgentIp: 0x00000000,
// MagicCookie: MAGIC_COOKIE,
// Mtype: 0x35,
// MtypeLen: 0x01,
// MtypeVal: 0x01,
// End: 0xff,
// }
//
// var flag uint16 = 0
// dhcp.BootpFlags = ^flag // flag = unicast , ^flag = broadcast
//
// //TODO : getting mac addr from zone
// dhcp.ClientMacAddr[0] = 0x50
// dhcp.ClientMacAddr[1] = 0xe5
// dhcp.ClientMacAddr[2] = 0x49
// dhcp.ClientMacAddr[3] = 0x46
// dhcp.ClientMacAddr[4] = 0x93
// dhcp.ClientMacAddr[5] = 0x28
//
// writer := new(bytes.Buffer)
// binary.Write(writer, binary.BigEndian, dhcp)
// conn, err := net.Dial("udp", "255.255.255.255:67")
// if err != nil {
// return err
// }
// conn.Write(writer.Bytes())
// defer conn.Close()
//
// return nil
//}
//
//func recvDHCPOffer(zone *types.DiscoveryZone) {
//
// socket, err := net.ListenUDP("udp4", &net.UDPAddr{
// IP: net.IPv4(255, 255, 255, 255),
// Port: 68,
// })
// if err != nil {
// log.Error(err)
// return
// }
// err = socket.SetDeadline(time.Now().Add(3 * time.Second))
// if err != nil {
// log.Error(err)
// return
// }
//
// buf := make([]byte, 4096)
// n, _, err := socket.ReadFromUDP(buf)
// if err != nil {
// log.Error(err)
// return
// }
// if n <= 0 {
// log.Error("No DHCP offer.")
// return
// }
//
// offer := dhcpDiscover{}
//
// reader := new(bytes.Buffer)
// reader.Write(buf)
// if err := binary.Read(reader, binary.BigEndian, &offer); err != nil {
// log.Error(err)
// return
// }
// if offer.MagicCookie != MAGIC_COOKIE {
// log.Error("Not a DHCP packet.")
// return
// }
//
// //option searching
// r := new(bytes.Buffer)
// r.Write(offer.Opts[:])
//
// for i := 0; i < r.Len(); i++ {
// v := r.Next(1)[0]
//
// if v == OPT_CODE_SUBNET_MASK && r.Next(1)[0] == 4 {
// ipStr := byteToIpString(r.Next(4))
// log.Infof("SUBNET MASK: %s", ipStr)
// }
//
// if v == OPT_CODE_ROUTER && r.Next(1)[0] == 4 {
// ipStr := byteToIpString(r.Next(4))
// log.Infof("ROUTER: %s", ipStr)
// }
//
// if v == OPT_CODE_DNS {
// len := r.Next(1)[0]
// var dns []string = make([]string, 0)
// var ipStr string
// ipStr = byteToIpString(r.Next(4))
// dns = append(dns, ipStr)
// if len == 8 {
// ipStr = byteToIpString(r.Next(4))
// dns = append(dns, ipStr)
// }
// log.Infof("DNS", dns)
// }
//
// if v == OPT_CODE_SERVER_IDENTIFIER && r.Next(1)[0] == 4 {
// ipStr := byteToIpString(r.Next(4))
// log.Infof("DHCP SERVER: %s", ipStr)
// }
// }
//
//}
//
//func byteToIpString(b []byte) string {
// var ipStr string
// len := len(b)
// for i := 0; i < len; i++ {
// v := b[i]
// ipStr += fmt.Sprintf("%d", v)
// if i < len-1 {
// ipStr += "."
// }
// }
//
// return ipStr
//}

12
matcher/dhcp/dhcp_test.go Normal file
View File

@ -0,0 +1,12 @@
package dhcp
//
//import (
// "loafle.com/overflow/collector/core/scan/zone"
// "testing"
//)
//
//func TestDHCP(t *testing.T) {
// zone := zone.NewZone()
// DiscoverDHCP(zone)
//}

151
matcher/dns/dns.go Normal file
View File

@ -0,0 +1,151 @@
package dns
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
type Dns_frame_header struct {
Transaction_id uint16
Flags uint16
Questions uint16
Answer_rrs uint16
Authority_rrs uint16
Additional_rrs uint16
}
type Dns_query_section struct {
Name uint8
Query_type uint16
Class_type uint16
}
type Dns_authority_section struct {
Name uint8
Auth_type uint16
Class_type uint16
Time_to_live uint32
Data_length uint16
Primary_name_server [20]uint8
Responsible_authority_mailbox [24]uint8
Serial_number uint32
Refresh_interval uint32
Retry_interval uint32
Expire_limit uint32
Minium_ttl uint32
}
type DNSMatcher struct {
packets []*packet.Packet
}
func NewDnsMatcher() *DNSMatcher {
m := &DNSMatcher{}
header := Dns_frame_header{
Transaction_id: 0x2a88,
Flags: 0x0100,
Questions: 1,
Answer_rrs: 0,
Authority_rrs: 0,
Additional_rrs: 0,
}
query := Dns_query_section{
Name: 0,
Query_type: 1,
Class_type: 1,
}
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, header)
binary.Write(buf, binary.BigEndian, query)
m.packets = append(m.packets, packet.NewPacket(buf.Bytes(), buf.Len()))
return m
}
func (t *DNSMatcher) ServiceName() string {
return "DNS"
}
func (t *DNSMatcher) PacketCount() int {
return len(t.packets)
}
func (t *DNSMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *DNSMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *DNSMatcher) IsNoResponse(index int) bool {
return false
}
func (t *DNSMatcher) IsPrePacket() bool {
return true
}
func (t *DNSMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
if packet.Len <= 0 {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
h := Dns_frame_header{}
if err := binary.Read(reader, binary.BigEndian, &h); err != nil {
return false
}
if h.Transaction_id != 0x2a88 {
return false
}
if h.Flags != 0x8180 && h.Flags != 0x8182 {
return false
}
if h.Questions != 1 {
return false
}
if h.Answer_rrs != 0 {
return false
}
if h.Authority_rrs != 0 && h.Authority_rrs != 1 {
return false
}
if h.Additional_rrs != 0 && h.Additional_rrs != 1 {
return false
}
q := Dns_query_section{}
if err := binary.Read(reader, binary.BigEndian, &q); err != nil {
return false
}
if q.Name != 0 {
return false
}
if q.Query_type != 1 {
return false
}
if q.Class_type != 1 {
return false
}
return true
}
func (t *DNSMatcher) IsSend(port int) bool {
if port == 53 {
return true
}
return false
}

33
matcher/dns/dns_test.go Normal file
View File

@ -0,0 +1,33 @@
package dns
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestDns(t *testing.T) {
// m := NewDnsMatcher()
//
// conn, _ := net.Dial("udp", "192.168.1.215:53")
//
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
// if m.IsSend(53) != true {
// t.Error("not port")
// }
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("dns found")
// return
// }
//
// t.Error("dns not found")
// }
//}

142
matcher/ftp/ftp.go Normal file
View File

@ -0,0 +1,142 @@
package ftp
import (
log "github.com/cihub/seelog"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
// FTP Status codes, defined in RFC 959
const (
statusReadyServer = "120"
statusOK = "200"
statusNewConnectOK = "220"
statusSystemNameOK = "215"
statusCloseConnect = "221"
statusUnkownCMD = "202"
statusTlsUseOK = "234"
statusCloseControlConnect = "421"
statusSyntaxErr = "500"
statusParamSyntaxErr = "501"
statusNotUseCMD = "502"
statusIncorrectCMD = "503"
statusTlsNotUse = "534"
statusNeedUserId = "332"
)
type FTPMatcher struct {
sendPackets []*packet.Packet
isFtps bool
}
func (ftp *FTPMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
result := false
if packet == nil || packet.Buffer == nil || packet.Len == 0 {
log.Error("Packet nil")
return result
}
str := string(packet.Buffer)
//fmt.Println(str)
code := str[:3]
if index == 0 {
switch code {
case statusNewConnectOK, statusReadyServer:
//fmt.Println(code)
result = true
break
}
} else if index == 1 {
switch code {
case statusSystemNameOK, statusSyntaxErr, statusParamSyntaxErr, statusNotUseCMD:
//fmt.Println(code)
result = true
break
}
} else if index == 2 {
switch code {
case statusIncorrectCMD, statusParamSyntaxErr, statusNotUseCMD, statusNeedUserId:
//fmt.Println(code)
result = true
break
}
} else if index == 3 {
switch code {
case statusCloseConnect, statusSyntaxErr:
//fmt.Println(code)
result = true
break
}
}
if index == 3 && result == true {
var err error
var isfs bool
//fmt.Println(info.Port.Host.Ip, info.Port.Port)
isfs, err = StartCheckFTPS(info.GetIP(), info.GetPort())
if isfs && err == nil {
ftp.isFtps = isfs
} else if err != nil {
log.Warn("FTPS Check Error : ", err.Error())
}
}
return result
}
func (ftp *FTPMatcher) PacketCount() int {
return len(ftp.sendPackets)
}
func (ftp *FTPMatcher) Packet(index int) *packet.Packet {
return ftp.sendPackets[index]
}
func (ftp *FTPMatcher) ServiceName() string {
re := ""
if ftp.isFtps {
re = "FTPS"
} else {
re = "FTP"
}
return re
}
func (ftp *FTPMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (ftp *FTPMatcher) IsNoResponse(index int) bool {
return false
}
func (ftp *FTPMatcher) IsPrePacket() bool {
return true
}
func NewFTPMatcher() *FTPMatcher {
ftm := FTPMatcher{}
sysStr := "SYST\r\n"
systByte := make([]byte, len(sysStr))
copy(systByte[:], sysStr)
ftm.sendPackets = append(ftm.sendPackets, packet.NewPacket(systByte, len(sysStr)))
passStr := "PASS \r\n"
passByte := make([]byte, len(passStr))
copy(passByte[:], passStr)
ftm.sendPackets = append(ftm.sendPackets, packet.NewPacket(passByte, len(passStr)))
quitStr := "QUIT\r\n"
quitByte := make([]byte, len(quitStr))
copy(quitByte[:], quitStr)
ftm.sendPackets = append(ftm.sendPackets, packet.NewPacket(quitByte, len(quitStr)))
return &ftm
}

235
matcher/ftp/ftp_test.go Normal file
View File

@ -0,0 +1,235 @@
package ftp
import (
"fmt"
"testing"
log "github.com/cihub/seelog"
"loafle.com/overflow/collector/discovery/scan/matcher/packet"
"loafle.com/overflow/collector/discovery/scan/matcher/scaninfo"
"loafle.com/overflow/collector/discovery/types"
"net"
)
//type FTP struct {
// conn net.Conn
// addr string
//
// reader *bufio.Reader
// writer *bufio.Writer
//}
//
//func (ftp *FTP) Close() {
// ftp.conn.Close()
//}
//
//func Connect(addr string) (*FTP, error) {
// var err error
// var conn net.Conn
//
// if conn, err = net.Dial("tcp", addr); err != nil {
// return nil, err
// }
//
// writer := bufio.NewWriter(conn)
// reader := bufio.NewReader(conn)
//
// obj := &FTP{
// conn:conn,
// addr:addr,
// reader:reader,
// writer:writer,
// }
// recv, _ := obj.receive()
//
// fmt.Println(recv)
//
// return obj, nil
//
//}
//
//func (ftp *FTP) receive() (string, error) {
// line, err := ftp.receiveLine()
//
// if err != nil {
// return line, err
// }
//
// fmt.Println("len : ", len(line))
// fmt.Println("line[3] :", line[3])
// //
// //if (len(line) >= 4) && (line[3] == '-') {
// // closingCode := line[:3] + " "
// //
// // for {
// // str, err := ftp.receiveLine()
// // fmt.Println("str pre: ", str)
// // line = line + str
// // fmt.Println("str after: ", line)
// // if err != nil {
// // return line, err
// // }
// //
// // if len(str) < 4 {
// // fmt.Println("Uncorrectly terminated response")
// // }else {
// // if str[:4] == closingCode {
// // break
// // }
// // }
// // }
// //}
//
// ftp.ReadAndDiscard()
//
// fmt.Println("receive line: ", line)
// return line, err
//}
//
//func (ftp *FTP) ReadAndDiscard() (int, error) {
// var i int
// bufferSize := ftp.reader.Buffered()
//
// for i = 0; i < bufferSize ; i++ {
// if _, err := ftp.reader.ReadByte(); err != nil {
// return i, err
// }
// }
//
// return i, nil
//}
//
//func (ftp *FTP) send(command string, arguments ...interface{}) error {
//
// command = fmt.Sprintf(command)
// command += "\r\n"
//
// if _, err := ftp.writer.WriteString(command); err != nil {
// return err
// }
//
// if err := ftp.writer.Flush(); err != nil {
// return err
// }
//
// return nil
//}
//
//func (ftp *FTP) cmd(expects string, command string, args ...interface{}) (line string, err error) {
//
// if err = ftp.send(command, args); err != nil {
// return
// }
//
// if line, err = ftp.receive(); err != nil {
// return
// }
//
//
// if !strings.HasPrefix(line, expects) {
// err = errors.New(line)
// return
// }
//
// return
//}
//
//func (ftp *FTP) receiveLine() (string, error) {
// line, err := ftp.reader.ReadString('\n')
//
// log.Printf("< %s", line)
//
// return line, err
//}
//
//func (ftp *FTP) Syst() (line string, err error) {
// if err := ftp.send("SYST"); err != nil {
// return "", err
// }
//
// if line, err = ftp.receive(); err != nil {
// return
// }
//
// if !strings.HasPrefix(line, "215") {
// err = errors.New(line)
// return
// }
//
// return strings.SplitN(strings.TrimSpace(line), " ", 2)[1], nil
//}
//func TestFtp(t *testing.T) {
// var err error
// var ftp *FTP
// //var f *FTPMatcher
//
// if ftp, err = Connect("192.168.1.202:21"); err != nil {
// panic(err)
// }
//
// //f.Match(0, nil,nil)
// ftp.Syst()
// ftp.cmd("503","PASS ")
// ftp.cmd("221","QUIT")
// defer ftp.Close()
//}
func TestMatchFTP(t *testing.T) {
ftm := NewFTPMatcher()
//fmt.Println(ftm)
//fmt.Println(ftm.sendPackets[0])
//log.LoadLogConfig("../../../../../../../../bin/log.xml")
//defer log.Flush()
port := types.NewPort("21", types.NewHost("192.168.1.202"), types.TYPE_TCP)
info := scaninfo.NewServiceScanInfo(port)
var ipport string
ipport = port.Host.Ip + ":" + string(port.Port)
log.Debug(ipport)
client, _ := net.Dial("tcp", ipport)
defer client.Close()
//reader := bufio.NewReader(client)
//writer := bufio.NewWriter(client)
fmt.Println(ftm.PacketCount())
//fmt.Println(reader.ReadString('\n'))
bytes := make([]byte, 512)
le, _ := client.Read(bytes)
fmt.Println(bytes)
b := ftm.Match(0, packet.NewPacket(bytes, le), nil)
fmt.Println(b)
for ii := 0; ii < ftm.PacketCount(); ii++ {
pack := ftm.Packet(ii)
fmt.Println(pack)
//writer.WriteString(pack)
client.Write(pack.Buffer)
//fmt.Println(reader.ReadString('\n'))
bytes := make([]byte, 512)
l, _ := client.Read(bytes)
//fmt.Println(bytes)
b := ftm.Match(ii+1, packet.NewPacket(bytes, l), info)
fmt.Println(b)
}
fmt.Println("Service Name : ", ftm.ServiceName())
}

191
matcher/ftp/ftps.go Normal file
View File

@ -0,0 +1,191 @@
package ftp
import (
"bufio"
"crypto/tls"
"errors"
"fmt"
log "github.com/cihub/seelog"
"net"
"strings"
"time"
)
// FTP is a Session for file Transfer Protocol
type FTPS struct {
conn net.Conn
addr string
tlsconfig *tls.Config
reader *bufio.Reader
writer *bufio.Writer
isFtps bool
}
func (fs *FTPS) close() {
fs.conn.Close()
}
func (fs *FTPS) quit() (err error) {
if _, err := fs.cmd(statusCloseConnect, "QUIT"); err != nil {
return err
}
fs.conn.Close()
fs.conn = nil
return nil
}
func (fs *FTPS) cmd(expects string, cmd string) (line string, err error) {
if err = fs.send(cmd); err != nil {
log.Error("ftps.go cmd send error: ", err)
return "", err
}
if line, err = fs.receive(); err != nil {
log.Error("ftps.go cmd receive error: ", err)
return line, err
}
if !strings.HasPrefix(line, expects) {
err = errors.New(line)
return line, err
}
return line, err
}
func (fs *FTPS) readAndDiscard() (int, error) {
var i int
bufferSize := fs.reader.Buffered()
for i = 0; i < bufferSize; i++ {
if _, err := fs.reader.ReadByte(); err != nil {
return i, err
}
}
return i, nil
}
func (fs *FTPS) receive() (string, error) {
line, err := fs.reader.ReadString('\n')
//log.Debug("< %s", line)
if err != nil {
return line, err
}
fs.readAndDiscard()
//fmt.Println(line)
return line, err
}
func (fs *FTPS) send(cmd string) (err error) {
if len(cmd) == 0 {
err = errors.New("command length 0")
}
cmd = fmt.Sprintf(cmd)
cmd += "\r\n"
if _, err := fs.writer.WriteString(cmd); err != nil {
return err
}
if err := fs.writer.Flush(); err != nil {
return err
}
return nil
}
func (fs *FTPS) authTls(config *tls.Config) error {
if _, err := fs.cmd(statusTlsUseOK, "AUTH TLS"); err != nil {
return err
}
fs.tlsconfig = config
fs.conn = tls.Client(fs.conn, config)
fs.writer = bufio.NewWriter(fs.conn)
fs.reader = bufio.NewReader(fs.conn)
_, err := fs.cmd(statusOK, "PBSZ 0")
if err != nil {
return err
}
_, err = fs.cmd(statusOK, "PROT P")
if err != nil {
return err
}
return nil
}
func (fs *FTPS) NewFTPSConnect(addr string) (*FTPS, error) {
var err error
var conn net.Conn
if conn, err = net.Dial("tcp", addr); err != nil {
log.Error("FTPS Socket Fail: ", err.Error())
return nil, err
}
err = conn.SetDeadline(time.Now().Add(3 * time.Second))
if err != nil {
//log.Error("FTPS Socket Fail: ", err.Error())
return nil, err
}
writer := bufio.NewWriter(conn)
reader := bufio.NewReader(conn)
var line string
obj := &FTPS{
conn: conn,
addr: addr,
reader: reader,
writer: writer,
}
line, err = obj.receive()
if !strings.HasPrefix(line, "220") {
err = errors.New(line)
return nil, err
}
//log.Debug(line)
return obj, err
}
func StartCheckFTPS(ip string, port string) (bool, error) {
var err error
var fs *FTPS
addr := ip + ":" + port
//log.Debug("address : " + addr)
if fs, err = fs.NewFTPSConnect(addr); err != nil {
return false, err
}
defer fs.close()
config := &tls.Config{
InsecureSkipVerify: true,
ClientAuth: tls.RequestClientCert,
}
if err = fs.authTls(config); err != nil {
return false, err
}
return true, err
}

13
matcher/ftp/ftps_test.go Normal file
View File

@ -0,0 +1,13 @@
package ftp
import (
"fmt"
"testing"
)
func TestStartCheckFTPS(t *testing.T) {
isFtps, err := StartCheckFTPS("192.168.1.202", "80")
fmt.Println("Result : ", isFtps)
fmt.Println("Error : ", err)
}

90
matcher/http/http.go Normal file
View File

@ -0,0 +1,90 @@
package http
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
"strings"
)
type HTTPMatcher struct {
sendPackets []*packet.Packet
}
func (h *HTTPMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
result := false
if packet == nil || packet.Buffer == nil || packet.Len == 0 {
return result
}
str := string(packet.Buffer)
//fmt.Println(str)
elems := strings.Split(str, "\r\n")
if len(elems) <= 0 {
return result
}
protocol := (elems[0])[:8]
httpv0 := strings.Compare(protocol, "HTTP/1.0")
httpv1 := strings.Compare(protocol, "HTTP/1.1")
httpv2 := strings.Compare(protocol, "HTTP/1.2")
if 0 == httpv0 || 0 == httpv1 || 0 == httpv2 {
result = true
}
serverName := "Unknown Server"
for _, valueStr := range elems {
tempElems := strings.Split(valueStr, ":")
if 0 == strings.Compare(tempElems[0], "Server") {
serverName = tempElems[1]
break
}
}
strings.Compare(serverName, "Unknown")
//fmt.Println("HTTP Server Name: ", serverName)
return result
}
func (h *HTTPMatcher) PacketCount() int {
return len(h.sendPackets)
}
func (h *HTTPMatcher) Packet(index int) *packet.Packet {
return h.sendPackets[index]
}
func (h *HTTPMatcher) ServiceName() string {
return "HTTP"
}
func (h *HTTPMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (h *HTTPMatcher) IsNoResponse(index int) bool {
return false
}
func (h *HTTPMatcher) IsPrePacket() bool {
return false
}
func NewHTTPMatcher() *HTTPMatcher {
h := HTTPMatcher{}
reqStr := "GET / HTTP/1.1\r\n\r\n"
byte := make([]byte, len(reqStr))
copy(byte[:], reqStr)
h.sendPackets = append(h.sendPackets, packet.NewPacket(byte, len(reqStr)))
return &h
}

49
matcher/http/http_test.go Normal file
View File

@ -0,0 +1,49 @@
package http
//import (
// "fmt"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestHTTPMatcher_Packet(t *testing.T) {
// hm := NewHTTPMatcher()
// fmt.Println(hm)
// fmt.Println(hm.sendPackets[0])
//
//}
//
//func TestHTTPMatcher_Match(t *testing.T) {
// fmt.Println("Match")
//
// hm := NewHTTPMatcher()
//
// port := types.NewPort("80", types.NewHost("192.168.1.103"), types.TYPE_TCP)
//
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// //fmt.Println(ipport)
//
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// pack := hm.Packet(0)
//
// //fmt.Println(pack)
//
// //writer.WriteString(pack)
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 512)
//
// l, _ := client.Read(bytes)
//
// //fmt.Println(bytes)
//
// hm.Match(0, packet.NewPacket(bytes, l), nil)
//
//}

View File

@ -0,0 +1,55 @@
package http
//import (
// "crypto/tls"
// "fmt"
// "loafle.com/overflow/collector/discovery/scan/matcher/packet"
// "log"
// "net"
// "testing"
// "time"
//)
//
//func TestHTTPSMatcher_Match(t *testing.T) {
// netinfo := "192.168.1.1:443"
// dialer := &net.Dialer{
// Timeout: 5 * time.Second,
// }
//
// conn, err := tls.DialWithDialer(
// dialer,
// "tcp",
// netinfo,
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.103",
// },
// )
//
// if err != nil {
// log.Println(err)
// return
// }
// defer conn.Close()
//
// //fmt.Println(conn)
// h := NewHTTPMatcher()
//
// pac := h.Packet(0)
//
// //fmt.Println(pac)
// //fmt.Println(pac.Buffer)
//
// //bytes := make([]byte, 1024)
//
// l, _ := conn.Write(pac.Buffer)
//
// buf := make([]byte, 1024)
// l, _ = conn.Read(buf)
//
// fmt.Println(string(buf))
// fmt.Println(l)
// is := h.Match(0, packet.NewPacket(buf, l), nil)
// fmt.Println(is)
//
//}

87
matcher/imap/imap.go Normal file
View File

@ -0,0 +1,87 @@
package imap
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
PRE_COMPARE_STR = "* OK"
SEND_COMPARE_STR = "* BYE"
)
type IMAPMatcher struct {
sendPackets []*packet.Packet
}
func (i *IMAPMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
switch index {
case 0:
recvStr := string(packet.Buffer)
if len(recvStr) < 3 {
return false
}
compareStr := recvStr[0:4]
if compareStr == PRE_COMPARE_STR {
return true
}
case 1:
recvStr := string(packet.Buffer)
if len(recvStr) < 5 {
return false
}
compareStr := recvStr[0:5]
if compareStr == SEND_COMPARE_STR {
return true
}
}
return false
}
func (i *IMAPMatcher) PacketCount() int {
return len(i.sendPackets)
}
func (i *IMAPMatcher) Packet(index int) *packet.Packet {
return i.sendPackets[index]
}
func (i *IMAPMatcher) ServiceName() string {
return "IMAP"
}
func (i *IMAPMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (i *IMAPMatcher) IsNoResponse(index int) bool {
return false
}
func (i *IMAPMatcher) IsPrePacket() bool {
return true
}
func NewIMAPMatcher() *IMAPMatcher {
im := IMAPMatcher{}
reqStr := "A0001 LOGOUT\r\n"
byte := make([]byte, len(reqStr))
copy(byte[:], reqStr)
im.sendPackets = append(im.sendPackets, packet.NewPacket(byte, len(reqStr)))
return &im
}

150
matcher/imap/imap_test.go Normal file
View File

@ -0,0 +1,150 @@
package imap
//
//import (
// "crypto/tls"
// "fmt"
// "loafle.com/overflow/collector/core/scan/port"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "loafle.com/overflow/collector/core/scan/service/matcher/scaninfo"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func ImapRun(client net.Conn, t *testing.T) {
//
// lm := NewIMAPMatcher()
//
// port := types.NewPort("143", types.NewHost("192.168.1.215"), types.TYPE_TCP)
//
// scanInfo := types.NewServiceScanInfo(port)
//
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// fmt.Println(ipport)
// //client, _ := net.Dial("tcp", ipport)
//
// //defer client.Close()
//
// bytett := make([]byte, 1024)
//
// rr, _ := client.Read(bytett)
//
// bb := lm.Match(0, packet.NewPacket(bytett, rr), scanInfo)
//
// if bb {
// t.Log("good!")
// }
//
// fmt.Println(lm.PacketCount())
//
// for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// //fmt.Println(pack)
//
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 1024)
//
// read, _ := client.Read(bytes)
//
// fmt.Println(cap(bytes))
//
// //fmt.Println(bytes)
//
// b := lm.Match(ii+1, packet.NewPacket(bytes, read), scanInfo)
//
// if b {
// t.Log("send Good!")
// }
//
// }
// t.Log(scanInfo)
//
//}
//
//func TestIMapTls(t *testing.T) {
//
// conn, _ := tls.Dial(
// "tcp",
// "192.168.1.215:993",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.215",
// },
// )
//
// defer conn.Close()
//
// ImapRun(conn, t)
//
//}
//
//func TestIMapNormal(t *testing.T) {
//
// client, _ := net.Dial("tcp", "192.168.1.215:143")
//
// defer client.Close()
//
// ImapRun(client, t)
//
//}
//
//func TestImap(t *testing.T) {
//
// lm := NewIMAPMatcher()
//
// //port := types.NewPort("143", types.NewHost("192.168.1.215"), types.TYPE_TCP)
//
// //scanInfo := scaninfo.NewServiceScanInfo(port)
//
// var ipport string
// //ipport = port.Host.Ip + ":" + port.Port_
//
// fmt.Println(ipport)
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// bytett := make([]byte, 1024)
//
// rr, _ := client.Read(bytett)
//
// //bb := lm.Match(0, packet.NewPacket(bytett, rr), scanInfo)
// bb := lm.Match(0, packet.NewPacket(bytett, rr), nil)
//
// if bb {
// t.Log("good!")
// }
//
// fmt.Println(lm.PacketCount())
//
// for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// //fmt.Println(pack)
//
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 1024)
//
// read, _ := client.Read(bytes)
//
// fmt.Println(cap(bytes))
//
// //fmt.Println(bytes)
//
// b := lm.Match(ii+1, packet.NewPacket(bytes, read), nil)
//
// if b {
// t.Log("send Good!")
// }
//
// }
// //t.Log(scanInfo)
//}

198
matcher/ldap/ldap.go Normal file
View File

@ -0,0 +1,198 @@
package ldap
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
type LDAPMatcher struct {
sendPackets []*packet.Packet
}
func (l *LDAPMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
buf := new(bytes.Buffer)
buf.Write(packet.Buffer)
ldapRecv := LDAP_RECV{}
binary.Read(buf, binary.LittleEndian, &ldapRecv)
if ldapRecv.MessageId != LDAP_MESSAGE_ID {
return false
}
if ldapRecv.ProtocolOp != LDAP_RES_BIND {
return false
}
if ldapRecv.ResultCode != LDAP_SUCCESS {
return false
}
return true
}
func (l *LDAPMatcher) PacketCount() int {
return len(l.sendPackets)
}
func (l *LDAPMatcher) Packet(index int) *packet.Packet {
return l.sendPackets[index]
}
func (l *LDAPMatcher) ServiceName() string {
return "LDAP"
}
func (l *LDAPMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (l *LDAPMatcher) IsNoResponse(index int) bool {
if index == 1 {
return true
}
return false
}
func (l *LDAPMatcher) IsPrePacket() bool {
return false
}
func NewLDAPMatcher() *LDAPMatcher {
ls := LDAP_SEND{
DefaultCode: 0x30,
PacketLength: 0x0c, // size -2
NextType1: 0x02,
NextTypeLength1: 0x01,
MessageId: LDAP_MESSAGE_ID,
ProtocolOp: LDAP_REQ_BIND,
ProtocolOpLength: 0x07,
NextType2: 0x02,
NextTypeLength2: 0x01,
Version: LDAP_VERSION3,
NextType3: 0x04,
NextTypeLength3: 0x00,
Auth: LDAP_AUTH_SIMPLE,
AuthLength: 0x00,
}
mCache := new(bytes.Buffer)
binary.Write(mCache, binary.LittleEndian, ls)
sendByte1 := mCache.Bytes()
lm := LDAPMatcher{
//sendPackets: make([][]byte, 2),
}
pp := packet.NewPacket(sendByte1, len(sendByte1))
lm.sendPackets = append(lm.sendPackets, pp)
lq := LDAP_QUIT{
DefaultCode: 0x30,
UnknwonCode1: 0x84,
PacketLength: 0x05,
NextType1: 0x02,
NextTypeLength1: 0x01,
MessageId: LDAP_MESSAGE_ID_QUIT,
ProtocolOp: LDAP_REQ_UNBIND,
protocolOpLength: 0x00,
}
lqBuffer := new(bytes.Buffer)
binary.Write(lqBuffer, binary.BigEndian, lq)
sendByte2 := lqBuffer.Bytes()
pp2 := packet.NewPacket(sendByte2, len(sendByte2))
lm.sendPackets = append(lm.sendPackets, pp2)
return &lm
}
type LDAP_SEND struct {
DefaultCode uint8
PacketLength uint8
NextType1 uint8
NextTypeLength1 uint8
MessageId uint8
ProtocolOp uint8
ProtocolOpLength uint8
NextType2 uint8
NextTypeLength2 uint8
Version uint8
NextType3 uint8
NextTypeLength3 uint8
Auth uint8
AuthLength uint8
}
type LDAP_RECV struct {
DefaultCode uint8
UnknwonCode1 uint8
EndCode11 uint8
EndCode12 uint8
MessageId uint8
ProtocolOp uint8
UnknwonCode2 uint8
EndCode21 uint8
EndCode22 uint8
ResultCode uint8
UnknwonCode3 uint8
UnknwonCode4 uint8
Auth uint8
UnknwonCode5 uint8
}
type LDAP_QUIT struct {
DefaultCode uint8
UnknwonCode1 uint8
PacketLength uint32
NextType1 uint8
NextTypeLength1 uint8
MessageId uint8
ProtocolOp uint8
protocolOpLength uint8
}
const (
LDAP_MESSAGE_ID = 0x99
LDAP_MESSAGE_ID_QUIT = 0x89
LDAP_VERSION3 = 3
LDAP_SUCCESS = 0x00
LDAP_REQ_BIND = 0x60
LDAP_REQ_UNBIND = 0x42
LDAP_RES_BIND = 0x61
LDAP_AUTH_SIMPLE = 0x80
)

110
matcher/ldap/ldap_test.go Normal file
View File

@ -0,0 +1,110 @@
package ldap
//
//import (
// "crypto/tls"
// "fmt"
// "loafle.com/overflow/collector/discovery/scan/matcher/packet"
// "loafle.com/overflow/collector/discovery/scan/matcher/scaninfo"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
////func SetUp() {
//// fmt.Println("SetUp")
////}
////
////func TearDown() {
//// fmt.Println("TearDown")
////}
//
////func TestMain(m *testing.M) {
//// SetUp()
//// m.Run()
//// TearDown()
////}
//
//func TestAAAA(t *testing.T) {
// ///animals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}}
//
// var ttt [][]int = make([][]int, 10)
//
// var aaa []int
// aaa = append(aaa, 111)
//
// ttt = append(ttt, aaa)
//
// fmt.Println(cap(ttt))
//
//}
//
//func ldapRun(client net.Conn, t *testing.T) {
// lm := NewLDAPMatcher()
//
// port := types.NewPort("389", types.NewHost("192.168.1.215"), types.TYPE_TCP)
// scanInfo := scaninfo.NewServiceScanInfo(port)
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// fmt.Println(ipport)
// //client, _ := net.Dial("tcp", ipport)
// //defer client.Close()
//
// fmt.Println(lm.PacketCount())
//
// for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// bytes := make([]byte, 1024)
//
// client.Write(pack.Buffer)
//
// read, _ := client.Read(bytes)
//
// if read <= 0 {
// bb := lm.IsNoResponse(ii)
// if bb {
//
// t.Log("IsNoResponse good")
// break
// }
//
// }
//
// fmt.Println(bytes)
//
// b := lm.Match(ii, packet.NewPacket(bytes, read), scanInfo)
//
// if b {
// t.Log("Good")
// }
//
// }
//
// t.Log(scanInfo)
//}
//
//func TestLdapTls(t *testing.T) {
// conn, _ := tls.Dial(
// "tcp",
// "192.168.1.215:636",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.215",
// },
// )
//
// defer conn.Close()
//
// ldapRun(conn, t)
//}
//
//func TestLdapNormal(t *testing.T) {
// client, _ := net.Dial("tcp", "192.168.1.215:389")
//
// defer client.Close()
//
// ldapRun(client, t)
//}

115
matcher/matcher.go Normal file
View File

@ -0,0 +1,115 @@
package matcher
import (
//"loafle.com/overflow/collector/core/scan/service/matcher/activedirectory"
//"loafle.com/overflow/collector/core/scan/service/matcher/cassandra"
//"loafle.com/overflow/collector/core/scan/service/matcher/dns"
//"loafle.com/overflow/collector/core/scan/service/matcher/ftp"
//"loafle.com/overflow/collector/core/scan/service/matcher/http"
//"loafle.com/overflow/collector/core/scan/service/matcher/imap"
//"loafle.com/overflow/collector/core/scan/service/matcher/ldap"
//"loafle.com/overflow/collector/core/scan/service/matcher/mongodb"
//"loafle.com/overflow/collector/core/scan/service/matcher/mssql"
//"loafle.com/overflow/collector/core/scan/service/matcher/mysql"
//"loafle.com/overflow/collector/core/scan/service/matcher/netbios"
"loafle.com/overflow/commons_go/matcher/oracle"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
//"loafle.com/overflow/collector/core/scan/service/matcher/pop"
//"loafle.com/overflow/collector/core/scan/service/matcher/redis"
//"loafle.com/overflow/collector/core/scan/service/matcher/rmi"
//"loafle.com/overflow/collector/core/scan/service/matcher/smb"
//"loafle.com/overflow/collector/core/scan/service/matcher/smtp"
//"loafle.com/overflow/collector/core/scan/service/matcher/snmp"
//"loafle.com/overflow/collector/core/scan/service/matcher/ssh"
//"loafle.com/overflow/collector/core/scan/service/matcher/telnet"
//"loafle.com/overflow/collector/core/scan/service/matcher/wmi"
)
var (
TcpMatchers []Matcher
UdpMatchers []UDPMatcher
)
func init() {
//TCP
//TcpMatchers = append(TcpMatchers, smtp.NewSmtpMatcher())
//TcpMatchers = append(TcpMatchers, ldap.NewLDAPMatcher())
//TcpMatchers = append(TcpMatchers, activedirectory.NewActiveDirectoryMatcher())
//TcpMatchers = append(TcpMatchers, mongodb.NewMongoDBMatcher())
//TcpMatchers = append(TcpMatchers, mysql.NewMySqlMatcher())
//TcpMatchers = append(TcpMatchers, mssql.NewMSSqlMatcher())
//TcpMatchers = append(TcpMatchers, redis.NewRedisMatcher())
//TcpMatchers = append(TcpMatchers, redis.NewRedisProtectedMatcher())
//TcpMatchers = append(TcpMatchers, netbios.NewNetBiosMatcher())
//TcpMatchers = append(TcpMatchers, smb.NewSMBMatcher())
//TcpMatchers = append(TcpMatchers, cassandra.NewCassandraMatcher())
//TcpMatchers = append(TcpMatchers, imap.NewIMAPMatcher())
TcpMatchers = append(TcpMatchers, oracle.NewOracleMatcher())
//TcpMatchers = append(TcpMatchers, pop.NewPOPMatcher())
//TcpMatchers = append(TcpMatchers, wmi.NewWMIMatcher())
//TcpMatchers = append(TcpMatchers, ftp.NewFTPMatcher())
//TcpMatchers = append(TcpMatchers, http.NewHTTPMatcher())
//TcpMatchers = append(TcpMatchers, rmi.NewRMIMatcher())
//TcpMatchers = append(TcpMatchers, ssh.NewSSHMatcher())
//TcpMatchers = append(TcpMatchers, telnet.NewTelnetMatcher())
//UdpMatchers = append(UdpMatchers, dns.NewDnsMatcher())
//UdpMatchers = append(UdpMatchers, snmp.NewSNMPv2Matcher())
//UdpMatchers = append(UdpMatchers, snmp.NewSNMPv3Matcher())
}
type Matcher interface {
Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool
PacketCount() int
Packet(index int) *packet.Packet
ServiceName() string
IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool
IsNoResponse(index int) bool
IsPrePacket() bool
}
type UDPMatcher interface {
Matcher
IsSend(port int) bool
}
func GetTcpMatchers(ispre bool) []Matcher {
retMatchers := make([]Matcher, 0)
l := len(TcpMatchers)
for i := 0; i < l; i++ {
c := TcpMatchers[i].IsPrePacket()
if c == ispre {
retMatchers = append(retMatchers, TcpMatchers[i])
}
}
return retMatchers
}
func GetUdpMatchers() []UDPMatcher {
retMatchers := make([]UDPMatcher, 0)
l := len(UdpMatchers)
for i := 0; i < l; i++ {
retMatchers = append(retMatchers, UdpMatchers[i])
}
return retMatchers
}
func GetMatcherByName(serName string) Matcher {
for _, m := range TcpMatchers {
if m.ServiceName() == serName {
return m
}
}
for _, m := range UdpMatchers {
if m.ServiceName() == serName {
return m
}
}
return nil
}

87
matcher/matcher_test.go Normal file
View File

@ -0,0 +1,87 @@
package matcher
import (
"fmt"
"testing"
)
type TestMatcher struct {
}
func (t *TestMatcher) ServiceName() string {
return "TestMatcher"
}
func (t *TestMatcher) Match(index int, packet []byte, info ServiceScanInfo) bool {
return true
}
func (t *TestMatcher) PacketCount() int {
return 1
}
func (t *TestMatcher) Packet(index int) []byte {
return nil
}
func (t *TestMatcher) IsError(index int, packet []byte, info ServiceScanInfo) bool {
return true
}
func (t *TestMatcher) IsNoResponse(index int) bool {
return true
}
func (t *TestMatcher) IsPrePacket() bool {
return true
}
type Animal interface {
Speak() string
}
type Dog struct {
}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct {
}
func (c Cat) Speak() string {
return "Meow!"
}
type Llama struct {
}
func (l Llama) Speak() string {
return "?????"
}
type JavaProgrammer struct {
}
func (j JavaProgrammer) Speak() string {
return "Design patterns!"
}
func TestMatcherTTT(t *testing.T) {
//animals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}}
var animals []Animal
animals = append(animals, &Dog{})
animals = append(animals, &Cat{})
animals = append(animals, &Llama{})
animals = append(animals, &JavaProgrammer{})
for _, a := range animals {
fmt.Println(a.Speak())
}
}
func TestMatchersInit(t *testing.T) {
}

122
matcher/mongodb/mongodb.go Normal file
View File

@ -0,0 +1,122 @@
package mongodb
import (
"bytes"
"encoding/binary"
"math/rand"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
MONGO_OP_REQUEST uint32 = 2004
MONGO_OP_REPLY uint32 = 1
MONGO_FCNAME string = "admin.$cmd"
MONGO_ELEMENT string = "ismaster"
)
var MONGO_REQUEST_ID uint32
type mongo struct {
MessageLength uint32
RequestId uint32
ResponseTo uint32
OpCode uint32
Flags uint32
FullCollectionName [11]byte
NumberToSkip uint32
NumberToReturn int32
DocumentLength uint32
Type_ uint8
Element [9]byte
Value uint8
_ uint8
}
type MongoDBMatcher struct {
packets []*packet.Packet
}
func NewMongoDBMatcher() *MongoDBMatcher {
mongoMatcher := &MongoDBMatcher{}
tempBuf := new(bytes.Buffer)
binary.Write(tempBuf, binary.BigEndian, mongo{})
var fcn [11]byte
copy(fcn[:], MONGO_FCNAME)
var elem [9]byte
copy(elem[:], MONGO_ELEMENT)
MONGO_REQUEST_ID = rand.Uint32()
m := mongo{
MessageLength: uint32(len(tempBuf.Bytes())),
RequestId: MONGO_REQUEST_ID,
ResponseTo: 0,
OpCode: MONGO_OP_REQUEST,
Flags: 0,
FullCollectionName: fcn,
NumberToSkip: 0,
NumberToReturn: -1,
DocumentLength: 16,
Type_: 0x08,
Element: elem,
Value: 1,
}
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, m)
mongoMatcher.packets = append(mongoMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return mongoMatcher
}
func (t *MongoDBMatcher) ServiceName() string {
return "MongoDB"
}
func (t *MongoDBMatcher) PacketCount() int {
return len(t.packets)
}
func (t *MongoDBMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *MongoDBMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *MongoDBMatcher) IsNoResponse(index int) bool {
return false
}
func (t *MongoDBMatcher) IsPrePacket() bool {
return false
}
func (t *MongoDBMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
m := mongo{}
if err := binary.Read(reader, binary.LittleEndian, &m); err != nil {
return false
}
if uint32(packet.Len) != m.MessageLength ||
m.ResponseTo != MONGO_REQUEST_ID ||
m.OpCode != MONGO_OP_REPLY {
return false
}
return true
}

View File

@ -0,0 +1,55 @@
package mongodb
//
//import (
// "crypto/tls"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestMongoNor(t *testing.T) {
//
// conn, _ := net.Dial("tcp", "192.168.1.105:27017")
//
// defer conn.Close()
//
// MongoRun(conn, t)
//
//}
//func TestMongoTLS(t *testing.T) {
// conn, _ := tls.Dial(
// "tcp",
// "192.168.1.105:27017",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.105",
// },
// )
//
// defer conn.Close()
//
// MongoRun(conn, t)
//}
//
//func MongoRun(conn net.Conn, t *testing.T) {
//
// m := NewMongoDBMatcher()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("MongoDB found")
// return
// }
//
// t.Error("MongoDB not found")
// }
//
//}

173
matcher/mssql/mssql.go Normal file
View File

@ -0,0 +1,173 @@
package mssql
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
HEADER_TYPE_PRELOGIN uint8 = 0x12
HEADER_TYPE_RESPONSE uint8 = 0x4
PL_OPTION_TOKEN_VERSION uint8 = 0x00
PL_OPTION_TOKEN_ENCRYPTION uint8 = 0x01
PL_OPTION_TOKEN_TRACEID uint8 = 0x05
PL_OPTION_TOKEN_TERMINATOR uint8 = 0xff
ENCRYPT_OFF string = "Encryption is available but off."
ENCRYPT_ON string = "Encryption is available and on."
ENCRYPT_NOT_SUP string = "Encryption is not available."
ENCRYPT_REQ string = "Encryption is required."
)
type PreloginMsg struct {
VersionToken uint8
VersionOffset uint16
VersionLength uint16
EncryptionToken uint8
EncryptionOffset uint16
EncryptionLength uint16
TraceIdToken uint8
TraceIdOffset uint16
TraceIdLength uint16
Terminator uint8
Options [7]uint8
TraceId [36]uint8
}
type mssql struct {
Type_ uint8
Status uint8
Length uint16
Channel uint16
PacketNum uint8
Window uint8
Prelogin PreloginMsg
}
type PreloginResponse struct {
Msg [256]uint8
}
type mssqlResponse struct {
Type_ uint8
Status uint8
Length uint16
Channel uint16
PacketNum uint8
Window uint8
PreLoginResp PreloginResponse
}
type MSSqlMatcher struct {
packets []*packet.Packet
isSSL bool
}
func NewMSSqlMatcher() *MSSqlMatcher {
mssqlMatcher := &MSSqlMatcher{}
tempBuf := new(bytes.Buffer)
binary.Write(tempBuf, binary.BigEndian, mssql{})
m := mssql{
Type_: HEADER_TYPE_PRELOGIN,
Status: 0x01,
Length: uint16(len(tempBuf.Bytes())),
Channel: 0,
PacketNum: 0,
Window: 0,
Prelogin: PreloginMsg{
VersionToken: PL_OPTION_TOKEN_VERSION,
VersionOffset: 0x0010,
VersionLength: 0x0006,
EncryptionToken: PL_OPTION_TOKEN_ENCRYPTION,
EncryptionOffset: 0x0016,
EncryptionLength: 0x0001,
TraceIdToken: PL_OPTION_TOKEN_TRACEID,
TraceIdOffset: 0x0017,
TraceIdLength: 0x0024,
Terminator: PL_OPTION_TOKEN_TERMINATOR,
},
}
writer := new(bytes.Buffer)
binary.Write(writer, binary.BigEndian, m)
mssqlMatcher.packets = append(mssqlMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return mssqlMatcher
}
func (t *MSSqlMatcher) ServiceName() string {
if t.isSSL {
return "SQL Server (SSL)"
}
return "SQL Server"
}
func (t *MSSqlMatcher) PacketCount() int {
return len(t.packets)
}
func (t *MSSqlMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *MSSqlMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *MSSqlMatcher) IsNoResponse(index int) bool {
return false
}
func (t *MSSqlMatcher) IsPrePacket() bool {
return false
}
func (t *MSSqlMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
m := mssqlResponse{}
if err := binary.Read(reader, binary.BigEndian, &m); err != nil {
return false
}
if m.Type_ != HEADER_TYPE_RESPONSE {
return false
}
if m.Length != uint16(packet.Len) {
return false
}
switch m.PreLoginResp.Msg[m.Length-9 : m.Length-8][0] {
case 0:
return true
case 1:
t.isSSL = true
return true
case 2:
return true
case 3:
t.isSSL = true
return true
default:
return false
}
return false
}

View File

@ -0,0 +1,64 @@
package mssql
//
//import (
// "loafle.com/overflow/collector/discovery/scan/matcher/packet"
// "net"
// "testing"
//)
//
///*
//192.168.1.106:1433 - normal
//192.168.1.103:1433 - ssl
//*/
//func TestSqlNor(t *testing.T) {
//
// conn, _ := net.Dial("tcp", "192.168.1.103:1433")
//
// defer conn.Close()
//
// sqlServerRun(conn, t)
//
//}
//
////func TestSqlTLS(t *testing.T) {
//// conn, err := tls.Dial(
//// "tcp",
//// "192.168.1.103:7680",
//// &tls.Config{
//// InsecureSkipVerify: true,
//// ServerName: "192.168.1.103",
//// },
//// )
////
//// if err != nil {
//// t.Log(err)
//// return
//// }
////
//// defer conn.Close()
////
//// sqlServerRun(conn, t)
////}
//
//func sqlServerRun(conn net.Conn, t *testing.T) {
//
// m := NewMSSqlMatcher()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log(m.ServiceName())
// return
// }
//
// t.Error("MSSQL not found")
// }
//
//}

151
matcher/mysql/mysql.go Normal file
View File

@ -0,0 +1,151 @@
package mysql
import (
"bytes"
"encoding/binary"
"fmt"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
"strconv"
"strings"
)
type PacketSize struct {
PacketLength [3]byte
PacketNumber byte
}
type mySql struct {
Payload PacketSize
Protocol byte
Version [256]byte
TreadId uint32
Salt1 [9]byte
ServerCapa uint16
ServerLang uint8
ServerStat uint16
ExtServerCapa uint16
AuthPlugLen uint8
_ [10]uint8
Salt2 [13]uint8
AuthPlugName [64]uint8
}
type MySqlMatcher struct {
packets []*packet.Packet
version string
isErrResp bool
errCode int
errMsg string
isSSL bool
}
func NewMySqlMatcher() *MySqlMatcher {
return &MySqlMatcher{}
}
func (t *MySqlMatcher) ServiceName() string {
if t.isErrResp {
return "MySQL" + "(Err-" + strconv.Itoa(t.errCode) + " : " + t.errMsg + ")"
}
if t.isSSL {
return "MySQL" + "-" + t.version + "(SSL)"
}
return "MySQL" + "(" + t.version + ")"
}
func (t *MySqlMatcher) PacketCount() int {
return len(t.packets)
}
func (t *MySqlMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *MySqlMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *MySqlMatcher) IsNoResponse(index int) bool {
return false
}
func (t *MySqlMatcher) IsPrePacket() bool {
return true
}
func (t *MySqlMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil || len(packet.Buffer) <= 0 {
return false
}
r := new(bytes.Buffer)
r.Write(packet.Buffer)
m := mySql{}
if err := binary.Read(r, binary.LittleEndian, &m); err != nil {
return false
}
buf := bytes.NewBuffer(m.Payload.PacketLength[:])
packetLen, _ := binary.ReadUvarint(buf)
if packetLen != uint64(packet.Len-4) {
return false
}
if m.Protocol == 0xff {
//MySQL error response
var code [2]uint8
copy(code[:], m.Version[:2])
var msg [256]uint8
copy(msg[:], m.Version[2:])
errCode := binary.LittleEndian.Uint16(code[:])
if errCode < 1000 || errCode > 1727 {
return false
}
errMsg := bytes.Trim(msg[:], "\x00")
t.isErrResp = true
t.errCode = int(errCode)
t.errMsg = string(errMsg)
return true
}
if m.Protocol != 10 && m.Protocol != 9 {
return false
}
t.checkSSL(packet)
return true
}
func (t *MySqlMatcher) checkSSL(packet *packet.Packet) {
temp := make([]byte, packet.Len)
r := new(bytes.Buffer)
r.Write(packet.Buffer)
if err := binary.Read(r, binary.LittleEndian, &temp); err != nil {
return
}
t.version = strings.Split(string(packet.Buffer)[5:packet.Len], "\x00")[0]
versionLen := len(t.version) + 1
data := binary.LittleEndian.Uint16(temp[18+versionLen : 20+versionLen])
s := fmt.Sprintf("%b", data)
for i, b := range s {
if i == 4 {
if b == 49 {
t.isSSL = true
}
}
}
}

View File

@ -0,0 +1,71 @@
package mysql
//
//import (
// "crypto/tls"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestMySql(t *testing.T) {
//
// m := NewMySqlMatcher()
//
// /*
// 192.168.1.103:3306 - normal
// 192.168.1.105:8306 - ssl
// 192.168.1.203:3306 - mysql with error code
// */
// conn, _ := net.Dial("tcp", "192.168.1.215:3306")
//
// defer conn.Close()
//
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(0, p, nil) {
// t.Log(m.ServiceName())
// return
// }
//
// t.Error("MySQL not found")
//
//}
//
//func TestCassandraTLS(t *testing.T) {
//
// m := NewMySqlMatcher()
//
// conn, err := tls.Dial(
// "tcp",
// "192.168.1.105:8306",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.105",
// },
// )
// if err != nil {
// t.Fatal(err)
// }
//
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log(m.ServiceName())
// return
// }
//
// t.Error("MySQL not found")
// }
//
//}

109
matcher/netbios/netbios.go Normal file
View File

@ -0,0 +1,109 @@
package netbios
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
NBSS_SESSION_REQUEST uint8 = 0x81
NBSS_POSITIVE_SESSION_RESPONSE uint8 = 0x82
NBSS_NEGATIVE_SESSION_RESPONSE uint8 = 0x83
ADDR string = "192.168.1.202:139"
)
type netBios struct {
MsgType uint8
Flags uint8 //0-6 : Reserved, must be zero. 7 : Length extension.
Length uint16
CalledNameLen uint8
CalledName [16]uint16
_ uint8
CallingNameLen uint8
CallingName [16]uint16
_ uint8
}
type NetBiosMatcher struct {
packets []*packet.Packet
}
func NewNetBiosMatcher() *NetBiosMatcher {
nbssMatcher := &NetBiosMatcher{}
tempBuf := new(bytes.Buffer)
binary.Write(tempBuf, binary.BigEndian, netBios{})
query := netBios{
MsgType: NBSS_SESSION_REQUEST,
Flags: 0x00,
Length: 0x4400,
CalledNameLen: 0x20,
CallingNameLen: 0x20,
}
query.CalledName[0] = 0x4D45 // L
query.CalledName[1] = 0x4745 // F
query.CallingName[0] = 0x4D45
query.CallingName[1] = 0x4745
for i := 2; i < 16; i++ {
query.CalledName[i] = 0x4143 //Space
query.CallingName[i] = 0x4143
}
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, query)
nbssMatcher.packets = append(nbssMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return nbssMatcher
}
func (t *NetBiosMatcher) ServiceName() string {
return "NBSS"
}
func (t *NetBiosMatcher) PacketCount() int {
return len(t.packets)
}
func (t *NetBiosMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *NetBiosMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *NetBiosMatcher) IsNoResponse(index int) bool {
return false
}
func (t *NetBiosMatcher) IsPrePacket() bool {
return false
}
func (t *NetBiosMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
n := netBios{}
if err := binary.Read(reader, binary.LittleEndian, &n); err != nil {
return false
}
if NBSS_NEGATIVE_SESSION_RESPONSE != n.MsgType {
return false
}
return true
}

View File

@ -0,0 +1,34 @@
package netbios
//
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestNBSS(t *testing.T) {
//
// m := NewNetBiosMatcher()
//
// conn, _ := net.Dial("tcp", "192.168.1.106:139")
//
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("NBSS found")
// return
// }
//
// t.Error("NBSS not found")
// }
//
//}

187
matcher/oracle/oracle.go Normal file
View File

@ -0,0 +1,187 @@
package oracle
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
type OracleMatcher struct {
sendPackets []*packet.Packet
}
func (o *OracleMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
header := header_packet{}
refuse := body_refuse{}
buf := new(bytes.Buffer)
buf.Write(packet.Buffer)
binary.Read(buf, binary.BigEndian, &header)
binary.Read(buf, binary.BigEndian, &refuse)
//fmt.Println(header)
//fmt.Println(refuse)
if header.Check_sum != 0 {
return false
}
if header.Types != 4 {
return false
}
if header.Reserved_byte != 0 {
return false
}
if header.Header_sum != 0 {
return false
}
if refuse.Reason_user != 34 {
return false
}
if refuse.Reason_system != 0 {
return false
}
var dataLen int = int(refuse.Data_len)
if dataLen != packet.Len-12 {
return false
}
return true
}
func (o *OracleMatcher) PacketCount() int {
return len(o.sendPackets)
}
func (o *OracleMatcher) Packet(index int) *packet.Packet {
return o.sendPackets[index]
}
func (o *OracleMatcher) ServiceName() string {
return "OracleMatcher"
}
func (o *OracleMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (o *OracleMatcher) IsNoResponse(index int) bool {
return false
}
func (o *OracleMatcher) IsPrePacket() bool {
return true
}
func NewOracleMatcher() *OracleMatcher {
pm := OracleMatcher{}
hp := header_packet{
Length: 247,
Check_sum: 0,
Types: 1,
Reserved_byte: 0,
Header_sum: 0,
}
bc := body_connect{
Version: 315,
Version_compatible: 300,
//Service_options:
Session_unit_size: 8192,
Maxumum_trans_data_unit_size: 65535,
//Nt_protocol_characteristics:
Line_turnaround_value: 0,
Value_of_1_in_hardware: 1,
Length_of_connect_data: 177,
Offset_to_connect_data: 70,
Maximum_receivable_connect_data: 0,
//Connect_flag0:
//Connect_flag1:
Trace_cross_facility_item_1: 0,
Trace_cross_facility_item_2: 0,
Trace_unique_connection_id: 0,
//Unknown_data:
//Connect_data:
}
bc.Service_options[0] = 0x0c
bc.Service_options[1] = 0x41
bc.Nt_protocol_characteristics[0] = 0x4f
bc.Nt_protocol_characteristics[1] = 0x98
bc.Connect_flag0 = 0x81
bc.Connect_flag1 = 0x81
bc.Unknown_data[10] = 0x20
bc.Unknown_data[13] = 0x20
conDataStr := "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.30)(PORT=1521))(CONNECT_DATA=(CID=(PROGRAM=JDBC Thin Client)(HOST=__jdbc__)(USER=loafle.match))(SERVICE_NAME=oracle.loafle.com.match)))"
connect_data := make([]byte, len(conDataStr))
copy(connect_data, conDataStr)
hpBuf := new(bytes.Buffer)
binary.Write(hpBuf, binary.BigEndian, hp)
hpBt := hpBuf.Bytes()
bcBuf := new(bytes.Buffer)
binary.Write(bcBuf, binary.BigEndian, bc)
bcBt := bcBuf.Bytes()
byteSize := len(hpBt) + len(bcBt) + len(conDataStr)
sendByte := make([]byte, byteSize)
copy(sendByte[0:], hpBt)
copy(sendByte[len(hpBt):], bcBt)
copy(sendByte[len(hpBt)+len(bcBt):], connect_data)
pm.sendPackets = append(pm.sendPackets, packet.NewPacket(sendByte, byteSize))
return &pm
}
type header_packet struct {
Length uint16
Check_sum uint16
Types byte
Reserved_byte byte
Header_sum uint16
}
type body_connect struct {
Version uint16
Version_compatible uint16
Service_options [2]byte
Session_unit_size uint16
Maxumum_trans_data_unit_size uint16
Nt_protocol_characteristics [2]byte
Line_turnaround_value uint16
Value_of_1_in_hardware uint16
Length_of_connect_data uint16
Offset_to_connect_data uint16
Maximum_receivable_connect_data uint32
Connect_flag0 byte
Connect_flag1 byte
Trace_cross_facility_item_1 uint32
Trace_cross_facility_item_2 uint32
Trace_unique_connection_id uint64
Unknown_data [20]byte
//Connect_data []byte
}
type body_refuse struct {
Reason_user byte
Reason_system byte
Data_len uint16
//Data []byte
}

View File

@ -0,0 +1,53 @@
package oracle
//
//import (
// "fmt"
// "loafle.com/overflow/collector/discovery/scan/matcher/packet"
// "loafle.com/overflow/collector/discovery/scan/matcher/scaninfo"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestOracle(t *testing.T) {
//
// lm := NewOracleMatcher()
//
// port := types.NewPort("1521", types.NewHost("192.168.1.30"), types.TYPE_TCP)
// scanInfo := scaninfo.NewServiceScanInfo(port)
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// fmt.Println(ipport)
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// fmt.Println(lm.PacketCount())
//
// for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// fmt.Println(pack)
//
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 1024)
//
// read, _ := client.Read(bytes)
//
// fmt.Println(bytes)
//
// b := lm.Match(ii, packet.NewPacket(bytes, read), scanInfo)
//
// if b {
// t.Log("Good")
// }
//
// }
//
// t.Log(scanInfo)
//
//}

13
matcher/packet/packet.go Normal file
View File

@ -0,0 +1,13 @@
package packet
type Packet struct {
Buffer []byte
Len int
}
func NewPacket(buf []byte, len int) *Packet {
return &Packet{
Buffer: buf,
Len: len,
}
}

73
matcher/pop/pop.go Normal file
View File

@ -0,0 +1,73 @@
package pop
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
COMPARE_STR = "+OK"
)
type POPMatcher struct {
sendPackets []*packet.Packet
}
func (p *POPMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
switch index {
case 0:
fallthrough
case 1:
recvStr := string(packet.Buffer)
if len(recvStr) < 3 {
return false
}
compareStr := recvStr[0:3]
if compareStr == COMPARE_STR {
return true
}
}
return false
}
func (p *POPMatcher) PacketCount() int {
return len(p.sendPackets)
}
func (p *POPMatcher) Packet(index int) *packet.Packet {
return p.sendPackets[index]
}
func (p *POPMatcher) ServiceName() string {
return "POPMatcher"
}
func (p *POPMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (p *POPMatcher) IsNoResponse(index int) bool {
return false
}
func (p *POPMatcher) IsPrePacket() bool {
return true
}
func NewPOPMatcher() *POPMatcher {
pm := POPMatcher{}
reqStr := "QUIT\r\n"
byte := make([]byte, len(reqStr))
copy(byte[:], reqStr)
pm.sendPackets = append(pm.sendPackets, packet.NewPacket(byte, len(reqStr)))
return &pm
}

86
matcher/pop/pop_test.go Normal file
View File

@ -0,0 +1,86 @@
package pop
//
//import (
// "crypto/tls"
// "fmt"
// "loafle.com/overflow/collector/discovery/scan/matcher/packet"
// "loafle.com/overflow/collector/discovery/scan/matcher/scaninfo"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestPopTLS(t *testing.T) {
// conn, _ := tls.Dial(
// "tcp",
// "192.168.1.215:995",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.215",
// },
// )
//
// defer conn.Close()
//
// pop3Run(conn, t)
//}
//
//func TestPopNor(t *testing.T) {
//
// client, _ := net.Dial("tcp", "192.168.1.215:110")
//
// defer client.Close()
//
// pop3Run(client, t)
//
//}
//
//func pop3Run(client net.Conn, t *testing.T) {
//
// lm := NewPOPMatcher()
//
// port := types.NewPort("110", types.NewHost("192.168.1.215"), types.TYPE_TCP)
// scanInfo := scaninfo.NewServiceScanInfo(port)
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// fmt.Println(ipport)
//
// bytett := make([]byte, 1024)
//
// read, _ := client.Read(bytett)
//
// bb := lm.Match(0, packet.NewPacket(bytett, read), scanInfo)
//
// if bb {
// t.Log("good!")
// }
//
// fmt.Println(lm.PacketCount())
//
// for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// //fmt.Println(pack)
//
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 1024)
//
// rr, _ := client.Read(bytes)
//
// //fmt.Println(bytes)
//
// b := lm.Match(ii+1, packet.NewPacket(bytes, rr), scanInfo)
//
// if b {
// t.Log("send Good!")
// }
//
// }
//
// t.Log(scanInfo)
//
//}

76
matcher/redis/redis.go Normal file
View File

@ -0,0 +1,76 @@
package redis
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
"strings"
)
const REDIS_PING string = "*1\r\n$4\r\nping\r\n"
type RedisMatcher struct {
packets []*packet.Packet
}
func NewRedisMatcher() *RedisMatcher {
redisMatcher := &RedisMatcher{}
redisMatcher.packets = append(redisMatcher.packets, packet.NewPacket([]byte(REDIS_PING), len(REDIS_PING)))
return redisMatcher
}
func (t *RedisMatcher) ServiceName() string {
return "Redis"
}
func (t *RedisMatcher) PacketCount() int {
return len(t.packets)
}
func (t *RedisMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *RedisMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *RedisMatcher) IsNoResponse(index int) bool {
return false
}
func (t *RedisMatcher) IsPrePacket() bool {
return false
}
func (t *RedisMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
resp := strings.Split(string(packet.Buffer), "\r\n")[0]
if len(resp) <= 0 {
return false
}
sign := string([]rune(resp)[0])
if len(sign) <= 0 {
return false
}
if sign == "+" {
if resp == "+PONG" || resp == "+OK" {
return true
}
}
if sign == "-" {
if resp == "-NOAUTH" || resp == "-ERR" {
return true
}
}
return false
}

View File

@ -0,0 +1,78 @@
package redis
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
COMPARE_STR_1 = "-"
COMPARE_STR_2 = "DENIED"
)
type RedisProtectedMatcher struct {
}
func NewRedisProtectedMatcher() *RedisProtectedMatcher {
redisMatcher := &RedisProtectedMatcher{}
return redisMatcher
}
func (r *RedisProtectedMatcher) ServiceName() string {
return "RedisProtectedMatcher"
}
func (r *RedisProtectedMatcher) PacketCount() int {
return 0
}
func (r *RedisProtectedMatcher) Packet(index int) *packet.Packet {
return nil
}
func (r *RedisProtectedMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (r *RedisProtectedMatcher) IsNoResponse(index int) bool {
return false
}
func (r *RedisProtectedMatcher) IsPrePacket() bool {
return true
}
func (r *RedisProtectedMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
switch index {
case 0:
str := string(packet.Buffer[:packet.Len])
if str == "" {
return false
}
if len(str) <= 0 {
return false
}
firstCompare := str[0:1]
seconcdCompare := str[1 : len(COMPARE_STR_2)+1]
if firstCompare != COMPARE_STR_1 {
return false
}
if seconcdCompare != COMPARE_STR_2 {
return false
}
return true
}
return false
}

View File

@ -0,0 +1,33 @@
package redis
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestRedisProtected(t *testing.T) {
//
// m := NewRedisProtectedMatcher()
//
// conn, err := net.Dial("tcp", "192.168.1.215:8379")
//
// if err != nil {
// t.Log(err)
// return
// }
//
// defer conn.Close()
//
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
//
// //fmt.Println(string(bytes[:n]))
//
// b := m.Match(0, packet.NewPacket(bytes, n), nil)
//
// if b {
// t.Log("good!")
// }
//
//}

View File

@ -0,0 +1,38 @@
package redis
//
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//const (
// ADDR string = "192.168.1.215:6379"
//)
//
//func TestRedisMatcher(t *testing.T) {
//
// m := NewRedisMatcher()
//
// conn, _ := net.Dial("tcp", ADDR)
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
//
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("Redis found.")
// return
// }
//
// t.Error("Redis not found")
// }
//
//}

111
matcher/rmi/rmi.go Normal file
View File

@ -0,0 +1,111 @@
package rmi
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
MAGIC_NUMBER = 0x4a524d49
STREAM_PROTOCOL = 0x4b
VERSION = 0x0002
ACK_PROTOCOL = 0x4e
)
type RMI_SEND_MESSAGE struct {
magic uint32
version uint16
protocol uint8
}
type RMI_RECV_MESSAGE struct {
streamMessage uint8
packetLen uint16
host []byte
port [2]byte
}
type RMIMatcher struct {
sendPackets []*packet.Packet
}
func (r *RMIMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
result := false
if packet == nil || packet.Buffer == nil || packet.Len == 0 {
return result
}
//fmt.Println("packet :", packet)
rmiRecv := RMI_RECV_MESSAGE{}
buf := bytes.NewReader(packet.Buffer)
binary.Read(buf, binary.BigEndian, &rmiRecv.streamMessage)
binary.Read(buf, binary.BigEndian, &rmiRecv.packetLen)
lenInt := int(rmiRecv.packetLen)
var tempHost = make([]byte, lenInt, lenInt)
copy(rmiRecv.host, tempHost)
rmiRecv.host = tempHost
binary.Read(buf, binary.BigEndian, &rmiRecv.host)
binary.Read(buf, binary.BigEndian, &rmiRecv.port)
hostIp := string(rmiRecv.host[:lenInt])
//fmt.Println(hostIp)
//hostPort := binary.BigEndian.Uint16(rmiRecv.port[:2])
if rmiRecv.streamMessage == ACK_PROTOCOL && lenInt == len(hostIp) {
result = true
}
return result
}
func (r *RMIMatcher) PacketCount() int {
return len(r.sendPackets)
}
func (r *RMIMatcher) Packet(index int) *packet.Packet {
return r.sendPackets[index]
}
func (r *RMIMatcher) ServiceName() string {
return "RMI"
}
func (r *RMIMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (r *RMIMatcher) IsNoResponse(index int) bool {
return false
}
func (r *RMIMatcher) IsPrePacket() bool {
return false
}
func NewRMIMatcher() *RMIMatcher {
r := RMIMatcher{}
rsm := RMI_SEND_MESSAGE{
magic: MAGIC_NUMBER,
version: VERSION,
protocol: STREAM_PROTOCOL,
}
mCache := new(bytes.Buffer)
binary.Write(mCache, binary.BigEndian, rsm)
sendByte1 := mCache.Bytes()
pp := packet.NewPacket(sendByte1, len(sendByte1))
r.sendPackets = append(r.sendPackets, pp)
return &r
}

48
matcher/rmi/rmi_test.go Normal file
View File

@ -0,0 +1,48 @@
package rmi
//import (
// "fmt"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestNew(t *testing.T) {
// r := NewRMIMatcher()
// fmt.Println("TestNew: ", r)
//}
//func TestRMIMatcher_Match(t *testing.T) {
//
// fmt.Println("Match")
//
// hm := NewRMIMatcher()
//
// port := types.NewPort("9840", types.NewHost("192.168.1.101"), types.TYPE_TCP)
//
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// //fmt.Println(ipport)
//
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// pack := hm.Packet(0)
//
// fmt.Println(pack.Buffer)
//
// //writer.WriteString(pack)
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 512)
//
// l, _ := client.Read(bytes)
//
// //fmt.Println(bytes)
//
// t1 := hm.Match(0, packet.NewPacket(bytes, l), nil)
//
// fmt.Println(t1)
//}

161
matcher/smb/smb.go Normal file
View File

@ -0,0 +1,161 @@
package smb
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
"strings"
)
const (
SMB_COM_NEGOTIATE uint8 = 0x72
SMB_SUCCESS uint8 = 0x00
)
type netBIOS struct {
MsgType byte
MsgLength [3]uint8
}
type smb struct {
NetBios netBIOS
Component [4]uint8
SmbCommand uint8
NtStatus [4]uint8
Flags uint8
Flags2 [2]uint8
ProcessId uint16
Signature uint64
Reserved uint16
Tid uint16
Pid uint16
Uid uint16
Mid uint16
Wct uint8
Bcc uint16
Bf1 uint8
Name1 [23]uint8
Bf2 uint8
Name2 [10]uint8
Bf3 uint8
Name3 [28]uint8
Bf4 uint8
Name4 [10]uint8
Bf5 uint8
Name5 [10]uint8
Bf6 uint8
Name6 [11]uint8
}
type SMBMatcher struct {
packets []*packet.Packet
}
func NewSMBMatcher() *SMBMatcher {
nbssMatcher := &SMBMatcher{}
query := smb{}
query.NetBios.MsgType = 0x00
query.NetBios.MsgLength[2] = 0x85
query.Component[0] = 0xff
query.Component[1] = 'S'
query.Component[2] = 'M'
query.Component[3] = 'B'
query.SmbCommand = SMB_COM_NEGOTIATE
query.NtStatus[3] = SMB_SUCCESS
query.Flags = 0x18
query.Flags2[0] = 0x53
query.Flags2[1] = 0xC8
query.ProcessId = 0x00
query.Signature = 0x00
query.Reserved = 0
query.Tid = 0
query.Pid = 0xfeff
query.Uid = 0
query.Mid = 0
query.Wct = 0
query.Bcc = 0x0062
query.Bf1 = 0x02
copy(query.Name1[:], "PC NETWORK PROGRAM 1.0")
query.Bf2 = 0x02
copy(query.Name2[:], "LANMAN1.0")
query.Bf3 = 0x02
copy(query.Name3[:], "Windows for Workgroups 3.1a")
query.Bf4 = 0x02
copy(query.Name4[:], "LM1.2X002")
query.Bf5 = 0x02
copy(query.Name5[:], "LANMAN2.1")
query.Bf6 = 0x02
copy(query.Name6[:], "NT LM 0.12")
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, query)
nbssMatcher.packets = append(nbssMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return nbssMatcher
}
func (t *SMBMatcher) ServiceName() string {
return "SMB"
}
func (t *SMBMatcher) PacketCount() int {
return len(t.packets)
}
func (t *SMBMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *SMBMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *SMBMatcher) IsNoResponse(index int) bool {
return false
}
func (t *SMBMatcher) IsPrePacket() bool {
return false
}
func (t *SMBMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
s := smb{}
if err := binary.Read(reader, binary.BigEndian, &s); err != nil {
return false
}
var des [4]byte
copy(des[1:], s.NetBios.MsgLength[:])
packetLen := binary.BigEndian.Uint32(des[:])
if packetLen != uint32(packet.Len-4) {
return false
}
if !strings.Contains(string(s.Component[:]), "SMB") {
return false
}
return true
}

37
matcher/smb/smb_test.go Normal file
View File

@ -0,0 +1,37 @@
package smb
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//const (
// ADDR string = "192.168.1.104:139"
//)
//
//func TestSMBMatcher(t *testing.T) {
//
// m := NewSMBMatcher()
//
// conn, _ := net.Dial("tcp", ADDR)
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
//
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("SMB found.")
// return
// }
//
// t.Error("SMB not found")
// }
//
//}

71
matcher/smtp/smtp.go Normal file
View File

@ -0,0 +1,71 @@
package smtp
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
"strings"
)
type SmtpMatcher struct {
packets []*packet.Packet
}
func NewSmtpMatcher() *SmtpMatcher {
m := &SmtpMatcher{}
b := []byte("helo test\r\n")
m.packets = append(m.packets, packet.NewPacket(b, len(b)))
b = []byte("quit\r\n")
m.packets = append(m.packets, packet.NewPacket(b, len(b)))
return m
}
func (t *SmtpMatcher) ServiceName() string {
return "SMTP"
}
func (t *SmtpMatcher) PacketCount() int {
return len(t.packets)
}
func (t *SmtpMatcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *SmtpMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *SmtpMatcher) IsNoResponse(index int) bool {
return false
}
func (t *SmtpMatcher) IsPrePacket() bool {
return true
}
func (t *SmtpMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
buf := string(packet.Buffer)
if len(buf) == 0 || len(buf) < 5 {
return false
}
splits := strings.Split(buf, "\r\n")
splits = strings.Split(buf, " ")
if index == 0 {
if splits[0] == "220" {
return true
}
} else if index == 1 {
if splits[0] == "250" {
return true
}
} else if index == 2 {
if splits[0] == "221" {
return true
}
}
return false
}

68
matcher/smtp/smtp_test.go Normal file
View File

@ -0,0 +1,68 @@
package smtp
//
//import (
// "crypto/tls"
// "fmt"
// "github.com/stretchr/testify/assert"
// "net"
// "strings"
// "testing"
//)
//
//func TestSMTPTLS(t *testing.T) {
//
// conn, err := tls.Dial("tcp",
// "192.168.1.215:465",
// &tls.Config{
// InsecureSkipVerify: true,
// ServerName: "192.168.1.215",
// },
// )
//
// if err != nil {
// t.Log(err)
// return
// }
//
// b := make([]byte, 1024)
//
// check(t, b, conn, "", "220")
// check(t, b, conn, "helo test\r\n", "250")
// check(t, b, conn, "quit\r\n", "221")
//
// conn.Close()
//}
//
//func TestSMTP(t *testing.T) {
//
// conn, _ := net.Dial("tcp", "192.168.1.215:25")
//
// b := make([]byte, 1024)
//
// check(t, b, conn, "", "220")
// check(t, b, conn, "helo test\r\n", "250")
// check(t, b, conn, "quit\r\n", "221")
//
// conn.Close()
//
//}
//func check(t *testing.T, b []byte, conn net.Conn, cmd string, compare string) {
//
// if cmd != "" {
// wlen, _ := conn.Write([]byte(cmd))
// assert.Equal(t, wlen, len(cmd))
// }
//
// rlen, _ := conn.Read(b)
//
// fmt.Println(rlen)
// fmt.Println(len(b))
//
// data := string(b[:rlen])
// fmt.Println(data)
// assert.Equal(t, true, rlen > 4)
// splits := strings.Split(data, " ")
// assert.Equal(t, compare, splits[0])
//
//}

200
matcher/snmp/snmpv2.go Normal file
View File

@ -0,0 +1,200 @@
package snmp
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
SNMP_START_SEQUENCE uint8 = 0X30
SNMP_TYPE_INTEGER uint8 = 0X02
SNMP_TYPE_STRING uint8 = 0X04
SNMP_TYPE_NULL uint8 = 0X05
SNMP_TYPE_OBJECT uint8 = 0X06
SNMP_GET_REQUEST uint8 = 0XA0
//SNMP_RESPONSE uint8 = 0XA2
SNMP_NO_DESC uint16 = 0X0004
SNMP_END_SEQUENCE uint8 = 0X30
SNMP_PROTOCOL_VERSION_3 uint8 = 0X03
SNMP_PROTOCOL_VERSION_2c uint8 = 0X01
SNMP_MSG_ID_MAX_VALUE uint32 = 0xFFFFFF7F
)
type snmpv2VarBinding struct {
VarBindindStart uint8
VarBindLen uint8
ObjectStart uint8
ObjectLen uint8
ValueType uint8
ValueLen uint8
ObjectValue uint64
NullValue uint8
EndIndicator uint8
}
type snmpv2Data struct {
DataType uint8
DataLen uint8
RequestIdType uint8
RequestIdLen uint8
RequestId uint8
ErrorStatusType uint8
ErrorStatusLen uint8
ErrorStatus uint8
ErrorIndexType uint8
ErrorIndexLen uint8
ErrorIndex uint8
VarBinding snmpv2VarBinding
}
type snmpv2 struct {
StartSeq uint8
SeqLen uint8
SNMPVersionType uint8
SNMPVersionLen uint8
SNMPVersion uint8
CommunityVersionType uint8
CommunityVersionLen uint8
Community [6]byte
Data snmpv2Data
}
type SNMPv2Matcher struct {
packets []*packet.Packet
}
func NewSNMPv2Matcher() *SNMPv2Matcher {
snmpMatcher := &SNMPv2Matcher{}
snmpTempBuf := new(bytes.Buffer)
binary.Write(snmpTempBuf, binary.BigEndian, snmpv2{}) //For getting the struct size
snmpDataTempBuf := new(bytes.Buffer)
binary.Write(snmpDataTempBuf, binary.BigEndian, snmpv2Data{}) //For getting the struct size
snmpVarTempBuf := new(bytes.Buffer)
binary.Write(snmpVarTempBuf, binary.BigEndian, snmpv2VarBinding{}) //For getting the struct size
q := snmpv2{}
q.StartSeq = SNMP_START_SEQUENCE
q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2
q.SNMPVersionType = SNMP_TYPE_INTEGER
q.SNMPVersionLen = 0x01
q.SNMPVersion = SNMP_PROTOCOL_VERSION_2c
q.CommunityVersionType = SNMP_TYPE_STRING
q.CommunityVersionLen = 0x06
var community [6]byte
copy(community[:], "public")
q.Community = community
q.Data.DataType = SNMP_GET_REQUEST
q.Data.DataLen = uint8(len(snmpDataTempBuf.Bytes())) - 2
q.Data.RequestIdType = SNMP_TYPE_INTEGER
q.Data.RequestIdLen = 0x01
q.Data.RequestId = 0x01
q.Data.ErrorStatusType = SNMP_TYPE_INTEGER
q.Data.ErrorStatusLen = 0x01
q.Data.ErrorStatus = 0x00
q.Data.ErrorIndexType = SNMP_TYPE_INTEGER
q.Data.ErrorIndexLen = 0x01
q.Data.ErrorIndex = 0x00
q.Data.VarBinding.VarBindindStart = SNMP_START_SEQUENCE
q.Data.VarBinding.VarBindLen = uint8(len(snmpVarTempBuf.Bytes())) - 2
q.Data.VarBinding.ObjectStart = SNMP_START_SEQUENCE
q.Data.VarBinding.ObjectLen = uint8(len(snmpVarTempBuf.Bytes())) - 4
q.Data.VarBinding.ValueType = SNMP_TYPE_OBJECT
q.Data.VarBinding.ValueLen = 0x08
q.Data.VarBinding.ObjectValue = 0x000001010201062b
q.Data.VarBinding.NullValue = SNMP_TYPE_NULL
q.Data.VarBinding.EndIndicator = 0x00
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, q)
snmpMatcher.packets = append(snmpMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return snmpMatcher
}
func (t *SNMPv2Matcher) ServiceName() string {
return "SNMP"
}
func (t *SNMPv2Matcher) PacketCount() int {
return len(t.packets)
}
func (t *SNMPv2Matcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *SNMPv2Matcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *SNMPv2Matcher) IsNoResponse(index int) bool {
return false
}
func (t *SNMPv2Matcher) IsPrePacket() bool {
return false
}
func (t *SNMPv2Matcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
r := new(bytes.Buffer)
r.Write(packet.Buffer)
s := snmpv2{}
if err := binary.Read(r, binary.BigEndian, &s); err != nil {
return false
}
if s.StartSeq != SNMP_START_SEQUENCE {
return false
}
var p uint8
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
for idx := 0; idx < 5; idx++ {
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
return false
}
if p == SNMP_TYPE_INTEGER {
break
}
p++
}
//finding protocol version type : 0x02 0x01 0x01
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
return false
}
if p == 0x01 {
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
return false
}
if p == 0x01 {
return true
}
}
return false
}
func (t *SNMPv2Matcher) IsSend(port int) bool {
if port == 161 {
return true
}
return false
}

View File

@ -0,0 +1,37 @@
package snmp
//
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestSNMP2(t *testing.T) {
//
// m := NewSNMPv2Matcher()
//
// conn, err := net.Dial("udp", "192.168.1.215:161")
// if err != nil {
// t.Error(err)
// return
// }
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("SNMP found")
// return
// }
//
// t.Error("SNMP not found")
// }
//
//}

218
matcher/snmp/snmpv3.go Normal file
View File

@ -0,0 +1,218 @@
package snmp
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
type snmpv3GlobalData struct {
GlobalDataStartSeq uint8
GlobalDataLen uint8
MsgIdType uint8
MsgIdLen uint8
MsgId uint32
MsgMaxSizeType uint8
MsgMaxSizeLen uint8
MsgMaxSize [3]uint8
MsgFlagsType uint8
MsgFlagsTypeLen uint8
MsgFlags uint8
MsgSecurityModelType uint8
MsgSecurityModelLen uint8
MsgSecurityModel uint8
}
type snmpv3MsgData struct {
MsgDataStartSeq uint8
MsgDataLen uint8
ContextEngineId uint16
ContextEngineName uint16
SnmpType uint8
Len uint8
RequestIdType uint8
RequestIdLen uint8
RequestId uint32
ErrorStatusType uint8
ErrorStatusLen uint8
ErrorStatus uint8
ErrorIndexType uint8
ErrorIndexLen uint8
ErrorIndex uint8
EndSeq uint8
EndIndicator uint8
}
type snmpv3 struct {
StartSeq uint8
SeqLen uint8
SNMPVersionType uint8
SNMPVersionLen uint8
SNMPVersion uint8
MsgGlobalData snmpv3GlobalData
Unk1 uint16
Unk2 uint16
MsgAuthoritativeEngineId uint16
MsgAuthoritativeEngineBootsType uint8
MsgAuthoritativeEngineBootsLen uint8
MsgAuthoritativeEngineBoots uint8
MsgAuthoritativeEngineTimeType uint8
MsgAuthoritativeEngineTimeLen uint8
MsgAuthoritativeEngineTime uint8
MsgUserName uint16
MsgAuthenticationParam uint16
MsgPrivacyParam uint16
MsgData snmpv3MsgData
}
type SNMPv3Matcher struct {
packets []*packet.Packet
}
func NewSNMPv3Matcher() *SNMPv3Matcher {
snmpMatcher := &SNMPv3Matcher{}
snmpTempBuf := new(bytes.Buffer)
binary.Write(snmpTempBuf, binary.BigEndian, snmpv3{}) //For getting the struct size
snmpMsgDataTempBuf := new(bytes.Buffer)
binary.Write(snmpMsgDataTempBuf, binary.BigEndian, snmpv3MsgData{}) //For getting the struct size
snmpGlobalTempBuf := new(bytes.Buffer)
binary.Write(snmpGlobalTempBuf, binary.BigEndian, snmpv3GlobalData{}) //For getting the struct size
q := snmpv3{}
q.StartSeq = SNMP_START_SEQUENCE
q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2
q.SNMPVersionType = SNMP_TYPE_INTEGER
q.SNMPVersionLen = 0x01
q.SNMPVersion = SNMP_PROTOCOL_VERSION_3
q.MsgGlobalData.GlobalDataStartSeq = SNMP_START_SEQUENCE
q.MsgGlobalData.GlobalDataLen = uint8(len(snmpGlobalTempBuf.Bytes())) - 2
q.MsgGlobalData.MsgIdType = SNMP_TYPE_INTEGER
q.MsgGlobalData.MsgIdLen = 0x04
q.MsgGlobalData.MsgId = SNMP_MSG_ID_MAX_VALUE
q.MsgGlobalData.MsgMaxSizeType = SNMP_TYPE_INTEGER
q.MsgGlobalData.MsgMaxSizeLen = 0x03
q.MsgGlobalData.MsgMaxSize[2] = 0xe3
q.MsgGlobalData.MsgMaxSize[1] = 0xff
q.MsgGlobalData.MsgMaxSize[0] = 0x00
q.MsgGlobalData.MsgFlagsType = SNMP_TYPE_STRING
q.MsgGlobalData.MsgFlagsTypeLen = 0x01
q.MsgGlobalData.MsgFlags = 0x04
q.MsgGlobalData.MsgSecurityModelType = SNMP_TYPE_INTEGER
q.MsgGlobalData.MsgSecurityModelLen = 0x01
q.MsgGlobalData.MsgSecurityModel = 0x03
q.Unk1 = 0x1004
q.Unk2 = 0x0e30
q.MsgAuthoritativeEngineId = SNMP_NO_DESC
q.MsgAuthoritativeEngineBootsType = SNMP_TYPE_INTEGER
q.MsgAuthoritativeEngineBootsLen = 0x01
q.MsgAuthoritativeEngineBoots = 0x00
q.MsgAuthoritativeEngineTimeType = SNMP_TYPE_INTEGER
q.MsgAuthoritativeEngineTimeLen = 0x01
q.MsgAuthoritativeEngineTime = 0x00
q.MsgUserName = SNMP_NO_DESC
q.MsgAuthenticationParam = SNMP_NO_DESC
q.MsgPrivacyParam = SNMP_NO_DESC
q.MsgData.MsgDataStartSeq = SNMP_START_SEQUENCE
q.MsgData.MsgDataLen = uint8(len(snmpMsgDataTempBuf.Bytes())) - 2
q.MsgData.ContextEngineId = SNMP_NO_DESC
q.MsgData.ContextEngineName = SNMP_NO_DESC
q.MsgData.SnmpType = SNMP_GET_REQUEST
q.MsgData.Len = 0x0E
q.MsgData.RequestIdType = SNMP_TYPE_INTEGER
q.MsgData.RequestIdLen = 0x04
q.MsgData.RequestId = 0x00 //
q.MsgData.ErrorStatusType = SNMP_TYPE_INTEGER
q.MsgData.ErrorStatusLen = 0x01
q.MsgData.ErrorStatus = 0x00
q.MsgData.ErrorIndexType = SNMP_TYPE_INTEGER
q.MsgData.ErrorIndexLen = 0x01
q.MsgData.ErrorIndex = 0x00
q.MsgData.EndSeq = SNMP_END_SEQUENCE
q.MsgData.EndIndicator = 0x00
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, q)
snmpMatcher.packets = append(snmpMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return snmpMatcher
}
func (t *SNMPv3Matcher) ServiceName() string {
return "SNMP"
}
func (t *SNMPv3Matcher) PacketCount() int {
return len(t.packets)
}
func (t *SNMPv3Matcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *SNMPv3Matcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *SNMPv3Matcher) IsNoResponse(index int) bool {
return false
}
func (t *SNMPv3Matcher) IsPrePacket() bool {
return false
}
func (t *SNMPv3Matcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
s := snmpv3{}
if err := binary.Read(reader, binary.LittleEndian, &s); err != nil {
return false
}
if s.StartSeq != SNMP_START_SEQUENCE {
return false
}
var p uint8
r := new(bytes.Buffer)
r.Write(packet.Buffer)
for {
binary.Read(r, binary.LittleEndian, &p)
if p == SNMP_TYPE_INTEGER {
break
}
}
binary.Read(r, binary.BigEndian, &p)
if p == 0x01 {
binary.Read(r, binary.BigEndian, &p)
if p == 0x03 {
return true
}
}
return false
}
func (t *SNMPv3Matcher) IsSend(port int) bool {
if port == 161 {
return true
}
return false
}

View File

@ -0,0 +1,37 @@
package snmp
//
//import (
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "net"
// "testing"
//)
//
//func TestSNMP3(t *testing.T) {
//
// m := NewSNMPv3Matcher()
//
// conn, err := net.Dial("udp", "192.168.1.254:161")
// if err != nil {
// t.Error(err)
// return
// }
// defer conn.Close()
//
// for i := 0; i < m.PacketCount(); i++ {
//
// pack := m.Packet(i)
// conn.Write(pack.Buffer)
// bytes := make([]byte, 1024)
// n, _ := conn.Read(bytes)
// p := packet.NewPacket(bytes, n)
//
// if m.Match(i, p, nil) {
// t.Log("SNMP found")
// return
// }
//
// t.Error("SNMP not found")
// }
//
//}

66
matcher/ssh/ssh.go Normal file
View File

@ -0,0 +1,66 @@
package ssh
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
"strings"
)
type SSHMatcher struct {
sendPackets []*packet.Packet
}
func (ssh *SSHMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
result := false
if packet == nil || packet.Buffer == nil || packet.Len == 0 {
return result
}
str := string(packet.Buffer)
//fmt.Println(str)
temps := strings.Split(str, " ")
protocol := strings.Split(temps[0], "-")
//osType := temps[1]
if 0 == strings.Compare(protocol[0], "SSH") {
majorVersion := protocol[1]
//fmt.Println(majorVersion)
if 0 == strings.Compare(majorVersion, "2.0") || 0 == strings.Compare(majorVersion, "1.0") {
result = true
}
}
return result
}
func (ssh *SSHMatcher) PacketCount() int {
return len(ssh.sendPackets)
}
func (ssh *SSHMatcher) Packet(index int) *packet.Packet {
return ssh.sendPackets[index]
}
func (ssh *SSHMatcher) ServiceName() string {
return "SSH"
}
func (ssh *SSHMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (ssh *SSHMatcher) IsNoResponse(index int) bool {
return false
}
func (ssh *SSHMatcher) IsPrePacket() bool {
return true
}
func NewSSHMatcher() *SSHMatcher {
r := SSHMatcher{}
return &r
}

33
matcher/ssh/ssh_test.go Normal file
View File

@ -0,0 +1,33 @@
package ssh
//import (
// "fmt"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestSSHMatcher_Match(t *testing.T) {
//
// port := types.NewPort("22", types.NewHost("192.168.1.103"), types.TYPE_TCP)
// ssh := NewSSHMatcher()
//
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// bytes := make([]byte, 512)
//
// l, _ := client.Read(bytes)
//
// fmt.Println(bytes)
//
// b := ssh.Match(0, packet.NewPacket(bytes, l), nil)
//
// fmt.Println(b)
//
//}

79
matcher/telnet/telnet.go Normal file
View File

@ -0,0 +1,79 @@
package telnet
import (
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
DO = 0xfd
WONT = 0x4b
WILL = 0xfb
DONT = 0xfe
CMD = 0xff
)
type TelnetMatcher struct {
sendPackets []*packet.Packet
}
func (tel *TelnetMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
result := false
if packet == nil || packet.Buffer == nil || packet.Len == 0 {
return result
}
buf := make([]byte, 0, 0)
count := 0
for i := 0; i < len(packet.Buffer); i++ {
if packet.Buffer[i] > 0 {
buf = append(buf, packet.Buffer[i])
} else if count > 2 {
break
} else {
count++
}
}
for idx := 0; idx < len(buf); idx += 3 {
if buf[idx] == CMD && (buf[idx+1] == DO || buf[idx+1] == WONT || buf[idx+1] == WILL || buf[idx+1] == DONT) {
result = true
} else {
result = false
}
}
return result
}
func (tel *TelnetMatcher) PacketCount() int {
return len(tel.sendPackets)
}
func (tel *TelnetMatcher) Packet(index int) *packet.Packet {
return tel.sendPackets[index]
}
func (tel *TelnetMatcher) ServiceName() string {
return "Telnet"
}
func (tel *TelnetMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (tel *TelnetMatcher) IsNoResponse(index int) bool {
return false
}
func (tel *TelnetMatcher) IsPrePacket() bool {
return true
}
func NewTelnetMatcher() *TelnetMatcher {
r := TelnetMatcher{}
return &r
}

View File

@ -0,0 +1,33 @@
package telnet
//import (
// "fmt"
// "loafle.com/overflow/collector/core/scan/service/matcher/packet"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestTelnetMatcher_Match(t *testing.T) {
//
// port := types.NewPort("23", types.NewHost("192.168.1.210"), types.TYPE_TCP)
// telnet := NewTelnetMatcher()
//
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// bytes := make([]byte, 512)
//
// l, _ := client.Read(bytes)
//
// fmt.Println("length :", l)
// fmt.Println(bytes)
//
// b := telnet.Match(0, packet.NewPacket(bytes, l), nil)
//
// fmt.Println(b)
//}

250
matcher/wmi/wmi.go Normal file
View File

@ -0,0 +1,250 @@
package wmi
import (
"bytes"
"encoding/binary"
"loafle.com/overflow/commons_go/matcher/packet"
"loafle.com/overflow/commons_go/model/scaninfo"
)
const (
PDU_BIND = 11
PDU_BIND_ACK = 12
PDU_REQ = 0
PDU_RESP = 2
WMI_CALL_ID_1 = 0x95
WMI_CALL_ID_2 = 0x96
)
type WMIMatcher struct {
sendPackets []*packet.Packet
}
func (w *WMIMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
buf := new(bytes.Buffer)
buf.Write(packet.Buffer)
wmiRecv := DCERPC_DEFAULT{}
binary.Read(buf, binary.LittleEndian, &wmiRecv)
switch index {
case 0:
if wmiRecv.Call_id != WMI_CALL_ID_1 {
return false
}
if wmiRecv.Ptype != PDU_BIND_ACK {
return false
}
return true
case 1:
if wmiRecv.Call_id != WMI_CALL_ID_2 {
return false
}
if wmiRecv.Ptype != PDU_RESP {
return false
}
return true
}
return false
}
func (w *WMIMatcher) PacketCount() int {
return len(w.sendPackets)
}
func (w *WMIMatcher) Packet(index int) *packet.Packet {
return w.sendPackets[index]
}
func (w *WMIMatcher) ServiceName() string {
return "WMI"
}
func (w *WMIMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (w *WMIMatcher) IsNoResponse(index int) bool {
return false
}
func (w *WMIMatcher) IsPrePacket() bool {
return true
}
func NewWMIMatcher() *WMIMatcher {
wm := WMIMatcher{}
ds1 := DCERPC_DEFAULT{
Rpc_ver: 5,
Rpc_ver_minor: 0,
Ptype: PDU_BIND,
Flags: 0x03,
Drep: 0x10,
Frag_len: 16 + 56,
Auth_len: 0,
Call_id: WMI_CALL_ID_1,
}
ds2 := DCERPC_DEFAULT{
Rpc_ver: 5,
Rpc_ver_minor: 0,
Ptype: PDU_REQ,
Flags: 0x03,
Drep: 0x10,
Frag_len: 16 + 8,
Auth_len: 0,
Call_id: WMI_CALL_ID_2,
}
ioxidr := DCERPC_IOXIDResolver{
MaxXmitFrag: 0x16d0,
MaxRecvFrag: 0x16d0,
AssocGroup: 0,
NumCtxItem: 1,
ContextId: 0,
NumTransItem: 1,
//interfaces
InterfaceVer: 0,
InterfaceVerMinor: 0,
//transSyntax
TransSyntaxVer: 2,
}
ioxidr.Interfaces[0] = 0xc4
ioxidr.Interfaces[1] = 0xfe
ioxidr.Interfaces[2] = 0xfc
ioxidr.Interfaces[3] = 0x99
ioxidr.Interfaces[4] = 0x60
ioxidr.Interfaces[5] = 0x52
ioxidr.Interfaces[6] = 0x1b
ioxidr.Interfaces[7] = 0x10
ioxidr.Interfaces[8] = 0xbb
ioxidr.Interfaces[9] = 0xcb
ioxidr.Interfaces[10] = 0x00
ioxidr.Interfaces[11] = 0xaa
ioxidr.Interfaces[12] = 0x00
ioxidr.Interfaces[13] = 0x21
ioxidr.Interfaces[14] = 0x34
ioxidr.Interfaces[15] = 0x7a
ioxidr.TransSyntax[0] = 0x04
ioxidr.TransSyntax[1] = 0x5d
ioxidr.TransSyntax[2] = 0x88
ioxidr.TransSyntax[3] = 0x8a
ioxidr.TransSyntax[4] = 0xeb
ioxidr.TransSyntax[5] = 0x1c
ioxidr.TransSyntax[6] = 0xc9
ioxidr.TransSyntax[7] = 0x11
ioxidr.TransSyntax[8] = 0x9f
ioxidr.TransSyntax[9] = 0xe8
ioxidr.TransSyntax[10] = 0x08
ioxidr.TransSyntax[11] = 0x00
ioxidr.TransSyntax[12] = 0x2b
ioxidr.TransSyntax[13] = 0x10
ioxidr.TransSyntax[14] = 0x48
ioxidr.TransSyntax[15] = 0x60
da := DCERPC_ALIVE{
AllocHint: 0,
ContextId: 0,
OpNum: 3,
}
buf1 := new(bytes.Buffer)
binary.Write(buf1, binary.LittleEndian, ds1)
ds1Bytes := buf1.Bytes()
buf2 := new(bytes.Buffer)
binary.Write(buf2, binary.LittleEndian, ds2)
ds2Bytes := buf2.Bytes()
buf3 := new(bytes.Buffer)
binary.Write(buf3, binary.LittleEndian, ioxidr)
ioxidrBytes := buf3.Bytes()
buf4 := new(bytes.Buffer)
binary.Write(buf4, binary.LittleEndian, da)
daBytes := buf4.Bytes()
firstByte := make([]byte, len(ds1Bytes)+len(ioxidrBytes))
copy(firstByte[0:], ds1Bytes)
copy(firstByte[len(ds1Bytes):], ioxidrBytes)
secondByte := make([]byte, len(ds2Bytes)+len(daBytes))
copy(secondByte[0:], ds2Bytes)
copy(secondByte[len(ds2Bytes):], daBytes)
wm.sendPackets = append(wm.sendPackets, packet.NewPacket(firstByte, len(ds1Bytes)+len(ioxidrBytes)))
wm.sendPackets = append(wm.sendPackets, packet.NewPacket(secondByte, len(ds2Bytes)+len(daBytes)))
return &wm
}
type DCERPC_DEFAULT struct {
Rpc_ver uint8
Rpc_ver_minor uint8
Ptype uint8
Flags uint8
Drep uint32
Frag_len uint16
Auth_len uint16
Call_id uint32
}
type DCERPC_ALIVE struct {
AllocHint uint32
ContextId uint16
OpNum uint16
}
type DCERPC_IOXIDResolver struct {
MaxXmitFrag uint16
MaxRecvFrag uint16
AssocGroup uint32
NumCtxItem uint8
UnknownCode [3]uint8
ContextId uint16
NumTransItem uint8
UnknownCode2 uint8
Interfaces [16]uint8
InterfaceVer uint16
InterfaceVerMinor uint16
TransSyntax [16]uint8
TransSyntaxVer uint32
}

51
matcher/wmi/wmi_test.go Normal file
View File

@ -0,0 +1,51 @@
package wmi
//import (
// "fmt"
// "loafle.com/overflow/collector/discovery/scan/matcher/packet"
// "loafle.com/overflow/collector/discovery/scan/matcher/scaninfo"
// "loafle.com/overflow/collector/discovery/types"
// "net"
// "testing"
//)
//
//func TestWMI(t *testing.T) {
//
// lm := NewWMIMatcher()
//
// port := types.NewPort("135", types.NewHost("192.168.1.1"), types.TYPE_TCP)
// scanInfo := scaninfo.NewServiceScanInfo(port)
// var ipport string
// ipport = port.Host.Ip + ":" + string(port.Port)
//
// fmt.Println(ipport)
// client, _ := net.Dial("tcp", ipport)
//
// defer client.Close()
//
// fmt.Println(lm.PacketCount())
//
// for ii := 0; ii < lm.PacketCount(); ii++ {
//
// pack := lm.Packet(ii)
//
// fmt.Println(pack)
//
// client.Write(pack.Buffer)
//
// bytes := make([]byte, 1024)
//
// read, _ := client.Read(bytes)
//
// //fmt.Println(bytes)
//
// b := lm.Match(ii, packet.NewPacket(bytes, read), scanInfo)
//
// if b {
// fmt.Println("Good")
// }
//
// }
//
// t.Log(scanInfo)
//}

View File

@ -0,0 +1,7 @@
package scaninfo
type ServiceScanInfo interface {
SetHistory(history string)
GetPort() string
GetIP() string
}

View File

@ -0,0 +1,37 @@
package timestamp
import (
"fmt"
"strconv"
"time"
)
type Timestamp time.Time
func (t Timestamp) MarshalJSON() ([]byte, error) {
ts := time.Time(t).Unix()
stamp := fmt.Sprint(ts * 1000)
return []byte(stamp), nil
}
func (t *Timestamp) UnmarshalJSON(b []byte) error {
ts, err := strconv.Atoi(string(b))
if err != nil {
return err
}
*t = Timestamp(time.Unix(int64(ts)/1000, 0))
return nil
}
func (t Timestamp) String() string {
return time.Time(t).String()
}
func Now() Timestamp {
return Timestamp(time.Now())
}
func Date(year int, month time.Month, day int) Timestamp {
return Timestamp(time.Date(year, month, day, 0, 0, 0, 0, time.UTC))
}