Generated from Manticore v1.1.5 • 201 packages. View on pkg.go.dev

pdu

import "github.com/TheManticoreProject/Manticore/network/dcerpc/v5/pdu"

Package pdu models connection-oriented DCE/RPC protocol data units (PDUs): the 16-byte common header and the Bind, Bind_Ack, Bind_Nak, Request, Response, and Fault bodies ([C706] section 12, [MS-RPCE] section 2.2).

Each PDU type embeds the common Header and represents a whole PDU. Marshal returns the complete on-the-wire bytes (header included) and sets the header’s frag_length; Unmarshal parses a complete PDU and returns the number of bytes consumed.

Only the little-endian data representation (DREP first byte 0x10) is supported, which is what Windows and Samba always send; a big-endian DREP is rejected on Unmarshal rather than silently mis-parsed.

Index

Constants

Presentation context negotiation result codes (p_cont_def_result_t), as returned in the result field of each p_result_t in a bind_ack PDU.

References:

const (
    ResultAcceptance        uint16 = 0
    ResultUserRejection     uint16 = 1
    ResultProviderRejection uint16 = 2
    ResultNegotiateAck      uint16 = 3 // [MS-RPCE] bind-time feature negotiation
)

Provider reject reasons (p_provider_reason_t / p_reject_reason_t).

Reference: [C706] section 12.6.3.1: https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm

const (
    ReasonNotSpecified                         uint16 = 0
    ReasonAbstractSyntaxNotSupported           uint16 = 1
    ReasonProposedTransferSyntaxesNotSupported uint16 = 2
    ReasonLocalLimitExceeded                   uint16 = 3
)

Common connection-oriented RPC fault status codes (nca_* / rpc_s_*). This is a subset; unknown codes are reported numerically by FaultStatus.String.

References:

const (
    NCASStatusOK             uint32 = 0x00000000
    NCASOpRngError           uint32 = 0x1C010002 // nca_s_op_rng_error: invalid opnum
    NCASUnkIf                uint32 = 0x1C010003 // nca_s_unk_if: unknown interface
    NCASProtoError           uint32 = 0x1C01000B // nca_s_proto_error
    NCASFaultIntDivByZero    uint32 = 0x1C000001 // nca_s_fault_int_div_by_zero
    NCASFaultAddrError       uint32 = 0x1C000002 // nca_s_fault_addr_error
    NCASFaultNDR             uint32 = 0x000006F7 // nca_s_fault_ndr: NDR could not decode
    NCASFaultAccessDenied    uint32 = 0x00000005 // nca_s_fault_access_denied
    NCASFaultContextMismatch uint32 = 0x1C00001A // nca_s_fault_context_mismatch
)

Authentication service identifiers (auth_type), as carried in the sec_trailer of an authenticated PDU.

Reference: [MS-RPCE] 2.2.1.1.7 Security Providers: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/d4097450-c62f-484b-872f-ddf59a7a0d36

const (
    AuthTypeNone         uint8 = 0x00
    AuthTypeGSSNegotiate uint8 = 0x09 // SPNEGO
    AuthTypeNTLMSSP      uint8 = 0x0A // RPC_C_AUTHN_WINNT
    AuthTypeGSSSchannel  uint8 = 0x0E // RPC_C_AUTHN_GSS_SCHANNEL
    AuthTypeGSSKerberos  uint8 = 0x10
    AuthTypeNetlogon     uint8 = 0x44 // RPC_C_AUTHN_NETLOGON
    // AuthTypeDefault selects the implementation default provider; it is an SSPI
    // selector value, not a value that appears in a sec_trailer on the wire.
    AuthTypeDefault uint8 = 0xFF // RPC_C_AUTHN_DEFAULT
)

Authentication levels (auth_level), as carried in the sec_trailer. Higher levels subsume the protection of lower ones.

Reference: [MS-RPCE] 2.2.1.1.8 Authentication Levels: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/425a7c53-c33a-4868-8e5b-2a850d40dc73

const (
    AuthLevelDefault      uint8 = 0x00
    AuthLevelNone         uint8 = 0x01
    AuthLevelConnect      uint8 = 0x02
    AuthLevelCall         uint8 = 0x03
    AuthLevelPkt          uint8 = 0x04
    AuthLevelPktIntegrity uint8 = 0x05
    AuthLevelPktPrivacy   uint8 = 0x06
)

HeaderSize is the size, in bytes, of the connection-oriented common header.

const HeaderSize = 16

