213 lines
5.6 KiB
Go
213 lines
5.6 KiB
Go
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
|
|
}
|