2017-12-14 07:38:48 +00:00
|
|
|
package sqlserver
|
2017-12-04 07:27:08 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
|
|
|
|
cnsm "git.loafle.net/commons_go/network_service_matcher"
|
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
type SQLServerMatcher struct {
|
2017-12-04 07:27:08 +00:00
|
|
|
cnsm.Matchers
|
|
|
|
isSSL bool
|
|
|
|
}
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
func (t *SQLServerMatcher) ServiceName() string {
|
2017-12-04 07:27:08 +00:00
|
|
|
if t.isSSL {
|
|
|
|
return "SQL Server (SSL)"
|
|
|
|
}
|
|
|
|
return "SQL Server"
|
|
|
|
}
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
func (t *SQLServerMatcher) IsPrePacket() bool {
|
2017-12-04 07:27:08 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
func (t *SQLServerMatcher) HasResponse(index int) bool {
|
2017-12-04 07:27:08 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
func (t *SQLServerMatcher) IsError(info cnsm.MatchInfo, index int, packet *cnsm.Packet) bool {
|
2017-12-04 07:27:08 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
func (t *SQLServerMatcher) Match(info cnsm.MatchInfo, index int, packet *cnsm.Packet) bool {
|
2017-12-04 07:27:08 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMatcher() cnsm.Matcher {
|
|
|
|
|
2017-12-14 03:30:12 +00:00
|
|
|
mm := &SQLServerMatcher{}
|
2017-12-04 07:27:08 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
mm.AddPacket(cnsm.NewPacket(writer.Bytes(), writer.Len()))
|
|
|
|
|
|
|
|
return mm
|
|
|
|
}
|