SecTrailerSize is the size, in bytes, of the sec_trailer (auth_verifier_co_t) header that precedes the auth_value in an authenticated PDU.

const SecTrailerSize = 8

Variables

DataRepresentationLittleEndian is the canonical packed_drep for little-endian integers, ASCII characters, and IEEE floating point.

var DataRepresentationLittleEndian = [4]byte{0x10, 0x00, 0x00, 0x00}

type Auth3

Auth3 is an rpc_auth_3 PDU: the optional third leg of an authenticated bind. After a bind that carried an authentication token and a bind_ack that returned the security provider’s challenge, the client sends an auth3 carrying the final token (for NTLM, the AUTHENTICATE message) to complete the exchange. The server sends no reply.

The PDU is the common header, a 4-byte pad (a vestigial max_xmit_frag/max_recv_frag that the server ignores), then the sec_trailer and the auth_value. The header’s auth_length counts only AuthValue.

References:

type Auth3 struct {
    Header     Header
    SecTrailer SecTrailer
    AuthValue  []byte
}

func (*Auth3) Marshal

func (a *Auth3) Marshal() ([]byte, error)

Marshal serializes the complete auth3 PDU, filling in the header’s packet type, frag_length, and auth_length.

func (*Auth3) Unmarshal

func (a *Auth3) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete auth3 PDU and returns the bytes consumed.

type Bind

Bind is a bind PDU: it proposes the maximum fragment sizes, an association group, and a list of presentation contexts to negotiate.

References:

type Bind struct {
    Header       Header
    MaxXmitFrag  uint16
    MaxRecvFrag  uint16
    AssocGroupID uint32
    ContextList  []ContextElement

    // SecTrailer and AuthValue carry an optional authentication verifier. When
    // AuthValue is non-empty, Marshal pads the body to a 4-byte boundary, appends the
    // sec_trailer and the auth_value (e.g. an NTLM NEGOTIATE token), and sets the
    // header's auth_length. They are nil/empty for an unauthenticated bind.
    SecTrailer SecTrailer
    AuthValue  []byte
}

func (*Bind) Marshal

func (b *Bind) Marshal() ([]byte, error)

Marshal serializes the complete bind PDU, filling in the header’s packet type, frag_length, and — when an auth_value is present — auth_length.

func (*Bind) String

func (b *Bind) String() string

String returns a one-line summary.

func (*Bind) Unmarshal

func (b *Bind) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete bind PDU and returns the bytes consumed.

type BindAck

BindAck is a bind_ack PDU: the server’s response to a bind, echoing the negotiated fragment sizes and reporting per-context negotiation results.

References:

type BindAck struct {
    Header           Header
    MaxXmitFrag      uint16
    MaxRecvFrag      uint16
    AssocGroupID     uint32
    SecondaryAddress string // port_spec, without the trailing NUL
    Results          []PresentationResult
}

func (*BindAck) Accepted

func (b *BindAck) Accepted() bool

Accepted reports whether at least one presentation context was accepted.

func (*BindAck) Marshal

func (b *BindAck) Marshal() ([]byte, error)

Marshal serializes the complete bind_ack PDU, including the 4-byte alignment pad after the secondary address.

func (*BindAck) String

func (b *BindAck) String() string

String returns a one-line summary.

func (*BindAck) Unmarshal

func (b *BindAck) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete bind_ack PDU and returns the bytes consumed.

type BindNak

BindNak is a bind_nak PDU: the server’s rejection of a bind, with a reason and the list of RPC protocol versions it supports.

Reference: [C706] section 12.6.3.1 (“The bind_nak PDU”): https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm

type BindNak struct {
    Header       Header
    RejectReason uint16
    Versions     []ProtocolVersion
}

func (*BindNak) Marshal

func (b *BindNak) Marshal() ([]byte, error)

Marshal serializes the complete bind_nak PDU.

func (*BindNak) String

func (b *BindNak) String() string

String returns a one-line summary.

func (*BindNak) Unmarshal

func (b *BindNak) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete bind_nak PDU and returns the bytes consumed.

type ContextElement

ContextElement is a single presentation context proposed in a bind (or alter_context) PDU: a context id, an abstract syntax (the target interface), and one or more candidate transfer syntaxes (p_cont_elem_t).

References:

type ContextElement struct {
    ContextID        uint16
    AbstractSyntax   syntax.SyntaxID
    TransferSyntaxes []syntax.SyntaxID
}

func (*ContextElement) Marshal

