package wmi import ( "bytes" "encoding/binary" "git.loafle.net/overflow/overflow_discovery/service/matcher" ) const ( PDU_BIND = 11 PDU_BIND_ACK = 12 PDU_REQ = 0 PDU_RESP = 2 WMI_CALL_ID_1 = 0x95 WMI_CALL_ID_2 = 0x96 ) type WMIMatcher struct { matcher.Matchers } func (w *WMIMatcher) ServiceName() string { return "WMI" } func (w *WMIMatcher) IsPrePacket() bool { return false } func (w *WMIMatcher) HasResponse(index int) bool { return true } func (w *WMIMatcher) IsError(info matcher.MatchInfo, index int, packet *matcher.Packet) bool { return false } func (w *WMIMatcher) Match(info matcher.MatchInfo, index int, packet *matcher.Packet) bool { if packet == nil { return false } buf := new(bytes.Buffer) buf.Write(packet.Buffer) wmiRecv := DCERPC_DEFAULT{} binary.Read(buf, binary.LittleEndian, &wmiRecv) switch index { case 0: if wmiRecv.Call_id != WMI_CALL_ID_1 { return false } if wmiRecv.Ptype != PDU_BIND_ACK { return false } return true case 1: if wmiRecv.Call_id != WMI_CALL_ID_2 { return false } if wmiRecv.Ptype != PDU_RESP { return false } return true } return false } func NewMatcher() matcher.Matcher { m := &WMIMatcher{} ds1 := DCERPC_DEFAULT{ Rpc_ver: 5, Rpc_ver_minor: 0, Ptype: PDU_BIND, Flags: 0x03, Drep: 0x10, Frag_len: 16 + 56, Auth_len: 0, Call_id: WMI_CALL_ID_1, } ds2 := DCERPC_DEFAULT{ Rpc_ver: 5, Rpc_ver_minor: 0, Ptype: PDU_REQ, Flags: 0x03, Drep: 0x10, Frag_len: 16 + 8, Auth_len: 0, Call_id: WMI_CALL_ID_2, } ioxidr := DCERPC_IOXIDResolver{ MaxXmitFrag: 0x16d0, MaxRecvFrag: 0x16d0, AssocGroup: 0, NumCtxItem: 1, ContextId: 0, NumTransItem: 1, //interfaces InterfaceVer: 0, InterfaceVerMinor: 0, //transSyntax TransSyntaxVer: 2, } ioxidr.Interfaces[0] = 0xc4 ioxidr.Interfaces[1] = 0xfe ioxidr.Interfaces[2] = 0xfc ioxidr.Interfaces[3] = 0x99 ioxidr.Interfaces[4] = 0x60 ioxidr.Interfaces[5] = 0x52 ioxidr.Interfaces[6] = 0x1b ioxidr.Interfaces[7] = 0x10 ioxidr.Interfaces[8] = 0xbb ioxidr.Interfaces[9] = 0xcb ioxidr.Interfaces[10] = 0x00 ioxidr.Interfaces[11] = 0xaa ioxidr.Interfaces[12] = 0x00 ioxidr.Interfaces[13] = 0x21 ioxidr.Interfaces[14] = 0x34 ioxidr.Interfaces[15] = 0x7a ioxidr.TransSyntax[0] = 0x04 ioxidr.TransSyntax[1] = 0x5d ioxidr.TransSyntax[2] = 0x88 ioxidr.TransSyntax[3] = 0x8a ioxidr.TransSyntax[4] = 0xeb ioxidr.TransSyntax[5] = 0x1c ioxidr.TransSyntax[6] = 0xc9 ioxidr.TransSyntax[7] = 0x11 ioxidr.TransSyntax[8] = 0x9f ioxidr.TransSyntax[9] = 0xe8 ioxidr.TransSyntax[10] = 0x08 ioxidr.TransSyntax[11] = 0x00 ioxidr.TransSyntax[12] = 0x2b ioxidr.TransSyntax[13] = 0x10 ioxidr.TransSyntax[14] = 0x48 ioxidr.TransSyntax[15] = 0x60 da := DCERPC_ALIVE{ AllocHint: 0, ContextId: 0, OpNum: 3, } buf1 := new(bytes.Buffer) binary.Write(buf1, binary.LittleEndian, ds1) ds1Bytes := buf1.Bytes() buf2 := new(bytes.Buffer) binary.Write(buf2, binary.LittleEndian, ds2) ds2Bytes := buf2.Bytes() buf3 := new(bytes.Buffer) binary.Write(buf3, binary.LittleEndian, ioxidr) ioxidrBytes := buf3.Bytes() buf4 := new(bytes.Buffer) binary.Write(buf4, binary.LittleEndian, da) daBytes := buf4.Bytes() firstByte := make([]byte, len(ds1Bytes)+len(ioxidrBytes)) copy(firstByte[0:], ds1Bytes) copy(firstByte[len(ds1Bytes):], ioxidrBytes) secondByte := make([]byte, len(ds2Bytes)+len(daBytes)) copy(secondByte[0:], ds2Bytes) copy(secondByte[len(ds2Bytes):], daBytes) m.AddPacket(matcher.NewPacket(firstByte, len(ds1Bytes)+len(ioxidrBytes))) m.AddPacket(matcher.NewPacket(secondByte, len(ds2Bytes)+len(daBytes))) return m } type DCERPC_DEFAULT struct { Rpc_ver uint8 Rpc_ver_minor uint8 Ptype uint8 Flags uint8 Drep uint32 Frag_len uint16 Auth_len uint16 Call_id uint32 } type DCERPC_ALIVE struct { AllocHint uint32 ContextId uint16 OpNum uint16 } type DCERPC_IOXIDResolver struct { MaxXmitFrag uint16 MaxRecvFrag uint16 AssocGroup uint32 NumCtxItem uint8 UnknownCode [3]uint8 ContextId uint16 NumTransItem uint8 UnknownCode2 uint8 Interfaces [16]uint8 InterfaceVer uint16 InterfaceVerMinor uint16 TransSyntax [16]uint8 TransSyntaxVer uint32 }