2016-07-19 15:48:55 +00:00
|
|
|
/* Benjamin DELPY `gentilkiwi`
|
|
|
|
http://blog.gentilkiwi.com
|
|
|
|
benjamin@gentilkiwi.com
|
|
|
|
Licence : https://creativecommons.org/licenses/by/4.0/
|
|
|
|
*/
|
|
|
|
#include "kull_m_rpc.h"
|
|
|
|
|
|
|
|
BOOL kull_m_rpc_createBinding(LPCWSTR ProtSeq, LPCWSTR NetworkAddr, LPCWSTR Endpoint, LPCWSTR Service, DWORD ImpersonationType, RPC_BINDING_HANDLE *hBinding, void (RPC_ENTRY * RpcSecurityCallback)(void *))
|
|
|
|
{
|
|
|
|
BOOL status = FALSE;
|
|
|
|
RPC_STATUS rpcStatus;
|
|
|
|
RPC_WSTR StringBinding = NULL;
|
|
|
|
RPC_SECURITY_QOS SecurityQOS = {RPC_C_SECURITY_QOS_VERSION, RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH, RPC_C_QOS_IDENTITY_STATIC, ImpersonationType};
|
|
|
|
LPWSTR fullServer;
|
|
|
|
DWORD szServer = (DWORD) (wcslen(NetworkAddr) * sizeof(wchar_t)), szPrefix = (DWORD) (wcslen(Service) * sizeof(wchar_t));
|
|
|
|
|
|
|
|
*hBinding = NULL;
|
|
|
|
rpcStatus = RpcStringBindingCompose(NULL, (RPC_WSTR) ProtSeq, (RPC_WSTR) NetworkAddr, (RPC_WSTR) Endpoint, NULL, &StringBinding);
|
|
|
|
if(rpcStatus == RPC_S_OK)
|
|
|
|
{
|
|
|
|
rpcStatus = RpcBindingFromStringBinding(StringBinding, hBinding);
|
|
|
|
if(rpcStatus == RPC_S_OK)
|
|
|
|
{
|
|
|
|
if(*hBinding)
|
|
|
|
{
|
|
|
|
if(fullServer = (LPWSTR) LocalAlloc(LPTR, szPrefix + sizeof(wchar_t) + szServer + sizeof(wchar_t)))
|
|
|
|
{
|
|
|
|
RtlCopyMemory(fullServer, Service, szPrefix);
|
|
|
|
RtlCopyMemory((PBYTE) fullServer + szPrefix + sizeof(wchar_t), NetworkAddr, szServer);
|
|
|
|
((PBYTE) fullServer)[szPrefix] = L'/';
|
2017-02-26 01:10:41 +00:00
|
|
|
rpcStatus = RpcBindingSetAuthInfoEx(*hBinding, (RPC_WSTR) fullServer, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, (MIMIKATZ_NT_MAJOR_VERSION < 6) ? RPC_C_AUTHN_GSS_KERBEROS : RPC_C_AUTHN_GSS_NEGOTIATE, NULL, 0, &SecurityQOS);
|
2016-07-19 15:48:55 +00:00
|
|
|
if(rpcStatus == RPC_S_OK)
|
|
|
|
{
|
|
|
|
if(RpcSecurityCallback)
|
|
|
|
{
|
|
|
|
rpcStatus = RpcBindingSetOption(*hBinding, RPC_C_OPT_SECURITY_CALLBACK, (ULONG_PTR) RpcSecurityCallback);
|
|
|
|
status = (rpcStatus == RPC_S_OK);
|
|
|
|
if(!status)
|
|
|
|
PRINT_ERROR(L"RpcBindingSetOption: 0x%08x (%u)\n", rpcStatus, rpcStatus);
|
|
|
|
}
|
|
|
|
else status = TRUE;
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"RpcBindingSetAuthInfoEx: 0x%08x (%u)\n", rpcStatus, rpcStatus);
|
|
|
|
LocalFree(fullServer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"No Binding!\n");
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"RpcBindingFromStringBinding: 0x%08x (%u)\n", rpcStatus, rpcStatus);
|
|
|
|
RpcStringFree(&StringBinding);
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"RpcStringBindingCompose: 0x%08x (%u)\n", rpcStatus, rpcStatus);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL kull_m_rpc_deleteBinding(RPC_BINDING_HANDLE *hBinding)
|
|
|
|
{
|
|
|
|
BOOL status = FALSE;
|
|
|
|
if(status = (RpcBindingFree(hBinding) == RPC_S_OK))
|
|
|
|
*hBinding = NULL;
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t cBytes)
|
|
|
|
{
|
2016-07-31 00:02:19 +00:00
|
|
|
return LocalAlloc(LPTR, cBytes);
|
2016-07-19 15:48:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __RPC_USER midl_user_free(void __RPC_FAR * p)
|
|
|
|
{
|
2016-07-31 00:02:19 +00:00
|
|
|
LocalFree(p);
|
2016-07-19 15:48:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __RPC_USER ReadFcn(void *State, char **pBuffer, unsigned int *pSize)
|
|
|
|
{
|
|
|
|
*pBuffer = (char *) ((PKULL_M_RPC_FCNSTRUCT) State)->addr;
|
|
|
|
((PKULL_M_RPC_FCNSTRUCT) State)->addr = *pBuffer + *pSize;
|
|
|
|
((PKULL_M_RPC_FCNSTRUCT) State)->size -= *pSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __RPC_USER WriteFcn(void *State, char *Buffer, unsigned int Size)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void __RPC_USER AllocFcn (void *State, char **pBuffer, unsigned int *pSize)
|
|
|
|
{
|
2016-07-29 18:04:05 +00:00
|
|
|
}
|
|
|
|
|
2016-07-31 00:02:19 +00:00
|
|
|
BOOL kull_m_rpc_Generic_Decode(PVOID data, DWORD size, PVOID pObject, PGENERIC_RPC_DECODE fDecode)
|
2016-07-29 18:04:05 +00:00
|
|
|
{
|
|
|
|
BOOL status = FALSE;
|
|
|
|
RPC_STATUS rpcStatus;
|
2016-07-31 00:02:19 +00:00
|
|
|
PVOID buffer;
|
|
|
|
KULL_M_RPC_FCNSTRUCT UserState ;
|
2016-07-29 18:04:05 +00:00
|
|
|
handle_t pHandle;
|
|
|
|
|
2016-07-31 00:02:19 +00:00
|
|
|
if(buffer = UserState.addr = LocalAlloc(LPTR, size))
|
2016-07-29 18:04:05 +00:00
|
|
|
{
|
2016-07-31 00:02:19 +00:00
|
|
|
UserState.size = size;
|
|
|
|
RtlCopyMemory(UserState.addr, data, size); // avoid data alteration
|
|
|
|
rpcStatus = MesDecodeIncrementalHandleCreate(&UserState, ReadFcn, &pHandle);
|
2016-07-29 18:04:05 +00:00
|
|
|
if(NT_SUCCESS(rpcStatus))
|
|
|
|
{
|
2016-07-31 00:02:19 +00:00
|
|
|
rpcStatus = MesIncrementalHandleReset(pHandle, NULL, NULL, NULL, NULL, MES_DECODE);
|
|
|
|
if(NT_SUCCESS(rpcStatus))
|
|
|
|
{
|
|
|
|
RpcTryExcept
|
|
|
|
{
|
|
|
|
fDecode(pHandle, pObject);
|
|
|
|
status = TRUE;
|
|
|
|
}
|
|
|
|
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
|
|
|
|
RpcEndExcept
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"MesIncrementalHandleReset: %08x\n", rpcStatus);
|
|
|
|
MesHandleFree(pHandle);
|
2016-07-29 18:04:05 +00:00
|
|
|
}
|
2016-07-31 00:02:19 +00:00
|
|
|
else PRINT_ERROR(L"MesDecodeIncrementalHandleCreate: %08x\n", rpcStatus);
|
|
|
|
LocalFree(buffer);
|
2016-07-29 18:04:05 +00:00
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-07-31 00:02:19 +00:00
|
|
|
void kull_m_rpc_Generic_Free(PVOID pObject, PGENERIC_RPC_FREE fFree)
|
2016-07-29 18:04:05 +00:00
|
|
|
{
|
|
|
|
RPC_STATUS rpcStatus;
|
|
|
|
KULL_M_RPC_FCNSTRUCT UserState = {NULL, 0};
|
|
|
|
handle_t pHandle;
|
|
|
|
|
|
|
|
rpcStatus = MesDecodeIncrementalHandleCreate(&UserState, ReadFcn, &pHandle); // for legacy
|
|
|
|
if(NT_SUCCESS(rpcStatus))
|
|
|
|
{
|
2016-07-31 00:02:19 +00:00
|
|
|
RpcTryExcept
|
|
|
|
fFree(pHandle, pObject);
|
|
|
|
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
|
|
|
|
RpcEndExcept
|
2016-07-29 18:04:05 +00:00
|
|
|
MesHandleFree(pHandle);
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"MesDecodeIncrementalHandleCreate: %08x\n", rpcStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL kull_m_rpc_Generic_Encode(PVOID pObject, PVOID *data, DWORD *size, PGENERIC_RPC_ENCODE fEncode, PGENERIC_RPC_ALIGNSIZE fAlignSize)
|
|
|
|
{
|
|
|
|
BOOL status = FALSE;
|
|
|
|
RPC_STATUS rpcStatus;
|
|
|
|
KULL_M_RPC_FCNSTRUCT UserState;
|
|
|
|
handle_t pHandle;
|
|
|
|
|
|
|
|
rpcStatus = MesEncodeIncrementalHandleCreate(&UserState, ReadFcn, WriteFcn, &pHandle);
|
|
|
|
if(NT_SUCCESS(rpcStatus))
|
|
|
|
{
|
|
|
|
*size = (DWORD) fAlignSize(pHandle, pObject);
|
|
|
|
if(*data = LocalAlloc(LPTR, *size))
|
|
|
|
{
|
|
|
|
rpcStatus = MesIncrementalHandleReset(pHandle, NULL, NULL, NULL, NULL, MES_ENCODE);
|
|
|
|
if(NT_SUCCESS(rpcStatus))
|
|
|
|
{
|
|
|
|
UserState.addr = *data;
|
|
|
|
UserState.size = *size;
|
2016-07-31 00:02:19 +00:00
|
|
|
RpcTryExcept
|
|
|
|
{
|
|
|
|
fEncode(pHandle, pObject);
|
|
|
|
status = TRUE;
|
|
|
|
}
|
|
|
|
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
|
|
|
|
RpcEndExcept
|
2016-07-29 18:04:05 +00:00
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"MesIncrementalHandleReset: %08x\n", rpcStatus);
|
|
|
|
|
|
|
|
if(!status)
|
|
|
|
{
|
|
|
|
*data = LocalFree(*data);
|
|
|
|
*size = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MesHandleFree(pHandle);
|
|
|
|
}
|
|
|
|
else PRINT_ERROR(L"MesEncodeIncrementalHandleCreate: %08x\n", rpcStatus);
|
|
|
|
return status;
|
2016-07-19 15:48:55 +00:00
|
|
|
}
|