Added mssql plug

This commit is contained in:
solar 2018-11-15 19:44:54 +08:00
parent 3a639ed0f1
commit 955f6f4f92
7 changed files with 376 additions and 84 deletions

View File

@ -1,21 +1,22 @@
package core package core
import ( import (
"io/ioutil" "fmt"
"plugin"
"github.com/google/gopacket"
"io" "io"
mysql "github.com/40t/go-sniffer/plugSrc/mysql/build" "io/ioutil"
redis "github.com/40t/go-sniffer/plugSrc/redis/build" "path"
"path/filepath"
"plugin"
hp "github.com/40t/go-sniffer/plugSrc/http/build" hp "github.com/40t/go-sniffer/plugSrc/http/build"
mongodb "github.com/40t/go-sniffer/plugSrc/mongodb/build" mongodb "github.com/40t/go-sniffer/plugSrc/mongodb/build"
"path/filepath" mysql "github.com/40t/go-sniffer/plugSrc/mysql/build"
"fmt" redis "github.com/40t/go-sniffer/plugSrc/redis/build"
"path" mssql "github.com/feiin/go-sniffer/plugSrc/mssql/build"
"github.com/google/gopacket"
) )
type Plug struct { type Plug struct {
dir string dir string
ResolveStream func(net gopacket.Flow, transport gopacket.Flow, r io.Reader) ResolveStream func(net gopacket.Flow, transport gopacket.Flow, r io.Reader)
BPF string BPF string
@ -71,6 +72,8 @@ func (p *Plug) LoadInternalPlugList() {
//Http //Http
list["http"] = hp.NewInstance() list["http"] = hp.NewInstance()
list["mssql"] = mssql.NewInstance()
p.InternalPlugList = list p.InternalPlugList = list
} }
@ -145,6 +148,8 @@ func (p *Plug) PrintList() {
func (p *Plug) SetOption(plugName string, plugParams []string) { func (p *Plug) SetOption(plugName string, plugParams []string) {
fmt.Println("internalPlug", plugName)
//Load Internal Plug //Load Internal Plug
if internalPlug, ok := p.InternalPlugList[plugName]; ok { if internalPlug, ok := p.InternalPlugList[plugName]; ok {

BIN
go-sniffer Executable file

Binary file not shown.

View File

@ -1,7 +1,7 @@
package main package main
import ( import (
"github.com/40t/go-sniffer/core" "github.com/feiin/go-sniffer/core"
) )
func main() { func main() {

View File

@ -0,0 +1,227 @@
package build
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os"
"strconv"
"sync"
"github.com/google/gopacket"
)
const (
Port = 1433
Version = "0.1"
CmdPort = "-p"
)
type Mssql struct {
port int
version string
source map[string]*stream
}
type stream struct {
packets chan *packet
}
type packet struct {
isClientFlow bool
status int
packetType int
length int
payload []byte
}
// packet types
// https://msdn.microsoft.com/en-us/library/dd304214.aspx
const (
packSQLBatch = 1
packRPCRequest = 3
packReply = 4
packAttention = 6
packBulkLoadBCP = 7
packTransMgrReq = 14
packNormal = 15
packLogin7 = 16
packSSPIMessage = 17
packPrelogin = 18
)
var mssql *Mssql
var once sync.Once
func NewInstance() *Mssql {
once.Do(func() {
mssql = &Mssql{
port: Port,
version: Version,
source: make(map[string]*stream),
}
})
return mssql
}
func (m *Mssql) Version() string {
return m.version
}
func (m *Mssql) BPFFilter() string {
return "tcp and port " + strconv.Itoa(m.port)
}
func (m *Mssql) SetFlag(flg []string) {
c := len(flg)
if c == 0 {
return
}
if c>>1 == 0 {
fmt.Println("ERR : Mssql Number of parameters")
os.Exit(1)
}
for i := 0; i < c; i = i + 2 {
key := flg[i]
val := flg[i+1]
switch key {
case CmdPort:
port, err := strconv.Atoi(val)
m.port = port
if err != nil {
panic("ERR : port")
}
if port < 0 || port > 65535 {
panic("ERR : port(0-65535)")
}
break
default:
panic("ERR : mssql's params")
}
}
}
// ResolveStream ...
func (m *Mssql) ResolveStream(net, transport gopacket.Flow, buf io.Reader) {
//uuid
uuid := fmt.Sprintf("%v:%v", net.FastHash(), transport.FastHash())
// log.Println(uuid)
if _, ok := m.source[uuid]; !ok {
var newStream = &stream{
packets: make(chan *packet, 100),
}
m.source[uuid] = newStream
go newStream.resolve()
}
for {
// log.Println("ssss")
newPacket := m.newPacket(net, transport, buf)
if newPacket == nil {
return
}
m.source[uuid].packets <- newPacket
}
// log.Println('ddd')
}
func (m *Mssql) newPacket(net, transport gopacket.Flow, r io.Reader) *packet {
// read packet
var packet *packet
var err error
packet, err = readStream(r)
//stream close
if err == io.EOF {
fmt.Println(net, transport, " close")
return nil
} else if err != nil {
fmt.Println("ERR : Unknown stream", net, transport, ":", err)
return nil
}
//set flow direction
if transport.Src().String() == strconv.Itoa(m.port) {
packet.isClientFlow = false
} else {
packet.isClientFlow = true
}
return packet
}
func (m *stream) resolve() {
for {
select {
case packet := <-m.packets:
if packet.isClientFlow {
m.resolveClientPacket(packet)
} else {
m.resolveServerPacket(packet)
}
}
}
}
func readStream(r io.Reader) (*packet, error) {
var buffer bytes.Buffer
header := make([]byte, 8)
p := &packet{}
if _, err := io.ReadFull(r, header); err != nil {
return nil, err
}
p.packetType = int(uint32(header[0]))
p.status = int(uint32(header[1]))
p.length = int(binary.BigEndian.Uint16(header[2:4]))
if p.length > 0 {
io.CopyN(&buffer, r, int64(p.length-8))
}
p.payload = buffer.Bytes()
return p, nil
}
func (m *stream) resolveClientPacket(p *packet) {
var msg string
switch p.packetType {
case 1:
msg = fmt.Sprintf("【query】 %s", string(p.payload))
case 4:
msg = fmt.Sprintf("【query】 %s", "Tabular result")
}
fmt.Println(GetNowStr(true), msg)
}
func (m *stream) resolveServerPacket(p *packet) {
var msg string
switch p.packetType {
case 4:
var b = int32(p.payload[0])
msg = fmt.Sprintf("【OK】 %d", b)
}
parseToken(p.payload)
fmt.Println(GetNowStr(false), msg)
}

View File

@ -0,0 +1,45 @@
package build
import (
"encoding/binary"
)
type token byte
// token ids
const (
tokenReturnStatus token = 121 // 0x79
tokenColMetadata token = 129 // 0x81
tokenOrder token = 169 // 0xA9
tokenError token = 170 // 0xAA
tokenInfo token = 171 // 0xAB
tokenReturnValue token = 0xAC
tokenLoginAck token = 173 // 0xad
tokenRow token = 209 // 0xd1
tokenNbcRow token = 210 // 0xd2
tokenEnvChange token = 227 // 0xE3
tokenSSPI token = 237 // 0xED
tokenDone token = 253 // 0xFD
tokenDoneProc token = 254
tokenDoneInProc token = 255
)
func parseToken(buf []byte) string {
var pos = 0
len := 0
for {
token := token(buf[pos])
switch token {
case tokenSSPI:
pos += 1
len = int(binary.LittleEndian.Uint16(buf[pos+1 : pos+2]))
pos += len
}
break
}
return ""
}

View File

@ -0,0 +1,14 @@
package build
import "time"
func GetNowStr(isClient bool) string {
var msg string
msg += time.Now().Format("2006-01-02 15:04:05")
if isClient {
msg += "| cli -> ser |"
} else {
msg += "| ser -> cli |"
}
return msg
}

View File

@ -1,18 +1,19 @@
package build package build
import ( import (
"github.com/google/gopacket"
"io"
"bytes" "bytes"
"encoding/binary"
"errors" "errors"
"fmt"
"io"
"log" "log"
"os"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
"fmt"
"encoding/binary" "github.com/google/gopacket"
"strings"
"os"
) )
const ( const (
@ -41,6 +42,7 @@ type packet struct {
var mysql *Mysql var mysql *Mysql
var once sync.Once var once sync.Once
func NewInstance() *Mysql { func NewInstance() *Mysql {
once.Do(func() { once.Do(func() {
@ -86,7 +88,7 @@ func (m *Mysql) ResolveStream(net, transport gopacket.Flow, buf io.Reader) {
} }
func (m *Mysql) BPFFilter() string { func (m *Mysql) BPFFilter() string {
return "tcp and port "+strconv.Itoa(m.port); return "tcp and port " + strconv.Itoa(m.port)
} }
func (m *Mysql) Version() string { func (m *Mysql) Version() string {
@ -110,7 +112,7 @@ func (m *Mysql) SetFlag(flg []string) {
switch key { switch key {
case CmdPort: case CmdPort:
port, err := strconv.Atoi(val); port, err := strconv.Atoi(val)
m.port = port m.port = port
if err != nil { if err != nil {
panic("ERR : port") panic("ERR : port")
@ -348,4 +350,3 @@ func (stm *stream) resolveClientPacket(payload []byte, seq int) {
fmt.Println(GetNowStr(true) + msg) fmt.Println(GetNowStr(true) + msg)
} }