由于RPCRT4.dll在不同版本中提供了不同的服务注册接口,存在一些兼容问题,那么没办法,只有把可能途经访问到的函数都做一下劫持。
劫持点如下标出,顺序为低版本到高版本:
RPC_STATUS RPC_ENTRY RpcEpRegisterW(
RPC_IF_HANDLE IfSpec,
RPC_BINDING_VECTOR *BindingVector,
UUID_VECTOR *UuidVector,
RPC_WSTR Annotation
)
RPC_STATUS RPC_ENTRY RpcServerRegisterIfEx(
RPC_IF_HANDLE IfSpec,
UUID *MgrTypeUuid,
RPC_MGR_EPV *MgrEpv,
unsigned int Flags,
unsigned int MaxCalls,
RPC_IF_CALLBACK_FN *IfCallback
)
RPC_STATUS RPC_ENTRY RpcServerRegisterIf3(
RPC_IF_HANDLE IfSpec,
UUID *MgrTypeUuid,
RPC_MGR_EPV *MgrEpv,
unsigned int Flags,
unsigned int MaxCalls,
unsigned int MaxRpcSize,
RPC_IF_CALLBACK_FN *IfCallback,
void *SecurityDescriptor
)
在注册过程中有一个最为明显的特征,可以标识出是我们想要的RPC组件服务进行了注册,就是IfSpec->InterfaceId.SyntaxGUID,本文讨论的这个GUID,目前为止还都是同一个:0x367ABB81, 0x9844, 0x35F1, 0xAD, 0x32, 0x98, 0xF0, 0x38, 0x00, 0x10, 0x03
即 {367ABB81-9844-35F1-AD32-98F038001003}。
劫持了一些我们感兴趣的RPC函数之后,却还有一个大的问题,那就是怎么拿到客户端的进程/线程信息~
幸运的是,RPCRT4.dll提供了一些函数,可以很方便的查到客户端是谁,I_RpcOpenClientThread,
I_RpcOpenClientProcess。
而且services.exe的TOKEN所在组(应该是属于Admin),没有拒绝TOKEN的问题,但是换到一些低权限组那没办法,只能用一些别的方法了~
使用
I_RpcOpenClientThread
/
I_RpcOpenClientProcess时注意DesiredAccess不要太高就行,要啥权限就写啥权限,一般而言QUERY_INFORMATION就行。
详细的实现部分就不继续说了,见附件内容。