ing
This commit is contained in:
173
matcher/mssql/mssql.go
Normal file
173
matcher/mssql/mssql.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package mssql
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"git.loafle.net/overflow/overflow_discovery/match/packet"
|
||||
"git.loafle.net/overflow/overflow_discovery/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) HasResponse(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
|
||||
|
||||
}
|
||||
63
matcher/mssql/mssql_test.go
Normal file
63
matcher/mssql/mssql_test.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package mssql
|
||||
|
||||
import (
|
||||
"git.loafle.net/overflow/overflow_discovery/match/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.16:11433")
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user