overflow_probe/matcher/snmp/snmpv2.go

201 lines
4.7 KiB
Go
Raw Normal View History

2017-08-03 10:08:34 +00:00
package snmp
import (
"bytes"
"encoding/binary"
"git.loafle.net/overflow/commons_go/matcher/packet"
"git.loafle.net/overflow/commons_go/model/scaninfo"
)
const (
SNMP_START_SEQUENCE uint8 = 0X30
SNMP_TYPE_INTEGER uint8 = 0X02
SNMP_TYPE_STRING uint8 = 0X04
SNMP_TYPE_NULL uint8 = 0X05
SNMP_TYPE_OBJECT uint8 = 0X06
SNMP_GET_REQUEST uint8 = 0XA0
//SNMP_RESPONSE uint8 = 0XA2
SNMP_NO_DESC uint16 = 0X0004
SNMP_END_SEQUENCE uint8 = 0X30
SNMP_PROTOCOL_VERSION_3 uint8 = 0X03
SNMP_PROTOCOL_VERSION_2c uint8 = 0X01
SNMP_MSG_ID_MAX_VALUE uint32 = 0xFFFFFF7F
)
type snmpv2VarBinding struct {
VarBindindStart uint8
VarBindLen uint8
ObjectStart uint8
ObjectLen uint8
ValueType uint8
ValueLen uint8
ObjectValue uint64
NullValue uint8
EndIndicator uint8
}
type snmpv2Data struct {
DataType uint8
DataLen uint8
RequestIdType uint8
RequestIdLen uint8
RequestId uint8
ErrorStatusType uint8
ErrorStatusLen uint8
ErrorStatus uint8
ErrorIndexType uint8
ErrorIndexLen uint8
ErrorIndex uint8
VarBinding snmpv2VarBinding
}
type snmpv2 struct {
StartSeq uint8
SeqLen uint8
SNMPVersionType uint8
SNMPVersionLen uint8
SNMPVersion uint8
CommunityVersionType uint8
CommunityVersionLen uint8
Community [6]byte
Data snmpv2Data
}
type SNMPv2Matcher struct {
packets []*packet.Packet
}
func NewSNMPv2Matcher() *SNMPv2Matcher {
snmpMatcher := &SNMPv2Matcher{}
snmpTempBuf := new(bytes.Buffer)
binary.Write(snmpTempBuf, binary.BigEndian, snmpv2{}) //For getting the struct size
snmpDataTempBuf := new(bytes.Buffer)
binary.Write(snmpDataTempBuf, binary.BigEndian, snmpv2Data{}) //For getting the struct size
snmpVarTempBuf := new(bytes.Buffer)
binary.Write(snmpVarTempBuf, binary.BigEndian, snmpv2VarBinding{}) //For getting the struct size
q := snmpv2{}
q.StartSeq = SNMP_START_SEQUENCE
q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2
q.SNMPVersionType = SNMP_TYPE_INTEGER
q.SNMPVersionLen = 0x01
q.SNMPVersion = SNMP_PROTOCOL_VERSION_2c
q.CommunityVersionType = SNMP_TYPE_STRING
q.CommunityVersionLen = 0x06
var community [6]byte
copy(community[:], "public")
q.Community = community
q.Data.DataType = SNMP_GET_REQUEST
q.Data.DataLen = uint8(len(snmpDataTempBuf.Bytes())) - 2
q.Data.RequestIdType = SNMP_TYPE_INTEGER
q.Data.RequestIdLen = 0x01
q.Data.RequestId = 0x01
q.Data.ErrorStatusType = SNMP_TYPE_INTEGER
q.Data.ErrorStatusLen = 0x01
q.Data.ErrorStatus = 0x00
q.Data.ErrorIndexType = SNMP_TYPE_INTEGER
q.Data.ErrorIndexLen = 0x01
q.Data.ErrorIndex = 0x00
q.Data.VarBinding.VarBindindStart = SNMP_START_SEQUENCE
q.Data.VarBinding.VarBindLen = uint8(len(snmpVarTempBuf.Bytes())) - 2
q.Data.VarBinding.ObjectStart = SNMP_START_SEQUENCE
q.Data.VarBinding.ObjectLen = uint8(len(snmpVarTempBuf.Bytes())) - 4
q.Data.VarBinding.ValueType = SNMP_TYPE_OBJECT
q.Data.VarBinding.ValueLen = 0x08
q.Data.VarBinding.ObjectValue = 0x000001010201062b
q.Data.VarBinding.NullValue = SNMP_TYPE_NULL
q.Data.VarBinding.EndIndicator = 0x00
writer := new(bytes.Buffer)
binary.Write(writer, binary.LittleEndian, q)
snmpMatcher.packets = append(snmpMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len()))
return snmpMatcher
}
func (t *SNMPv2Matcher) ServiceName() string {
return "SNMP"
}
func (t *SNMPv2Matcher) PacketCount() int {
return len(t.packets)
}
func (t *SNMPv2Matcher) Packet(index int) *packet.Packet {
return t.packets[index]
}
func (t *SNMPv2Matcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
return false
}
func (t *SNMPv2Matcher) IsNoResponse(index int) bool {
return false
}
func (t *SNMPv2Matcher) IsPrePacket() bool {
return false
}
func (t *SNMPv2Matcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool {
if packet == nil {
return false
}
r := new(bytes.Buffer)
r.Write(packet.Buffer)
s := snmpv2{}
if err := binary.Read(r, binary.BigEndian, &s); err != nil {
return false
}
if s.StartSeq != SNMP_START_SEQUENCE {
return false
}
var p uint8
reader := new(bytes.Buffer)
reader.Write(packet.Buffer)
for idx := 0; idx < 5; idx++ {
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
return false
}
if p == SNMP_TYPE_INTEGER {
break
}
p++
}
//finding protocol version type : 0x02 0x01 0x01
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
return false
}
if p == 0x01 {
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
return false
}
if p == 0x01 {
return true
}
}
return false
}
func (t *SNMPv2Matcher) IsSend(port int) bool {
if port == 161 {
return true
}
return false
}