func (c *ContextElement) Marshal() ([]byte, error)

Marshal serializes a presentation context element.

func (*ContextElement) Unmarshal

func (c *ContextElement) Unmarshal(data []byte) (int, error)

Unmarshal parses a presentation context element and returns the bytes consumed.

type Fault

Fault is a fault PDU: it reports that a call failed, carrying a status code and any error stub data.

References:

type Fault struct {
    Header      Header
    AllocHint   uint32
    ContextID   uint16
    CancelCount uint8
    Status      uint32
    Stub        []byte
}

func (*Fault) Error

func (f *Fault) Error() string

Error implements the error interface so a Fault can be returned directly from a call. The message includes the mnemonic status code.

func (*Fault) Marshal

func (f *Fault) Marshal() ([]byte, error)

Marshal serializes the complete fault PDU.

func (*Fault) String

func (f *Fault) String() string

String returns a one-line summary.

func (*Fault) Unmarshal

func (f *Fault) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete fault PDU and returns the bytes consumed.

type FaultStatus

FaultStatus is a fault PDU status code, with a descriptive String.

type FaultStatus uint32

func (FaultStatus) String

func (s FaultStatus) String() string

String returns a mnemonic for known status codes, otherwise the hex value.

Header is the connection-oriented common header present at the start of every PDU.

References:

type Header struct {
    RPCVersion         uint8
    RPCVersionMinor    uint8
    PacketType         PacketType
    PacketFlags        PFCFlags
    DataRepresentation [4]byte
    FragLength         uint16
    AuthLength         uint16
    CallID             uint32
}

func NewHeader

func NewHeader(pt PacketType, flags PFCFlags, callID uint32) Header

NewHeader returns a header initialized for protocol version 5.0 with little-endian data representation and the given packet type, flags, and call id.

func PeekHeader

func PeekHeader(data []byte) (*Header, error)

PeekHeader parses just the common header from the front of a complete PDU buffer. It is a convenience for dispatching on PacketType before fully unmarshalling.

func (*Header) Marshal

func (h *Header) Marshal() ([]byte, error)

Marshal serializes the header into its 16-byte wire form.

func (*Header) String

func (h *Header) String() string

String returns a human-readable one-line summary of the header.

func (*Header) Unmarshal

func (h *Header) Unmarshal(data []byte) (int, error)

Unmarshal parses a header from the start of data and returns the bytes consumed (always HeaderSize on success).

type PFCFlags

PFCFlags is the set of PFC_* flags carried in the pfc_flags field of the common header.

References:

type PFCFlags uint8
const (
    // PFCFirstFrag marks the first fragment of a multi-fragment PDU.
    PFCFirstFrag PFCFlags = 0x01
    // PFCLastFrag marks the last fragment of a multi-fragment PDU.
    PFCLastFrag PFCFlags = 0x02
    // PFCPendingCancel signals a pending cancel (request) or a cancel was pending
    // (response).
    PFCPendingCancel PFCFlags = 0x04
    // PFCReserved is reserved.
    PFCReserved PFCFlags = 0x08
    // PFCConcMpx indicates support for concurrent multiplexing on the connection.
    PFCConcMpx PFCFlags = 0x10
    // PFCDidNotExecute indicates the server did not execute the call (response/fault).
    PFCDidNotExecute PFCFlags = 0x20
    // PFCMaybe indicates a "maybe" call with no response expected.
    PFCMaybe PFCFlags = 0x40
    // PFCObjectUuid indicates an object UUID is present in the PDU body.
    PFCObjectUuid PFCFlags = 0x80
)

func (PFCFlags) Has

func (f PFCFlags) Has(flag PFCFlags) bool

Has reports whether all bits in flag are set.

func (PFCFlags) String

func (f PFCFlags) String() string

String returns a “|”-joined list of set flag names.

type PacketType

PacketType identifies the kind of a connection-oriented DCE/RPC PDU, as carried in the ptype field of the common header.

References:

type PacketType uint8
const (
    PacketTypeRequest          PacketType = 0
    PacketTypePing             PacketType = 1
    PacketTypeResponse         PacketType = 2
    PacketTypeFault            PacketType = 3
    PacketTypeWorking          PacketType = 4
    PacketTypeNoCall           PacketType = 5
    PacketTypeReject           PacketType = 6
    PacketTypeAck              PacketType = 7
    PacketTypeClCancel         PacketType = 8
    PacketTypeFack             PacketType = 9
    PacketTypeCancelAck        PacketType = 10
    PacketTypeBind             PacketType = 11
    PacketTypeBindAck          PacketType = 12
    PacketTypeBindNak          PacketType = 13
    PacketTypeAlterContext     PacketType = 14
    PacketTypeAlterContextResp PacketType = 15
    PacketTypeAuth3            PacketType = 16
    PacketTypeShutdown         PacketType = 17
    PacketTypeCoCancel         PacketType = 18
    PacketTypeOrphaned         PacketType = 19
)

