UINT32 PrvScenarioAppContainerEnumExisting() { UINT32 status = NO_ERROR; UINT32 numAppContainers = 0; INET_FIREWALL_APP_CONTAINER* pAppContainers = 0; status = NetworkIsolationEnumAppContainers(NETISO_FLAG_FORCE_COMPUTE_BINARIES, (DWORD*)&numAppContainers, &pAppContainers); HLPR_BAIL_ON_FAILURE(status); for(UINT32 containerIndex = 0; containerIndex < numAppContainers; containerIndex++) { status = PrvScenarioAppContainerAddFwpmObjects(pAppContainers[containerIndex].appContainerSid, pAppContainers[containerIndex].userSid, pAppContainers[containerIndex].displayName); HLPR_BAIL_ON_FAILURE(status); } HLPR_BAIL_LABEL: return status; }
UINT32 ScenarioAppContainerAdd(_In_ BOOLEAN trustWSH, _In_ BOOLEAN persistent, _In_ BOOLEAN bootTime) { UINT32 status = NO_ERROR; if(trustWSH) status = PrvScenarioAppContainerAddFwpmObjects(persistent, bootTime); else { status = PrvScenarioAppContainerRegister(); HLPR_BAIL_ON_FAILURE(status); status = PrvScenarioAppContainerEnumExisting(); HLPR_BAIL_ON_FAILURE(status); } HLPR_BAIL_LABEL: if(status == NO_ERROR) scenarioConfigured = TRUE; return status; }
VOID PowerStateCallback(_In_ VOID* pCallbackContext, _In_ VOID* pPowerStateEvent, _In_ VOID* pEventSpecifics) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> PowerStateCallback()\n"); #endif /// DBG UNREFERENCED_PARAMETER(pCallbackContext); if(pPowerStateEvent == (VOID*)PO_CB_SYSTEM_STATE_LOCK) { NTSTATUS status = STATUS_SUCCESS; if(pEventSpecifics) { /// entering the ON state (S0), so return operation to normal if(g_calloutsRegistered == FALSE) { status = KrnlHlprExposedCalloutsRegister(); HLPR_BAIL_ON_FAILURE(status); g_calloutsRegistered = TRUE; } } else { /// leaving the ON state (S0) to sleep (S1/S2/S3) or hibernate (S4) /// Unregister the callouts so no more injection will take place. By default, the filters /// invoking the callouts will return block. if(g_calloutsRegistered == TRUE) { status = KrnlHlprExposedCalloutsUnregister(); HLPR_BAIL_ON_FAILURE(status); g_calloutsRegistered = FALSE; } } } HLPR_BAIL_LABEL: #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- PowerStateCallback()\n"); #endif /// DBG return; }
NTSTATUS KrnlHlprThreadedDPCQueue(_In_ KDEFERRED_ROUTINE* pDPCFn, _In_ CLASSIFY_DATA* pClassifyData, _In_opt_ INJECTION_DATA* pInjectionData, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprThreadedDPCQueue()\n"); #endif /// DBG NT_ASSERT(pDPCFn); NT_ASSERT(pClassifyData); NTSTATUS status = STATUS_SUCCESS; DPC_DATA* pDPCData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pDPCData will be freed by caller status = KrnlHlprDPCDataCreate(&pDPCData, pClassifyData, pInjectionData, pContext); HLPR_BAIL_ON_FAILURE(status); #pragma warning(pop) KeInitializeThreadedDpc(&(pDPCData->kdpc), pDPCFn, 0); KeInsertQueueDpc(&(pDPCData->kdpc), pDPCData, 0); HLPR_BAIL_LABEL: #pragma warning(push) #pragma warning(disable: 6001) /// pDPCData initialized with call to KrnlHlprDPCDataCreate if(status != STATUS_SUCCESS && pDPCData) KrnlHlprDPCDataDestroy(&pDPCData); #pragma warning(pop) #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprThreadedDPCQueue() [status: %#x]\n", status); #endif /// DBG return status; }
_IRQL_requires_same_ VOID SubscriptionBFEStateChangeCallback(_Inout_ VOID* pContext, _In_ FWPM_SERVICE_STATE bfeState) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> SubscriptionBFEStateChangeCallback()\n"); #endif /// DBG NT_ASSERT(pContext); NTSTATUS status = STATUS_SUCCESS; WFPSAMPLER_DEVICE_DATA* pDeviceData = (WFPSAMPLER_DEVICE_DATA*)pContext; switch(bfeState) { case FWPM_SERVICE_RUNNING: { if(pDeviceData->pEngineHandle == 0) { status = KrnlHlprFwpmSessionCreateEngineHandle(&(pDeviceData->pEngineHandle)); HLPR_BAIL_ON_FAILURE(status); } break; } case FWPM_SERVICE_STOP_PENDING: { KrnlHlprFwpmSessionDestroyEngineHandle(&(pDeviceData->pEngineHandle)); break; } } HLPR_BAIL_LABEL: #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- SubscriptionBFEStateChangeCallback() [status: %#x]\n", status); #endif /// DBG return; }
DWORD WindowsFirewallNotifyThreadStartRoutine(_In_ LPVOID lpThreadParameter) { ASSERT(lpThreadParameter); UINT32 status = NO_ERROR; THREAD_DATA* pThreadData = (THREAD_DATA*)lpThreadParameter; SERVICE_NOTIFY svcNotify = {0}; HlprEventSet(pThreadData->threadStartEvent); svcNotify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; svcNotify.pfnNotifyCallback = WindowsFirewallNotification; svcNotify.pContext = pWFNotifyThread; status = HlprServiceNotificationStateChangeRegister(L"MPSSvc", &svcNotify, SERVICE_NOTIFY_RUNNING, &scmHandle, &mpsSvcHandle); HLPR_BAIL_ON_FAILURE(status); status = WaitForSingleObjectEx(mpsSvcHandle, INFINITE, TRUE); if(status != WAIT_IO_COMPLETION) { if(status == WAIT_FAILED) status = GetLastError(); HlprLogError(L"WindowsFirewallNotifyThreadStartRoutine : WaitForSingleObjectEx() [status: %#x]", status); } HLPR_BAIL_LABEL: HLPR_CLOSE_SERVICE_HANDLE(mpsSvcHandle); HLPR_CLOSE_SERVICE_HANDLE(scmHandle); return status; }
NTSTATUS KrnlHlprClassifyDataAcquireLocalCopy(_Inout_ CLASSIFY_DATA* pClassifyData, _In_ const FWPS_INCOMING_VALUES* pClassifyValues, _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata, _In_opt_ VOID* pPacket, _In_opt_ const VOID* pClassifyContext, _In_ const FWPS_FILTER* pFilter, _In_ const UINT64 flowContext, _In_ FWPS_CLASSIFY_OUT* pClassifyOut) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprClassifyDataAcquireLocalCopy()\n"); #endif /// DBG NT_ASSERT(pClassifyData); NT_ASSERT(pClassifyValues); NT_ASSERT(pMetadata); NT_ASSERT(pFilter); NT_ASSERT(pClassifyOut); NTSTATUS status = STATUS_SUCCESS; pClassifyData->pClassifyValues = KrnlHlprFwpsIncomingValuesCreateLocalCopy(pClassifyValues); HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pClassifyValues, status); pClassifyData->pMetadataValues = KrnlHlprFwpsIncomingMetadataValuesCreateLocalCopy(pMetadata); HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pMetadataValues, status); if(pPacket) { if(pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 || pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD || pClassifyValues->layerId == FWPS_LAYER_STREAM_V6 || pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD) { pClassifyData->pPacket = KrnlHlprFwpsStreamCalloutIOPacketCreateLocalCopy((FWPS_STREAM_CALLOUT_IO_PACKET*)pPacket); HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pPacket, status); } #if(NTDDI_VERSION >= NTDDI_WIN7) /// LayerData at the FWPM_LAYER_ALE_{BIND/CONNECT}_REDIRECT_V{4/6} is obtained via KrnlHlprRedirectDataCreate() else if(pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V6) { pClassifyData->pPacket = 0; } #endif /// (NTDDI_VERSION >= NTDDI_WIN7) else { if(NET_BUFFER_LIST_NEXT_NBL((NET_BUFFER_LIST*)pPacket)) { pClassifyData->chainedNBL = TRUE; pClassifyData->numChainedNBLs = 1; } if(pClassifyData->chainedNBL && ( /// The IPPACKET and IPFORWARD Layers allow for Fragment Grouping if the option is enabled pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6 || pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 || pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6 #if(NTDDI_VERSION >= NTDDI_WIN8) /// The NDIS layers allow for batched NBLs provided the callout was registered with FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY set || pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET || pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET || pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_NATIVE || pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_NATIVE || pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_ETHERNET || pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_ETHERNET #endif /// (NTDDI_VERSION >= NTDDI_WIN8) )) { for(NET_BUFFER_LIST* pCurrentNBL = (NET_BUFFER_LIST*)pPacket; pCurrentNBL; pClassifyData->numChainedNBLs++) { NET_BUFFER_LIST* pNextNBL = NET_BUFFER_LIST_NEXT_NBL(pCurrentNBL); FwpsReferenceNetBufferList(pCurrentNBL, TRUE); pCurrentNBL = pNextNBL; #if DBG InterlockedIncrement64((LONG64*)&(g_OutstandingNBLReferences)); #endif /// DBG } pClassifyData->pPacket = pPacket; } else { /// Otherwise we expect to receive a single NBL NT_ASSERT(NET_BUFFER_LIST_NEXT_NBL((NET_BUFFER_LIST*)pPacket) == 0); FwpsReferenceNetBufferList((NET_BUFFER_LIST*)pPacket, TRUE); pClassifyData->pPacket = pPacket; #if DBG InterlockedIncrement64((LONG64*)&(g_OutstandingNBLReferences)); #endif /// DBG } } } #if(NTDDI_VERSION >= NTDDI_WIN7) if(pClassifyContext) { /// ClassifyHandle for these layers is obtained in REDIRECT_DATA if(pClassifyValues->layerId != FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 && pClassifyValues->layerId != FWPS_LAYER_ALE_CONNECT_REDIRECT_V6 && pClassifyValues->layerId != FWPS_LAYER_ALE_BIND_REDIRECT_V4 && pClassifyValues->layerId != FWPS_LAYER_ALE_BIND_REDIRECT_V6) { status = FwpsAcquireClassifyHandle((VOID*)pClassifyContext, 0, &(pClassifyData->classifyContextHandle)); HLPR_BAIL_ON_FAILURE(status); } } #else UNREFERENCED_PARAMETER(pClassifyContext); #endif /// (NTDDI_VERSION >= NTDDI_WIN7) if(pFilter) { pClassifyData->pFilter = KrnlHlprFwpsFilterCreateLocalCopy(pFilter); HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pFilter, status); } pClassifyData->flowContext = flowContext; if(pClassifyOut) { pClassifyData->pClassifyOut = KrnlHlprFwpsClassifyOutCreateLocalCopy(pClassifyOut); HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pClassifyOut, status); } HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) KrnlHlprClassifyDataReleaseLocalCopy(pClassifyData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprClassifyDataAcquireLocalCopy() [status: %#x]\n", status); #endif /// DBG return status; }
UINT32 PrvScenarioProxyDeleteFwpmObjects(_In_ const FWPM_FILTER* pFilter) { ASSERT(pFilter); UINT32 status = NO_ERROR; HANDLE engineHandle = 0; HANDLE enumHandle = 0; UINT32 entryCount = 0; FWPM_FILTER** ppFilters = 0; FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0}; FWPM_PROVIDER_CONTEXT_ENUM_TEMPLATE providerContextEnumTemplate = {0}; GUID calloutKey = {0}; #if(NTDDI_VERSION >= NTDDI_WIN7) if(pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 || pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V6 || pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V4 || pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V6) calloutKey = WFPSAMPLER_CALLOUT_PROXY_BY_ALE_REDIRECT; else #endif /// (NTDDI_VERSION >= NTDDI_WIN7) calloutKey = WFPSAMPLER_CALLOUT_PROXY_BY_INJECTION; calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(pFilter->layerKey)); /// Uniquely identifies the callout used providerContextEnumTemplate.providerContextType = FWPM_GENERAL_CONTEXT; filterEnumTemplate.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filterEnumTemplate.layerKey = pFilter->layerKey; filterEnumTemplate.enumType = FWP_FILTER_ENUM_FULLY_CONTAINED; filterEnumTemplate.flags = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME | FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED; filterEnumTemplate.numFilterConditions = pFilter->numFilterConditions; filterEnumTemplate.filterCondition = pFilter->filterCondition; filterEnumTemplate.providerContextTemplate = &providerContextEnumTemplate; filterEnumTemplate.actionMask = FWP_ACTION_FLAG_CALLOUT; filterEnumTemplate.calloutKey = &calloutKey; status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterCreateEnumHandle(engineHandle, &filterEnumTemplate, &enumHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterEnum(engineHandle, enumHandle, 0xFFFFFFFF, &ppFilters, &entryCount); HLPR_BAIL_ON_FAILURE(status); if(ppFilters) { for(UINT32 filterIndex = 0; filterIndex < entryCount; filterIndex++) { HlprFwpmFilterDeleteByKey(engineHandle, &(ppFilters[filterIndex]->filterKey)); HlprFwpmCalloutDeleteByKey(engineHandle, &(ppFilters[filterIndex]->action.calloutKey)); if(ppFilters[filterIndex]->flags & FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT) HlprFwpmProviderContextDeleteByKey(engineHandle, &(ppFilters[filterIndex]->providerContextKey)); } FwpmFreeMemory((void**)&ppFilters); } HLPR_BAIL_LABEL: if(engineHandle) { if(enumHandle) HlprFwpmFilterDestroyEnumHandle(engineHandle, &enumHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
UINT32 PrvScenarioProxyAddFwpmObjects(_In_ const FWPM_FILTER* pFilter, _In_ const PC_PROXY_DATA* pPCProxyData) { ASSERT(pFilter); ASSERT(pPCProxyData); UINT32 status = NO_ERROR; HANDLE engineHandle = 0; FWP_BYTE_BLOB byteBlob = {0}; FWPM_PROVIDER_CONTEXT providerContext = {0}; FWPM_CALLOUT callout = {0}; FWPM_FILTER filter = {0}; RtlCopyMemory(&filter, pFilter, sizeof(FWPM_FILTER)); status = HlprGUIDPopulate(&(providerContext.providerContextKey)); HLPR_BAIL_ON_FAILURE(status); providerContext.displayData.name = L"WFPSampler's Proxy ProviderContext"; providerContext.displayData.description = L"Instructs the driver where to proxy the socket or connection"; providerContext.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; providerContext.type = FWPM_GENERAL_CONTEXT; providerContext.dataBuffer = &byteBlob; providerContext.dataBuffer->size = sizeof(PC_PROXY_DATA); providerContext.dataBuffer->data = (UINT8*)pPCProxyData; #if(NTDDI_VERSION >= NTDDI_WIN7) if(pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 || pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V6 || pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V4 || pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V6) callout.calloutKey = WFPSAMPLER_CALLOUT_PROXY_BY_ALE_REDIRECT; else #endif /// (NTDDI_VERSION >= NTDDI_WIN7) callout.calloutKey = WFPSAMPLER_CALLOUT_PROXY_BY_INJECTION; callout.calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(filter.layerKey)); /// Uniquely identifies the callout used callout.displayData.name = L"WFPSampler's Proxy Callout"; callout.displayData.description = L"Proxies the socket or connection to the designated destination"; callout.flags = FWPM_CALLOUT_FLAG_USES_PROVIDER_CONTEXT; callout.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; callout.applicableLayer = filter.layerKey; status = HlprGUIDPopulate(&(filter.filterKey)); HLPR_BAIL_ON_FAILURE(status); filter.flags |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT; filter.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filter.subLayerKey = WFPSAMPLER_SUBLAYER; filter.weight.type = FWP_UINT8; filter.weight.uint8 = 0xF; filter.action.type = FWP_ACTION_CALLOUT_UNKNOWN; filter.action.calloutKey = callout.calloutKey; filter.providerContextKey = providerContext.providerContextKey; if(filter.flags & FWPM_FILTER_FLAG_BOOTTIME || filter.flags & FWPM_FILTER_FLAG_PERSISTENT) { providerContext.flags |= FWPM_PROVIDER_CONTEXT_FLAG_PERSISTENT; callout.flags |= FWPM_CALLOUT_FLAG_PERSISTENT; } status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionBegin(engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmProviderContextAdd(engineHandle, &providerContext); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmCalloutAdd(engineHandle, &callout); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterAdd(engineHandle, &filter); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionCommit(engineHandle); HLPR_BAIL_ON_FAILURE(status); HLPR_BAIL_LABEL: if(engineHandle) { if(status != NO_ERROR) HlprFwpmTransactionAbort(engineHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
UINT32 PrvScenarioFastStreamInjectionDeleteFwpmObjects(_In_ const FWPM_FILTER* pFilter) { ASSERT(pFilter); UINT32 status = NO_ERROR; HANDLE engineHandle = 0; HANDLE enumHandle = 0; UINT32 entryCount = 0; FWPM_FILTER** ppFilters = 0; FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0}; GUID calloutKey = {0}; calloutKey = WFPSAMPLER_CALLOUT_FAST_STREAM_INJECTION; calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(pFilter->layerKey)); /// Uniquely identifies the callout used filterEnumTemplate.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filterEnumTemplate.layerKey = pFilter->layerKey; filterEnumTemplate.enumType = FWP_FILTER_ENUM_FULLY_CONTAINED; filterEnumTemplate.flags = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME | FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED; filterEnumTemplate.numFilterConditions = pFilter->numFilterConditions; filterEnumTemplate.filterCondition = pFilter->filterCondition; filterEnumTemplate.actionMask = FWP_ACTION_FLAG_CALLOUT; filterEnumTemplate.calloutKey = &calloutKey; status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterCreateEnumHandle(engineHandle, &filterEnumTemplate, &enumHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterEnum(engineHandle, enumHandle, 0xFFFFFFFF, &ppFilters, &entryCount); HLPR_BAIL_ON_FAILURE(status); if(ppFilters) { for(UINT32 filterIndex = 0; filterIndex < entryCount; filterIndex++) { HlprFwpmFilterDeleteByKey(engineHandle, &(ppFilters[filterIndex]->filterKey)); HlprFwpmCalloutDeleteByKey(engineHandle, &(ppFilters[filterIndex]->action.calloutKey)); } FwpmFreeMemory((void**)&ppFilters); } HLPR_BAIL_LABEL: if(engineHandle) { if(enumHandle) HlprFwpmFilterDestroyEnumHandle(engineHandle, &enumHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
UINT32 PrvScenarioFastStreamInjectionAddFwpmObjects(_In_ const FWPM_FILTER* pFilter) { ASSERT(pFilter); UINT32 status = NO_ERROR; HANDLE engineHandle = 0; FWPM_CALLOUT callout = {0}; FWPM_FILTER filter = {0}; RtlCopyMemory(&filter, pFilter, sizeof(FWPM_FILTER)); callout.calloutKey = WFPSAMPLER_CALLOUT_FAST_STREAM_INJECTION; callout.calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(filter.layerKey)); /// Uniquely identifies the callout used callout.displayData.name = L"WFPSampler's Fast Stream Injection Callout"; callout.displayData.description = L"Causes callout invocation which blindly injects data back into the stream"; callout.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; callout.applicableLayer = filter.layerKey; status = HlprGUIDPopulate(&(filter.filterKey)); HLPR_BAIL_ON_FAILURE(status); filter.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filter.subLayerKey = WFPSAMPLER_SUBLAYER; filter.weight.type = FWP_UINT8; filter.weight.uint8 = 0xF; filter.action.type = FWP_ACTION_CALLOUT_TERMINATING; filter.action.calloutKey = callout.calloutKey; if(filter.flags & FWPM_FILTER_FLAG_BOOTTIME || filter.flags & FWPM_FILTER_FLAG_PERSISTENT) callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT; status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionBegin(engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmCalloutAdd(engineHandle, &callout); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterAdd(engineHandle, &filter); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionCommit(engineHandle); HLPR_BAIL_ON_FAILURE(status); HLPR_BAIL_LABEL: if(engineHandle) { if(status != NO_ERROR) HlprFwpmTransactionAbort(engineHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice, _In_ IO_WORKITEM_ROUTINE* pWorkItemFn, _In_ CLASSIFY_DATA* pClassifyData, _In_ REDIRECT_DATA* pRedirectData, _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemQueue()\n"); #endif /// DBG NT_ASSERT(pWDMDevice); NT_ASSERT(pWorkItemFn); NT_ASSERT(pClassifyData); NT_ASSERT(pRedirectData); NTSTATUS status = STATUS_SUCCESS; PIO_WORKITEM pIOWorkItem = 0; WORKITEM_DATA* pWorkItemData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in KrnlHlprWorkItemDataDestroy pIOWorkItem = IoAllocateWorkItem(pWDMDevice); if(pIOWorkItem == 0) { status = STATUS_UNSUCCESSFUL; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n", status); HLPR_BAIL; } #pragma warning(pop) status = KrnlHlprWorkItemDataCreate(&pWorkItemData, pClassifyData, pRedirectData, pIOWorkItem, pContext); HLPR_BAIL_ON_FAILURE(status); IoQueueWorkItem(pWorkItemData->pIOWorkItem, pWorkItemFn, DelayedWorkQueue, (PVOID)pWorkItemData); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS && pWorkItemData) KrnlHlprWorkItemDataDestroy(&pWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemQueue() [status: %#x]\n", status); #endif /// DBG return status; }
_IRQL_requires_same_ VOID ClassifyPendAuthorization(_In_ const FWPS_INCOMING_VALUES* pClassifyValues, _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata, _Inout_opt_ VOID* pNetBufferList, _In_ const FWPS_FILTER* pFilter, _In_ UINT64 flowContext, _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> ClassifyPendAuthorization()\n"); #endif /// DBG NT_ASSERT(pClassifyValues); NT_ASSERT(pMetadata); NT_ASSERT(pFilter); NT_ASSERT(pClassifyOut); NT_ASSERT(pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6); NT_ASSERT(pFilter->providerContext); NT_ASSERT(pFilter->providerContext->type == FWPM_GENERAL_CONTEXT); NT_ASSERT(pFilter->providerContext->dataBuffer); NT_ASSERT(pFilter->providerContext->dataBuffer->size == sizeof(PC_PEND_AUTHORIZATION_DATA)); NT_ASSERT(pFilter->providerContext->dataBuffer->data); NTSTATUS status = STATUS_SUCCESS; PC_PEND_AUTHORIZATION_DATA* pPendAuthorizationData = (PC_PEND_AUTHORIZATION_DATA*)pFilter->providerContext->dataBuffer->data; /// RESOURCE_ASSIGNTMENT & AUTH_LISTEN will Reauthorize after the completion of the pend. /// AUTH_CONNECT's completeOperation will trigger a Reauthorization if(KrnlHlprFwpsIncomingValueConditionFlagsAreSet(pClassifyValues, FWP_CONDITION_FLAG_IS_REAUTHORIZE)) { if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) pClassifyOut->actionType = pPendAuthorizationData->finalAction; } else { BOOLEAN actionSet = FALSE; if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) { INJECTION_DATA* pInjectionData = 0; PEND_DATA* pPendData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6) { status = KrnlHlprInjectionDataCreate(&pInjectionData, pClassifyValues, pMetadata, (NET_BUFFER_LIST*)pNetBufferList); HLPR_BAIL_ON_FAILURE(status); } #pragma warning(pop) /// AUTH_RECV_ACCEPT's injection will be indicative of PERMIT if(pInjectionData && pInjectionData->injectionState == FWPS_PACKET_INJECTED_BY_SELF) { pClassifyOut->actionType = pPendAuthorizationData->finalAction; actionSet = TRUE; } else { #pragma warning(push) #pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy status = KrnlHlprPendDataCreate(&pPendData, pMetadata, (NET_BUFFER_LIST*)pNetBufferList, pFilter); HLPR_BAIL_ON_FAILURE(status); #pragma warning(pop) status = TriggerPendAuthorizationOutOfBand(pClassifyValues, pMetadata, pNetBufferList, 0, pFilter, flowContext, pClassifyOut, pInjectionData, pPendData, pPendAuthorizationData); } HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) { DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! ClassifyPendAuthorization() [status: %#x]\n", status); if(pInjectionData) KrnlHlprInjectionDataDestroy(&pInjectionData); if(pPendData) KrnlHlprPendDataDestroy(&pPendData); } if(!actionSet) { pClassifyOut->actionType = FWP_ACTION_BLOCK; pClassifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } } } #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- ClassifyPendAuthorization()\n"); #endif /// DBG return; }
NTSTATUS TriggerPendAuthorizationOutOfBand(_In_ const FWPS_INCOMING_VALUES* pClassifyValues, _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata, _Inout_opt_ VOID* pLayerData, _In_opt_ const VOID* pClassifyContext, _In_ const FWPS_FILTER* pFilter, _In_ UINT64 flowContext, _In_ FWPS_CLASSIFY_OUT* pClassifyOut, _Inout_opt_ INJECTION_DATA* pInjectionData, _Inout_ PEND_DATA* pPendData, _In_ PC_PEND_AUTHORIZATION_DATA* pPCData) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> TriggerPendAuthorizationOutOfBand()\n"); #endif /// DBG NT_ASSERT(pClassifyValues); NT_ASSERT(pMetadata); NT_ASSERT(pFilter); NT_ASSERT(pClassifyOut); NT_ASSERT(pPendData); NT_ASSERT(pPCData); NTSTATUS status = STATUS_SUCCESS; CLASSIFY_DATA* pClassifyData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy status = KrnlHlprClassifyDataCreateLocalCopy(&pClassifyData, pClassifyValues, pMetadata, pLayerData, pClassifyContext, pFilter, flowContext, pClassifyOut); HLPR_BAIL_ON_FAILURE(status); #pragma warning(pop) if(pPCData->useWorkItems || pPCData->delay) { /// introducing the delay requires PASSIVE_LEVEL, so force use of a Work Item status = KrnlHlprWorkItemQueue(g_pWDMDevice, PendAuthorizationWorkItemRoutine, pClassifyData, pPendData, (VOID*)pInjectionData); } else { if(pPCData->useThreadedDPC) status = KrnlHlprThreadedDPCQueue(PendAuthorizationDeferredProcedureCall, pClassifyData, pPendData, pInjectionData); else status = KrnlHlprDPCQueue(PendAuthorizationDeferredProcedureCall, pClassifyData, pPendData, pInjectionData); } HLPR_BAIL_ON_FAILURE(status); pClassifyOut->actionType = FWP_ACTION_BLOCK; HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) { if(pClassifyData) KrnlHlprClassifyDataDestroyLocalCopy(&pClassifyData); } #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- TriggerPendAuthorizationOutOfBand() [status: %#x]\n", status); #endif /// DBG return status; }
/** @framework_function="RPCClientInterfaceInitialize" Purpose: Initialize the RPC client interface by creating a fast binding handle. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/AA378651.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/AA375587.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/AA375583.aspx <br> */ UINT32 RPCClientInterfaceInitialize() { RPC_STATUS status = RPC_S_OK; SID* pLocalSystemSID = 0; SIZE_T sidSize = 0; RPC_SECURITY_QOS_V4 securityQoS = {0}; RPC_BINDING_HANDLE_TEMPLATE_V1 bindingHandleTemplate = {0}; RPC_BINDING_HANDLE_SECURITY_V1 bindingHandleSecurity = {0}; RPC_BINDING_HANDLE_OPTIONS_V1 bindingHandleOptions = {0}; HLPR_NEW(pRPCData, RPC_DATA); HLPR_BAIL_ON_ALLOC_FAILURE(pRPCData, status); status = HlprSIDCreate(&pLocalSystemSID, &sidSize, 0, WinLocalSystemSid); HLPR_BAIL_ON_FAILURE(status); wfpSamplerBindingHandle = 0; pRPCData->rpcClientInterfaceHandle = IWFPSampler_v1_0_c_ifspec; /// MIDL generated Client Interface Handle pRPCData->protocolSequence = RPC_PROTSEQ_LRPC; /// Use Local RPC securityQoS.Version = 4; /// Use RPC_SECURITY_QOS_V4 structure securityQoS.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; /// Request mutual authentication from the security provider securityQoS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; /// Security context is created only once securityQoS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY; /// Allow server to get client's identity and allow it's impersonation securityQoS.Sid = pLocalSystemSID; /// Security identifier used by Local RPC securityQoS.EffectiveOnly = TRUE; /// only see enabled privileges bindingHandleTemplate.Version = 1; /// Use BINDING_HANDLE_TEMPLATE_V1 structure bindingHandleTemplate.ProtocolSequence = pRPCData->protocolSequence; /// Use Local RPC bindingHandleTemplate.StringEndpoint = (PWSTR)g_pEndpoint; /// String representation of our endpoint bindingHandleSecurity.Version = 1; /// Use BINDING_HANDLE_SECURITY_V1 structure bindingHandleSecurity.AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY; /// Authentication level which causes Local RPC to use a secure channel bindingHandleSecurity.AuthnSvc = RPC_C_AUTHN_WINNT; /// Autherntication service to use bindingHandleSecurity.SecurityQos = (RPC_SECURITY_QOS*)&securityQoS; /// Security Qos Settings to Use bindingHandleOptions.Version = 1; /// Use BINDING_HANDLE_OPTIONS_V1 structure bindingHandleOptions.Flags = RPC_BHO_NONCAUSAL; /// Execute calls in any order bindingHandleOptions.ComTimeout = RPC_C_BINDING_DEFAULT_TIMEOUT; /// Use default communication timeout value status = RpcBindingCreate(&bindingHandleTemplate, /// Core structure of the binding handle &bindingHandleSecurity, /// Security options for the binding handle &bindingHandleOptions, /// Additional options to set on the binding handle &wfpSamplerBindingHandle); /// Created binding handle if(status != RPC_S_OK) { HlprLogError(L"RPCClientInterfaceInitialize : RpcBindingCreate() [status: %#x]", status); HLPR_BAIL; } pRPCData->bindingHandle = wfpSamplerBindingHandle; status = RpcBindingBind(0, /// These RPC calls will be synchronous pRPCData->bindingHandle, /// Binding handle that will be used to make the RPC call pRPCData->rpcClientInterfaceHandle); /// Interface handle that will be used to make the RPC call if(status != RPC_S_OK) { HlprLogError(L"RPCClientInterfaceInitialize : RpcBindingBind() [status: %#x]", status); HLPR_BAIL; } HLPR_BAIL_LABEL: if(status != RPC_S_OK) { HlprLogError(L"[status: %#x]", status); PrvRPCTroubleshootError(); RPCClientInterfaceTerminate(); } if(pLocalSystemSID) HlprSIDDestroy(&pLocalSystemSID); return status; }
UINT32 PrvScenarioAppContainerDeleteFwpmObjects(_In_ const SID* pPackageID, _In_ const SID* pUserID) { UNREFERENCED_PARAMETER(pUserID); ASSERT(pPackageID); ASSERT(pUserID); UINT32 status = NO_ERROR; /// UINT32 sidSize = 0; HANDLE engineHandle = 0; const GUID pLayerKeys[] = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, FWPM_LAYER_ALE_AUTH_CONNECT_V4, FWPM_LAYER_ALE_AUTH_CONNECT_V6}; const UINT8 NUM_CONDITIONS = 1; /// 2 const UINT8 NUM_OBJECTS = RTL_NUMBER_OF(pLayerKeys); FWPM_FILTER_CONDITION pFilterConditions[NUM_CONDITIONS] = {0}; pFilterConditions[0].fieldKey = FWPM_CONDITION_ALE_PACKAGE_ID; pFilterConditions[0].matchType = FWP_MATCH_EQUAL; pFilterConditions[0].conditionValue.type = FWP_SID; pFilterConditions[0].conditionValue.sid = (SID*)pPackageID; /// pFilterConditions[1].fieldKey = FWPM_CONDITION_ALE_USER_ID; /// pFilterConditions[1].matchType = FWP_MATCH_EQUAL; /// pFilterConditions[1].conditionValue.type = FWP_SECURITY_DESCRIPTOR_TYPE; /// pFilterConditions[1].conditionValue.sd = ; status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); for(UINT32 objectIndex = 0; objectIndex < NUM_OBJECTS; objectIndex++) { UINT32 entryCount = 0; FWPM_FILTER** ppFilters = 0; HANDLE enumHandle = 0; FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0}; filterEnumTemplate.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filterEnumTemplate.layerKey = pLayerKeys[objectIndex]; filterEnumTemplate.enumType = FWP_FILTER_ENUM_FULLY_CONTAINED; filterEnumTemplate.flags = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME | FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED; filterEnumTemplate.numFilterConditions = NUM_CONDITIONS; filterEnumTemplate.filterCondition = pFilterConditions; filterEnumTemplate.actionMask = 0xFFFFFFFF; status = HlprFwpmFilterCreateEnumHandle(engineHandle, &filterEnumTemplate, &enumHandle); HLPR_BAIL_ON_FAILURE_WITH_LABEL(status, HLPR_BAIL_LABEL_2); status = HlprFwpmFilterEnum(engineHandle, enumHandle, 0xFFFFFFFF, &ppFilters, &entryCount); HLPR_BAIL_ON_FAILURE_WITH_LABEL(status, HLPR_BAIL_LABEL_2); if(ppFilters) { for(UINT32 filterIndex = 0; filterIndex < entryCount; filterIndex++) { HlprFwpmFilterDeleteByKey(engineHandle, &(ppFilters[filterIndex]->filterKey)); } FwpmFreeMemory((void**)&ppFilters); } HLPR_BAIL_LABEL_2: if(enumHandle) HlprFwpmFilterDestroyEnumHandle(engineHandle, &enumHandle); } HLPR_BAIL_LABEL: HlprFwpmEngineClose(&engineHandle); return status; }
UINT32 PrvBasicPacketModificationScenarioAddFwpmObjects(_In_ const FWPM_FILTER* pFilter, _In_ const PC_BASIC_PACKET_MODIFICATION_DATA* pPCBasicPacketModificationData) { ASSERT(pFilter); ASSERT(pPCBasicPacketModificationData); UINT32 status = NO_ERROR; HANDLE engineHandle = 0; FWP_BYTE_BLOB byteBlob = {0}; FWPM_PROVIDER_CONTEXT providerContext = {0}; FWPM_CALLOUT callout = {0}; FWPM_FILTER filter = {0}; RtlCopyMemory(&filter, pFilter, sizeof(FWPM_FILTER)); status = HlprGUIDPopulate(&(providerContext.providerContextKey)); HLPR_BAIL_ON_FAILURE(status); providerContext.displayData.name = L"WFPSampler's Basic Packet Modification Provider Context"; providerContext.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; providerContext.type = FWPM_GENERAL_CONTEXT; providerContext.dataBuffer = &byteBlob; providerContext.dataBuffer->size = sizeof(PC_BASIC_PACKET_MODIFICATION_DATA); providerContext.dataBuffer->data = (UINT8*)pPCBasicPacketModificationData; callout.calloutKey = WFPSAMPLER_CALLOUT_BASIC_PACKET_MODIFICATION; callout.calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(filter.layerKey)); /// Uniquely identifies the callout used callout.displayData.name = L"WFPSampler's Basic Packet Modification Callout"; callout.displayData.description = L"Causes callout invocation which modifies the headers and injects traffic back"; callout.flags = FWPM_CALLOUT_FLAG_USES_PROVIDER_CONTEXT; callout.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; callout.applicableLayer = filter.layerKey; status = HlprGUIDPopulate(&(filter.filterKey)); HLPR_BAIL_ON_FAILURE(status); filter.flags |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT; filter.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filter.subLayerKey = WFPSAMPLER_SUBLAYER; filter.weight.type = FWP_UINT8; filter.weight.uint8 = 0xF; filter.action.type = FWP_ACTION_CALLOUT_UNKNOWN; filter.action.calloutKey = callout.calloutKey; filter.providerContextKey = providerContext.providerContextKey; if(filter.flags & FWPM_FILTER_FLAG_BOOTTIME || filter.flags & FWPM_FILTER_FLAG_PERSISTENT) { providerContext.flags |= FWPM_PROVIDER_CONTEXT_FLAG_PERSISTENT; callout.flags |= FWPM_CALLOUT_FLAG_PERSISTENT; } status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionBegin(engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmProviderContextAdd(engineHandle, &providerContext); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmCalloutAdd(engineHandle, &callout); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmFilterAdd(engineHandle, &filter); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionCommit(engineHandle); HLPR_BAIL_ON_FAILURE(status); HLPR_BAIL_LABEL: if(engineHandle) { if(status != NO_ERROR) HlprFwpmTransactionAbort(engineHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
UINT32 PrvScenarioAppContainerAddFwpmObjects(_In_ BOOLEAN persistent = TRUE, _In_ BOOLEAN bootTime = FALSE) { UINT32 status = NO_ERROR; UINT32 sidSize = 0; HANDLE engineHandle = 0; const GUID pLayerKeys[] = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, FWPM_LAYER_ALE_AUTH_CONNECT_V4, FWPM_LAYER_ALE_AUTH_CONNECT_V6}; const UINT32 NUM_OBJECTS = RTL_NUMBER_OF(pLayerKeys); FWPM_FILTER_CONDITION filterCondition = {0}; FWPM_FILTER pFilters[NUM_OBJECTS] = {0}; /// Only App Containers have a valid (non-NULL) SID for the ALE_PACKAGE_ID filterCondition.fieldKey = FWPM_CONDITION_ALE_PACKAGE_ID; filterCondition.matchType = FWP_MATCH_NOT_EQUAL; filterCondition.conditionValue.type = FWP_SID; #pragma warning(push) #pragma warning(disable: 6388) /// filterCondition.conditionValue.sid guaranteed to be 0 due to ZeroMemory call status = HlprSIDGetWellKnown(WinNullSid, &(filterCondition.conditionValue.sid), &sidSize); HLPR_BAIL_ON_FAILURE(status); #pragma warning(pop) for(UINT32 objectIndex = 0; objectIndex < NUM_OBJECTS; objectIndex++) { status = HlprGUIDPopulate(&(pFilters[objectIndex].filterKey)); HLPR_BAIL_ON_FAILURE(status); pFilters[objectIndex].displayData.name = L"WFPSampler's AppContainer Scenario Filter"; pFilters[objectIndex].displayData.description = L"Trust Windows Service Hardening to handle all App Containers"; pFilters[objectIndex].flags |= FWPM_FILTER_FLAG_PERSISTENT; pFilters[objectIndex].providerKey = (GUID*)&WFPSAMPLER_PROVIDER; pFilters[objectIndex].layerKey = pLayerKeys[objectIndex]; pFilters[objectIndex].subLayerKey = WFPSAMPLER_SUBLAYER; pFilters[objectIndex].weight.type = FWP_UINT8; pFilters[objectIndex].weight.uint8 = 0xF; pFilters[objectIndex].numFilterConditions = 1; pFilters[objectIndex].filterCondition = &filterCondition; pFilters[objectIndex].action.type = FWP_ACTION_PERMIT; if(!persistent) pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT; if(bootTime) { if(pFilters[objectIndex].flags & FWPM_FILTER_FLAG_PERSISTENT) pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT; pFilters[objectIndex].flags |= FWPM_FILTER_FLAG_BOOTTIME; } } status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionBegin(engineHandle); HLPR_BAIL_ON_FAILURE(status); for(UINT32 objectIndex = 0; objectIndex < NUM_OBJECTS; objectIndex++) { status = HlprFwpmFilterAdd(engineHandle, &(pFilters[objectIndex])); HLPR_BAIL_ON_FAILURE(status); } status = HlprFwpmTransactionCommit(engineHandle); HLPR_BAIL_ON_FAILURE(status); HLPR_BAIL_LABEL: HlprSIDDestroy(&(filterCondition.conditionValue.sid)); if(engineHandle) { if(status != NO_ERROR) HlprFwpmTransactionAbort(engineHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
UINT32 PrvScenarioAppContainerAddFwpmObjects(_In_ const SID* pPackageID, _In_ const SID* pUserID, _In_opt_ PCWSTR pDisplayName, _In_ BOOLEAN persistent = TRUE, _In_ BOOLEAN bootTime = FALSE) { UNREFERENCED_PARAMETER(pUserID); ASSERT(pPackageID); ASSERT(pUserID); UINT32 status = NO_ERROR; /// UINT32 sidSize = 0; HANDLE engineHandle = 0; const GUID pLayerKeys[] = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, FWPM_LAYER_ALE_AUTH_CONNECT_V4, FWPM_LAYER_ALE_AUTH_CONNECT_V6}; const UINT8 NUM_CONDITIONS = 1; /// 2 const UINT8 NUM_OBJECTS = RTL_NUMBER_OF(pLayerKeys); FWPM_FILTER_CONDITION pFilterConditions[NUM_CONDITIONS] = {0}; FWPM_FILTER pFilters[NUM_OBJECTS] = {0}; /// status = HlprSecurityDescriptorGetSelfRelativeForUser(); pFilterConditions[0].fieldKey = FWPM_CONDITION_ALE_PACKAGE_ID; pFilterConditions[0].matchType = FWP_MATCH_EQUAL; pFilterConditions[0].conditionValue.type = FWP_SID; pFilterConditions[0].conditionValue.sid = (SID*)pPackageID; /// pFilterConditions[1].fieldKey = FWPM_CONDITION_ALE_USER_ID; /// pFilterConditions[1].matchType = FWP_MATCH_EQUAL; /// pFilterConditions[1].conditionValue.type = FWP_SECURITY_DESCRIPTOR_TYPE; /// pFilterConditions[1].conditionValue.sd = ; for(UINT32 objectIndex = 0; objectIndex < NUM_OBJECTS; objectIndex++) { status = HlprGUIDPopulate(&(pFilters[objectIndex].filterKey)); HLPR_BAIL_ON_FAILURE(status); pFilters[objectIndex].displayData.name = L"WFPSampler's AppContainer Scenario Filter"; pFilters[objectIndex].displayData.description = (PWSTR)pDisplayName; pFilters[objectIndex].flags |= FWPM_FILTER_FLAG_PERSISTENT; pFilters[objectIndex].providerKey = (GUID*)&WFPSAMPLER_PROVIDER; pFilters[objectIndex].layerKey = pLayerKeys[objectIndex]; pFilters[objectIndex].subLayerKey = WFPSAMPLER_SUBLAYER; pFilters[objectIndex].weight.type = FWP_UINT8; pFilters[objectIndex].weight.uint8 = 0xF; pFilters[objectIndex].numFilterConditions = NUM_CONDITIONS; pFilters[objectIndex].filterCondition = pFilterConditions; pFilters[objectIndex].action.type = FWP_ACTION_PERMIT; if(!persistent) pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT; if(bootTime) { if(pFilters[objectIndex].flags & FWPM_FILTER_FLAG_PERSISTENT) pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT; pFilters[objectIndex].flags |= FWPM_FILTER_FLAG_BOOTTIME; } } status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); status = HlprFwpmTransactionBegin(engineHandle); HLPR_BAIL_ON_FAILURE(status); for(UINT32 objectIndex = 0; objectIndex < NUM_OBJECTS; objectIndex++) { status = HlprFwpmFilterAdd(engineHandle, &(pFilters[objectIndex])); HLPR_BAIL_ON_FAILURE(status); } status = HlprFwpmTransactionCommit(engineHandle); HLPR_BAIL_ON_FAILURE(status); HLPR_BAIL_LABEL: if(engineHandle) { if(status != NO_ERROR) HlprFwpmTransactionAbort(engineHandle); HlprFwpmEngineClose(&engineHandle); } return status; }
UINT32 PrvScenarioAppContainerDeleteFwpmObjects() { UINT32 status = NO_ERROR; UINT32 sidSize = 0; HANDLE engineHandle = 0; const GUID pLayerKeys[] = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, FWPM_LAYER_ALE_AUTH_CONNECT_V4, FWPM_LAYER_ALE_AUTH_CONNECT_V6}; const UINT32 NUM_OBJECTS = RTL_NUMBER_OF(pLayerKeys); FWPM_FILTER_CONDITION filterCondition = {0}; /// Only App Containers have a valid (non-NULL) SID for the ALE_PACKAGE_ID filterCondition.fieldKey = FWPM_CONDITION_ALE_PACKAGE_ID; filterCondition.matchType = FWP_MATCH_NOT_EQUAL; filterCondition.conditionValue.type = FWP_SID; #pragma warning(push) #pragma warning(disable: 6388) /// filterCondition.conditionValue.sid guaranteed to be 0 due to ZeroMemory call status = HlprSIDGetWellKnown(WinNullSid, &(filterCondition.conditionValue.sid), &sidSize); HLPR_BAIL_ON_FAILURE(status); #pragma warning(pop) status = HlprFwpmEngineOpen(&engineHandle); HLPR_BAIL_ON_FAILURE(status); for(UINT32 objectIndex = 0; objectIndex < NUM_OBJECTS; objectIndex++) { HANDLE enumHandle = 0; UINT32 entryCount = 0; FWPM_FILTER** ppFilters = 0; FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0}; filterEnumTemplate.providerKey = (GUID*)&WFPSAMPLER_PROVIDER; filterEnumTemplate.layerKey = pLayerKeys[objectIndex]; filterEnumTemplate.enumType = FWP_FILTER_ENUM_FULLY_CONTAINED; filterEnumTemplate.flags = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME | FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED; filterEnumTemplate.numFilterConditions = 1; filterEnumTemplate.filterCondition = &filterCondition; filterEnumTemplate.actionMask = 0xFFFFFFFF; status = HlprFwpmFilterCreateEnumHandle(engineHandle, &filterEnumTemplate, &enumHandle); HLPR_BAIL_ON_FAILURE_WITH_LABEL(status, HLPR_BAIL_LABEL_2); status = HlprFwpmFilterEnum(engineHandle, enumHandle, 0xFFFFFFFF, &ppFilters, &entryCount); HLPR_BAIL_ON_FAILURE_WITH_LABEL(status, HLPR_BAIL_LABEL_2); if(ppFilters) { for(UINT32 filterIndex = 0; filterIndex < entryCount; filterIndex++) { HlprFwpmFilterDeleteByKey(engineHandle, &(ppFilters[filterIndex]->filterKey)); } FwpmFreeMemory((void**)&ppFilters); } HLPR_BAIL_LABEL_2: if(enumHandle) HlprFwpmFilterDestroyEnumHandle(engineHandle, &enumHandle); } HLPR_BAIL_LABEL: HlprSIDDestroy(&(filterCondition.conditionValue.sid)); HlprFwpmEngineClose(&engineHandle); return status; }