249 lines
4.5 KiB
Go
249 lines
4.5 KiB
Go
package wmi
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
|
|
osm "git.loafle.net/overflow/service_matcher-go"
|
|
)
|
|
|
|
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 {
|
|
osm.Matchers
|
|
}
|
|
|
|
func (m *WMIMatcher) Key() string {
|
|
return "WMI"
|
|
}
|
|
|
|
func (m *WMIMatcher) Name(matchCtx *osm.MatchCtx) string {
|
|
return "WMI"
|
|
}
|
|
|
|
func (m *WMIMatcher) IsPrePacket(matchCtx *osm.MatchCtx) bool {
|
|
return false
|
|
}
|
|
|
|
func (m *WMIMatcher) HasResponse(matchCtx *osm.MatchCtx, index int) bool {
|
|
return true
|
|
}
|
|
|
|
func (m *WMIMatcher) IsError(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) bool {
|
|
return false
|
|
}
|
|
|
|
func (m *WMIMatcher) Match(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) error {
|
|
|
|
if packet == nil {
|
|
return osm.NoPacketReceivedError()
|
|
}
|
|
|
|
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 osm.NotMatchedError()
|
|
}
|
|
|
|
if wmiRecv.Ptype != PDU_BIND_ACK {
|
|
return osm.NotMatchedError()
|
|
}
|
|
|
|
return nil
|
|
case 1:
|
|
|
|
if wmiRecv.Call_id != WMI_CALL_ID_2 {
|
|
return osm.NotMatchedError()
|
|
}
|
|
|
|
if wmiRecv.Ptype != PDU_RESP {
|
|
return osm.NotMatchedError()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
return osm.NotMatchedError()
|
|
}
|
|
|
|
func NewMatcher() osm.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(osm.NewPacket(firstByte, len(ds1Bytes)+len(ioxidrBytes)))
|
|
m.AddPacket(osm.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
|
|
}
|