func (PacketType) String

func (t PacketType) String() string

String returns the mnemonic name of the packet type.

type PresentationResult

PresentationResult is one server response in a bind_ack p_result_list (p_result_t): the negotiation result, an optional reason, and the accepted transfer syntax.

Reference: [C706] section 12.6.3.1 (“The bind_ack PDU”): https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm

type PresentationResult struct {
    Result         uint16
    Reason         uint16
    TransferSyntax syntax.SyntaxID
}

func (*PresentationResult) Marshal

func (r *PresentationResult) Marshal() ([]byte, error)

Marshal serializes a single presentation result (24 bytes).

func (*PresentationResult) Unmarshal

func (r *PresentationResult) Unmarshal(data []byte) (int, error)

Unmarshal parses a single presentation result and returns the bytes consumed.

type ProtocolVersion

ProtocolVersion is one supported RPC protocol version (p_rt_version_t).

type ProtocolVersion struct {
    Major uint8
    Minor uint8
}

type Request

Request is a request PDU: it carries a method call (opnum) and its marshalled arguments (stub data) to the server.

When the PFC_OBJECT_UUID flag is set, a 16-byte object UUID precedes the stub data; otherwise it is absent. Stub data is 8-octet aligned, which the fixed 8-byte body (plus an optional 16-byte object UUID) already satisfies.

Reference: [C706] section 12.6.3.1 (“The request PDU”): https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm

type Request struct {
    Header     Header
    AllocHint  uint32
    ContextID  uint16
    Opnum      uint16
    ObjectUUID *guid.GUID // present iff PFC_OBJECT_UUID is set
    Stub       []byte
}

func (*Request) Marshal

func (r *Request) Marshal() ([]byte, error)

Marshal serializes the complete request PDU. If ObjectUUID is non-nil the PFC_OBJECT_UUID flag is set automatically. AllocHint defaults to len(Stub) when left zero.

func (*Request) String

func (r *Request) String() string

String returns a one-line summary.

func (*Request) Unmarshal

func (r *Request) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete request PDU and returns the bytes consumed.

type Response

Response is a response PDU: it carries the marshalled return values (stub data) of a successful call back to the client.

Reference: [C706] section 12.6.3.1 (“The response PDU”): https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm

type Response struct {
    Header      Header
    AllocHint   uint32
    ContextID   uint16
    CancelCount uint8
    Stub        []byte
}

func (*Response) Marshal

func (r *Response) Marshal() ([]byte, error)

Marshal serializes the complete response PDU.

func (*Response) String

func (r *Response) String() string

String returns a one-line summary.

func (*Response) Unmarshal

func (r *Response) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete response PDU and returns the bytes consumed.

type SecTrailer

SecTrailer is the fixed 8-byte security trailer (auth_verifier_co_t) that sits between a PDU’s body and its authentication token (auth_value). The header’s auth_length counts only the auth_value that follows this trailer, not the trailer itself.

References:

type SecTrailer struct {
    AuthType      uint8  // security provider (auth_type)
    AuthLevel     uint8  // protection level (auth_level)
    AuthPadLength uint8  // bytes of padding inserted before the trailer to 4-byte-align it
    AuthReserved  uint8  // must be zero
    AuthContextID uint32 // identifies the security context within the connection
}

func ExtractAuthVerifier

func ExtractAuthVerifier(raw []byte) (*SecTrailer, []byte, error)

ExtractAuthVerifier returns the sec_trailer and auth_value from the tail of a complete PDU, located using the common header’s auth_length: the last auth_length bytes are the auth_value, preceded by the 8-byte sec_trailer. It returns nil, nil when the PDU carries no authentication verifier (auth_length == 0).

func (*SecTrailer) Marshal

func (s *SecTrailer) Marshal() []byte

Marshal serializes the 8-byte sec_trailer.

func (*SecTrailer) Unmarshal

func (s *SecTrailer) Unmarshal(data []byte) error

Unmarshal parses an 8-byte sec_trailer from the front of data.