overflow_discovery/service/matcher/snmp/v3/snmpv3.go

213 lines
5.6 KiB
Go
Raw Normal View History

2017-11-21 12:47:55 +00:00
package v3
import (
"bytes"
"encoding/binary"
"git.loafle.net/overflow/overflow_discovery/service/matcher"
"git.loafle.net/overflow/overflow_probe/matcher/snmp"
)
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 SNMPMatcher struct {
matcher.Matchers
}
func (t *SNMPMatcher) ServiceName() string {
return "SNMP"
}
func (t *SNMPMatcher) IsPrePacket() bool {
return false
}
func (t *SNMPMatcher) HasResponse(index int) bool {
return true
}
func (t *SNMPMatcher) IsError(info matcher.MatchInfo, index int, packet *matcher.Packet) bool {
return false
}
func (t *SNMPMatcher) Match(info matcher.MatchInfo, index int, packet *matcher.Packet) 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.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.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 *SNMPMatcher) IsSend(info matcher.MatchInfo) bool {
if info.Port() == 161 {
return true
}
return false
}
func NewMatcher() matcher.UDPMatcher {
m := &SNMPMatcher{}
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.SNMP_START_SEQUENCE
q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2
q.SNMPVersionType = snmp.SNMP_TYPE_INTEGER
q.SNMPVersionLen = 0x01
q.SNMPVersion = snmp.SNMP_PROTOCOL_VERSION_3
q.MsgGlobalData.GlobalDataStartSeq = snmp.SNMP_START_SEQUENCE
q.MsgGlobalData.GlobalDataLen = uint8(len(snmpGlobalTempBuf.Bytes())) - 2
q.MsgGlobalData.MsgIdType = snmp.SNMP_TYPE_INTEGER
q.MsgGlobalData.MsgIdLen = 0x04
q.MsgGlobalData.MsgId = snmp.SNMP_MSG_ID_MAX_VALUE
q.MsgGlobalData.MsgMaxSizeType = snmp.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.SNMP_TYPE_STRING
q.MsgGlobalData.MsgFlagsTypeLen = 0x01
q.MsgGlobalData.MsgFlags = 0x04
q.MsgGlobalData.MsgSecurityModelType = snmp.SNMP_TYPE_INTEGER
q.MsgGlobalData.MsgSecurityModelLen = 0x01
q.MsgGlobalData.MsgSecurityModel = 0x03
q.Unk1 = 0x1004
q.Unk2 = 0x0e30
q.MsgAuthoritativeEngineId = snmp.SNMP_NO_DESC
q.MsgAuthoritativeEngineBootsType = snmp.SNMP_TYPE_INTEGER
q.MsgAuthoritativeEngineBootsLen = 0x01
q.MsgAuthoritativeEngineBoots = 0x00
q.MsgAuthoritativeEngineTimeType = snmp.SNMP_TYPE_INTEGER
q.MsgAuthoritativeEngineTimeLen = 0x01
q.MsgAuthoritativeEngineTime = 0x00
q.MsgUserName = snmp.SNMP_NO_DESC
q.MsgAuthenticationParam = snmp.SNMP_NO_DESC
q.MsgPrivacyParam = snmp.SNMP_NO_DESC
q.MsgData.MsgDataStartSeq = snmp.SNMP_START_SEQUENCE
q.MsgData.MsgDataLen = uint8(len(snmpMsgDataTempBuf.Bytes())) - 2
q.MsgData.ContextEngineId = snmp.SNMP_NO_DESC
q.MsgData.ContextEngineName = snmp.SNMP_NO_DESC
q.MsgData.SnmpType = snmp.SNMP_GET_REQUEST
q.MsgData.Len = 0x0E
q.MsgData.RequestIdType = snmp.SNMP_TYPE_INTEGER
q.MsgData.RequestIdLen = 0x04
q.MsgData.RequestId = 0x00 //
q.MsgData.ErrorStatusType = snmp.SNMP_TYPE_INTEGER
q.MsgData.ErrorStatusLen = 0x01
q.MsgData.ErrorStatus = 0x00
q.MsgData.ErrorIndexType = snmp.SNMP_TYPE_INTEGER
q.MsgData.ErrorIndexLen = 0x01
q.MsgData.ErrorIndex = 0x00
q.MsgData.EndSeq = snmp.SNMP_END_SEQUENCE
q.MsgData.EndIndicator = 0x00
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, q)
m.AddPacket(matcher.NewPacket(writer.Bytes(), writer.Len()))
return m
}