package smb import ( "bytes" "encoding/binary" "strings" osm "git.loafle.net/overflow/service_matcher-go" ) 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 { osm.Matchers } func (m *SMBMatcher) Key() string { return "SMB" } func (m *SMBMatcher) Type() string { return "NETWORK" } func (m *SMBMatcher) Vendor(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SMBMatcher) Version(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SMBMatcher) OsType(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SMBMatcher) OsVersion(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SMBMatcher) Name(matchCtx *osm.MatchCtx) string { return "SMB" } func (m *SMBMatcher) IsPrePacket() bool { return false } func (m *SMBMatcher) HasResponse(matchCtx *osm.MatchCtx, index int) bool { return true } func (m *SMBMatcher) IsError(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) bool { return false } func (m *SMBMatcher) Match(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) error { if packet == nil || !packet.Valid() { return osm.NoPacketReceivedError() } reader := new(bytes.Buffer) reader.Write(packet.Buffer) s := smb{} if err := binary.Read(reader, binary.BigEndian, &s); err != nil { return err } var des [4]byte copy(des[1:], s.NetBios.MsgLength[:]) packetLen := binary.BigEndian.Uint32(des[:]) if packetLen != uint32(packet.Len-4) { return osm.NotMatchedError() } if !strings.Contains(string(s.Component[:]), "SMB") { return osm.NotMatchedError() } if s.SmbCommand != SMB_COM_NEGOTIATE { return osm.NotMatchedError() } return nil } func NewMatcher() osm.Matcher { m := &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) m.AddPacket(osm.NewPacket(writer.Bytes(), writer.Len())) return m }