Microsoft Windows uses its implementation of Distributed Computing Environment/Remote Procedure Call (DCE/RPC), which it calls Microsoft RPC, to call certain APIs remotely.

A Remote Procedure Call is initiated by communicating to the RPC Endpoint Mapper, which exists as the Windows service RpcEptMapper and listens on the port 135/tcp. The endpoint mapper resolves a requested endpoint/interface and responds to the client with the port that the service is listening on. Since the RPC endpoints are assigned ports when the services start, these ports are dynamically assigned from 49152 to 65535. The connection to the endpoint mapper then terminates and the client program can communicate directly with the requested service.

RPC is a legitimate functionality of Windows that allows remote interaction with a variety of services. For a Windows environment to be properly configured, several programs use RPC to communicate legitimately with servers. The background and benign RPC activity may be enormous, but must be learned, especially peer-to-peer RPC between workstations, which is often indicative of Lateral Movement.

According to ATT&CK, adversaries frequently use RPC connections to remotely

Additional endpoints are detailed at here.

ATT&CK Detection

Technique Tactic Level of Coverage
Valid Accounts Lateral Movement Moderate
Remote Services Lateral Movement Moderate

Pseudocode

Traffic to the RPC Endpoint Mapper will always have the destination port of 135. Assuming success, RPC traffic will continue to the endpoint. The endpoint and the client both bind to dynamically assigned ports (on Windows, this is typically greater than 49152). The traffic between the client and endpoint can be detected by looking at traffic to 135 followed by traffic where the source and destination ports are at least 49152.

flows = search Flow:Start
rpc_mapper = filter flows where (dest_port == 135)
rpc_endpoint = filter flows where (dest_port >= 49152 and src_port >= 49152)
rpc = join rpc_mapper, rpc_endpoint where (
 (rpc_mapper.time < rpc_endpoint.time < rpc_mapper.time + 2 seconds) and
 (rpc_mapper.src_ip == rpc_endpoint.src_ip and rpc_mapper.dest_ip == rpc_endpoint.dest_ip)
)
output rpc

Data Model References

Object Action Field
flow start dest_port
flow start src_port