DCE/RPC

The DCE/RPC implementation uses two separate configuration sections, which are both listed below.

Section [RPC]

Added in version 1.0.0.dev2.

RPC.ErrorCode: int | str = "rpc_s_access_denied"

Maps to rpc.RPCConfig.rpc_error_code.

Specifies the error code to return after successful authentication.

RPC.Interfaces: List[str]

Maps to rpc.RPCConfig.rpc_modules.

A list of directory paths containing external modules or files to be loaded as extensions for specific RPC interfaces. For example, modules located in dementor/protocols/msrpc will always be imported.

These modules differ slightly from the standard extension mechanism. Each extension module may define:

protocol.__uuid__: str | bytes | List[str | bytes]

Contains one or more interface UUIDs associated with the protocol. If a client connects using one of these UUIDs, the associated handler will be invoked.

Example __uuid__ definition for EPM
__uuid__ = "E1AF8308-5D1F-11C9-91A4-08002B14A0FA"

The value may be a string, binary UUID, or a list of either.

protocol.handle_request(rpc: RPCHandler, request: rpcrt.MSRPCRequestHeader, data) int

Optional if RPCEndpointHandlerClass is provided.

Defines a callback invoked by RPCHandler for requests matching the UUID. The request object is from the impacket library.

Return values:

  • 0: Success — continue listening for additional packets.

  • Any other value: An error is sent in a FAULT response and the connection is closed.

class protocol.RPCEndpointHandlerClass

Optional if handle_request() is defined.

Defines a class to handle RPC requests. It must be instantiable without arguments and must implement the __call__ method:

__call__(self, rpc: RPCHandler, request: rpcrt.MSRPCRequestHeader, data: bytes) int

Same behavior as handle_request().

Hint

You may alias your custom class as RPCEndpointHandlerClass:

custom.py
class MyHandler:
    ...

RPCEndpointHandlerClass = MyHandler

Currently, only two interfaces are implemented: EPMv4 and DCOM. Refer to the source code for implementation details.

RPC.ExtendedSessionSecurity: bool = true

Maps to rpc.RPCConfig.ntlm_ess.

Changed in version 1.0.0.dev5: Internal mapping changed from rpc_ntlm_ess to ntlm_ess

Enables Extended Session Security (ESS) during NTLM authentication. With ESS enabled, NTLMv1/v2-SSP hashes are captured instead of standard NTLM hashes.

Resolution precedence:

  1. RPC.Server.ExtendedSessionSecurity (per-server)

  2. RPC.ExtendedSessionSecurity (global fallback)

  3. NTLM.ExtendedSessionSecurity (final fallback)

Server.Challenge: str = NTLM.Challenge

Maps to rpc.RPCConfig.ntlm_challenge.

Changed in version 1.0.0.dev5: Internal mapping changed from rpc_ntlm_challenge to ntlm_challenge

Sets the NTLM challenge value used during authentication. Resolution precedence:

  1. RPC.Server.Challenge

  2. RPC.Challenge

  3. NTLM.Challenge

Server.FQDN: str = "DEMENTOR"

Maps to rpc.RPCConfig.rpc_fqdn. Can also be set in [Globals]

Specifies the Fully Qualified Domain Name (FQDN) used by the server. The hostname part is included in NTLM responses. The domain part is optional.

Section [EPM]

Added in version 1.0.0.dev2.

EPM.TargetPort: int = 49000

Maps to rpc.RPCConfig.epm_port.

Defines the static port used for RPC communication when a client sends a Map request.

EPM.TargetPortRange: str | dict

Maps to rpc.RPCConfig.epm_port_range.

Overrides EPM.TargetPort and randomly selects a port from a specified range.

Supported formats:

  • [START]-END: START is optional; defaults to 45000.

  • START-[END]: END is optional; defaults to 49999.

Alternatively, use a dictionary:

PortRange = { start = 45000, end = 49999 }

Attention

The random port is selected once at startup — not per client.

Default Configuration

DCE/RPC configuration (default values)
1[RPC]
2ErrorCode = "rpc_s_access_denied"
3
4[EPM]
5TargetPort = 49000