Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <initguid.h>
- #include <ntddk.h>
- #define NDIS620
- #include <ndis.h>
- #include <fwpsk.h>
- #include <fwpmk.h>
- #include <ip2string.h>
- #include <mstcpip.h>
- #define WPP_CONTROL_GUIDS \
- WPP_DEFINE_CONTROL_GUID(Default, (81C29CFA,1DD4,4177,9B97,8A361B74B246), \
- WPP_DEFINE_BIT(Default) \
- )
- #include "main.tmh"
- #define DNS_PORT 53
- // DNS host the client wants to connect to
- #define DNS_HOST_ORIGINAL 0x0292A8C0 // 192.168.146.2
- // DNS host the client is redirected to
- #define DNS_HOST_REDIRECT 0x08080808 // 8.8.8.8
- #pragma pack(push, 1)
- typedef struct _IPV4_HEADER
- {
- UINT8 VersionAndHeaderLength;
- UINT8 TypeOfService;
- UINT16 TotalLength;
- UINT16 Identification;
- UINT16 FlagsAndFragmentOffset;
- UINT8 TimeToLive;
- UINT8 Protocol;
- UINT16 Checksum;
- UINT32 SourceAddress;
- UINT32 DestinationAddress;
- } IPV4_HEADER, *PIPV4_HEADER;
- #pragma pack(pop)
- HANDLE g_InjectionHandle = NULL;
- HANDLE g_EngineHandle = NULL;
- GUID g_SessionKey = { 0 };
- GUID g_ProviderKey = { 0 };
- GUID g_SubLayerKey = { 0 };
- GUID g_ConnectRedirectCalloutKey = { 0 };
- GUID g_ConnectRedirectFilterKey = { 0 };
- GUID g_DatagramDataCalloutKey = { 0 };
- GUID g_DatagramDataFilterKey = { 0 };
- DRIVER_INITIALIZE DriverEntry;
- DRIVER_UNLOAD DriverUnload;
- void NTAPI DriverConnectRedirectClassify(
- _In_ const FWPS_INCOMING_VALUES* inFixedValues,
- _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
- _Inout_opt_ void* layerData,
- _In_opt_ const void* classifyContext,
- _In_ const FWPS_FILTER* filter,
- _In_ UINT64 flowContext,
- _Inout_ FWPS_CLASSIFY_OUT* classifyOut
- );
- void NTAPI DriverDatagramDataClassify(
- _In_ const FWPS_INCOMING_VALUES* inFixedValues,
- _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
- _Inout_opt_ void* layerData,
- _In_opt_ const void* classifyContext,
- _In_ const FWPS_FILTER* filter,
- _In_ UINT64 flowContext,
- _Inout_ FWPS_CLASSIFY_OUT* classifyOut
- );
- NTSTATUS NTAPI DriverNotify(
- _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType,
- _In_ const GUID* filterKey,
- _Inout_ FWPS_FILTER* filter
- );
- NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
- {
- WPP_INIT_TRACING(DriverObject, RegistryPath);
- DoTraceMessage(Default, "DriverEntry() enter");
- DriverObject->DriverUnload = DriverUnload;
- ExUuidCreate(&g_SessionKey);
- ExUuidCreate(&g_ProviderKey);
- ExUuidCreate(&g_SubLayerKey);
- ExUuidCreate(&g_ConnectRedirectCalloutKey);
- ExUuidCreate(&g_DatagramDataCalloutKey);
- ExUuidCreate(&g_ConnectRedirectFilterKey);
- ExUuidCreate(&g_DatagramDataFilterKey);
- {
- NTSTATUS Status = FwpsInjectionHandleCreate(AF_INET, FWPS_INJECTION_TYPE_TRANSPORT, &g_InjectionHandle);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsInjectionHandleCreate() Status=%!STATUS!", Status);
- }
- FWPS_CALLOUT Callout;
- RtlZeroMemory(&Callout, sizeof(Callout));
- Callout.calloutKey = g_ConnectRedirectCalloutKey;
- Callout.classifyFn = DriverConnectRedirectClassify;
- Callout.notifyFn = DriverNotify;
- UINT32 CalloutId = 0;
- Status = FwpsCalloutRegister(DriverObject, &Callout, &CalloutId);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsCalloutRegister(ConnectRedirect) Status=%!STATUS!", Status);
- }
- Callout.calloutKey = g_DatagramDataCalloutKey;
- Callout.classifyFn = DriverDatagramDataClassify;
- CalloutId = 0;
- Status = FwpsCalloutRegister(DriverObject, &Callout, &CalloutId);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsCalloutRegister(DatagramData) Status=%!STATUS!", Status);
- }
- }
- {
- FWPM_SESSION Session;
- RtlZeroMemory(&Session, sizeof(Session));
- Session.sessionKey = g_SessionKey;
- Session.displayData.name = L"WfpDnsRedirect Session";
- Session.flags = FWPM_SESSION_FLAG_DYNAMIC;
- NTSTATUS Status = FwpmEngineOpen(NULL, RPC_C_AUTHN_DEFAULT, NULL, &Session, &g_EngineHandle);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmEngineOpen() Status=%!STATUS!", Status);
- }
- Status = FwpmTransactionBegin(g_EngineHandle, 0);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmTransactionBegin() Status=%!STATUS!", Status);
- }
- FWPM_PROVIDER Provider;
- RtlZeroMemory(&Provider, sizeof(Provider));
- Provider.providerKey = g_ProviderKey;
- Provider.displayData.name = L"WfpDnsRedirect Provider";
- Status = FwpmProviderAdd(g_EngineHandle, &Provider, NULL);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmProviderAdd() Status=%!STATUS!", Status);
- }
- FWPM_SUBLAYER SubLayer;
- RtlZeroMemory(&SubLayer, sizeof(SubLayer));
- SubLayer.subLayerKey = g_SubLayerKey;
- SubLayer.displayData.name = L"WfpDnsRedirect SubLayer";
- SubLayer.providerKey = &g_ProviderKey;
- SubLayer.weight = MAXUINT16;
- Status = FwpmSubLayerAdd(g_EngineHandle, &SubLayer, NULL);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmSubLayerAdd() Status=%!STATUS!", Status);
- }
- FWPM_CALLOUT Callout;
- RtlZeroMemory(&Callout, sizeof(Callout));
- Callout.calloutKey = g_ConnectRedirectCalloutKey;
- Callout.displayData.name = L"WfpDnsRedirect Connect Redirect Callout";
- Callout.providerKey = &g_ProviderKey;
- Callout.applicableLayer = FWPM_LAYER_ALE_CONNECT_REDIRECT_V4;
- UINT32 CalloutId = 0;
- Status = FwpmCalloutAdd(g_EngineHandle, &Callout, NULL, &CalloutId);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmCalloutAdd(ConnectRedirect) Status=%!STATUS!", Status);
- }
- Callout.calloutKey = g_DatagramDataCalloutKey;
- Callout.displayData.name = L"WfpDnsRedirect Datagram Data Callout";
- Callout.applicableLayer = FWPM_LAYER_DATAGRAM_DATA_V4;
- CalloutId = 0;
- Status = FwpmCalloutAdd(g_EngineHandle, &Callout, NULL, &CalloutId);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmCalloutAdd(DatagramData) Status=%!STATUS!", Status);
- }
- UINT64 FilterWeight = MAXUINT64;
- FWPM_FILTER Filter;
- RtlZeroMemory(&Filter, sizeof(Filter));
- Filter.filterKey = g_ConnectRedirectFilterKey;
- Filter.displayData.name = L"WfpDnsRedirect Connect Redirect Filter";
- Filter.providerKey = &g_ProviderKey;
- Filter.layerKey = FWPM_LAYER_ALE_CONNECT_REDIRECT_V4;
- Filter.subLayerKey = g_SubLayerKey;
- Filter.weight.type = FWP_UINT64;
- Filter.weight.uint64 = &FilterWeight;
- Filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
- Filter.action.calloutKey = g_ConnectRedirectCalloutKey;
- UINT64 FilterId = 0;
- Status = FwpmFilterAdd(g_EngineHandle, &Filter, NULL, &FilterId);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmFilterAdd(ConnectRedirect) Status=%!STATUS!", Status);
- }
- Filter.filterKey = g_DatagramDataFilterKey;
- Filter.displayData.name = L"WfpDnsRedirect Datagram Data Filter";
- Filter.layerKey = FWPM_LAYER_DATAGRAM_DATA_V4;
- Filter.action.calloutKey = g_DatagramDataCalloutKey;
- FilterId = 0;
- Status = FwpmFilterAdd(g_EngineHandle, &Filter, NULL, &FilterId);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmFilterAdd(DatagramData) Status=%!STATUS!", Status);
- }
- Status = FwpmTransactionCommit(g_EngineHandle);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmTransactionCommit() Status=%!STATUS!", Status);
- }
- }
- DoTraceMessage(Default, "DriverEntry() exit");
- return STATUS_SUCCESS;
- }
- VOID DriverUnload(PDRIVER_OBJECT DriverObject)
- {
- DoTraceMessage(Default, "DriverUnload enter");
- {
- NTSTATUS Status = FwpmTransactionBegin(g_EngineHandle, 0);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmTransactionBegin() Status=%!STATUS!", Status);
- }
- Status = FwpmFilterDeleteByKey(g_EngineHandle, &g_DatagramDataFilterKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmFilterDeleteByKey(DatagramData) Status=%!STATUS!", Status);
- }
- Status = FwpmFilterDeleteByKey(g_EngineHandle, &g_ConnectRedirectFilterKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmFilterDeleteByKey(ConnectRedirect) Status=%!STATUS!", Status);
- }
- Status = FwpmCalloutDeleteByKey(g_EngineHandle, &g_DatagramDataCalloutKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmCalloutDeleteByKey(DatagramData) Status=%!STATUS!", Status);
- }
- Status = FwpmCalloutDeleteByKey(g_EngineHandle, &g_ConnectRedirectCalloutKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmCalloutDeleteByKey(ConnectRedirect) Status=%!STATUS!", Status);
- }
- Status = FwpmSubLayerDeleteByKey(g_EngineHandle, &g_SubLayerKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmSubLayerDeleteByKey() Status=%!STATUS!", Status);
- }
- Status = FwpmProviderDeleteByKey(g_EngineHandle, &g_ProviderKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmProviderDeleteByKey() Status=%!STATUS!", Status);
- }
- Status = FwpmTransactionCommit(g_EngineHandle);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpmTransactionCommit() Status=%!STATUS!", Status);
- }
- Status = FwpmEngineClose(g_EngineHandle);
- g_EngineHandle = NULL;
- }
- {
- NTSTATUS Status = FwpsCalloutUnregisterByKey(&g_DatagramDataCalloutKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsCalloutUnregisterByKey(DatagramData) Status=%!STATUS!", Status);
- }
- Status = FwpsCalloutUnregisterByKey(&g_ConnectRedirectCalloutKey);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsCalloutUnregisterByKey(ConnectRedirect) Status=%!STATUS!", Status);
- }
- Status = FwpsInjectionHandleDestroy(g_InjectionHandle);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsInjectionHandleDestroy() Status=%!STATUS!", Status);
- }
- }
- DoTraceMessage(Default, "DriverUnload exit");
- WPP_CLEANUP(DriverObject);
- }
- NTSTATUS NTAPI DriverNotify(
- _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType,
- _In_ const GUID* filterKey,
- _Inout_ FWPS_FILTER* filter
- )
- {
- UNREFERENCED_PARAMETER(notifyType);
- UNREFERENCED_PARAMETER(filterKey);
- UNREFERENCED_PARAMETER(filter);
- return STATUS_SUCCESS;
- }
- void NTAPI DriverConnectRedirectClassify(
- _In_ const FWPS_INCOMING_VALUES* inFixedValues,
- _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
- _Inout_opt_ void* layerData,
- _In_opt_ const void* classifyContext,
- _In_ const FWPS_FILTER* filter,
- _In_ UINT64 flowContext,
- _Inout_ FWPS_CLASSIFY_OUT* classifyOut
- )
- {
- UNREFERENCED_PARAMETER(inMetaValues);
- UNREFERENCED_PARAMETER(layerData);
- UNREFERENCED_PARAMETER(flowContext);
- UINT32 RemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_REMOTE_ADDRESS].value.uint32;
- UINT16 RemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_REMOTE_PORT].value.uint16;
- classifyOut->actionType = FWP_ACTION_PERMIT;
- classifyOut->rights |= FWPS_RIGHT_ACTION_WRITE;
- if ((RemotePort == DNS_PORT) && (RemoteAddress != DNS_HOST_REDIRECT))
- {
- UINT64 ClassifyHandle = 0;
- NTSTATUS Status = FwpsAcquireClassifyHandle((void*)classifyContext, 0, &ClassifyHandle);
- if (NT_SUCCESS(Status))
- {
- FWPS_CONNECT_REQUEST* ConnectRequest = NULL;
- Status = FwpsAcquireWritableLayerDataPointer(ClassifyHandle, filter->filterId, 0, &ConnectRequest, classifyOut);
- if (NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "Redirect DNS request");
- IN_ADDR RedirectAddress;
- RedirectAddress.s_addr = DNS_HOST_REDIRECT;
- INETADDR_SET_ADDRESS((SOCKADDR*)&ConnectRequest->remoteAddressAndPort, (const UCHAR*)&RedirectAddress);
- FwpsApplyModifiedLayerData(ClassifyHandle, ConnectRequest, 0);
- classifyOut->actionType = FWP_ACTION_PERMIT;
- classifyOut->rights |= FWPS_RIGHT_ACTION_WRITE;
- }
- else
- {
- DoTraceMessage(Default, "FwpsAcquireWritableLayerDataPointer() Status=%!STATUS!", Status);
- }
- FwpsReleaseClassifyHandle(ClassifyHandle);
- ClassifyHandle = 0;
- }
- else
- {
- DoTraceMessage(Default, "FwpsAcquireClassifyHandle() Status=%!STATUS!", Status);
- }
- }
- }
- void UpdateIpv4HeaderChecksum(PIPV4_HEADER IpHeader, UINT32 IpHeaderSize)
- {
- UINT32 Checksum = 0;
- UINT32 WordCount = IpHeaderSize / sizeof(UINT16);
- UINT16* Header = (UINT16*)IpHeader;
- IpHeader->Checksum = 0;
- for (UINT8 WordIndex = 0; WordIndex < WordCount; WordIndex++)
- {
- Checksum += Header[WordIndex];
- }
- Checksum = (Checksum & 0x0000ffff) + (Checksum >> 16);
- Checksum += (Checksum >> 16);
- IpHeader->Checksum = (UINT16)~Checksum;
- }
- void NTAPI DriverDatagramDataInjectComplete(
- _In_ void* context,
- _Inout_ NET_BUFFER_LIST* netBufferList,
- _In_ BOOLEAN dispatchLevel
- )
- {
- UNREFERENCED_PARAMETER(context);
- UNREFERENCED_PARAMETER(dispatchLevel);
- if (!NT_SUCCESS(netBufferList->Status))
- {
- DoTraceMessage(Default, "DriverDatagramDataInjectComplete() Status=%!STATUS!", netBufferList->Status);
- }
- FwpsFreeCloneNetBufferList(netBufferList, 0);
- }
- void NTAPI DriverDatagramDataClassify(
- _In_ const FWPS_INCOMING_VALUES* inFixedValues,
- _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
- _Inout_opt_ void* layerData,
- _In_opt_ const void* classifyContext,
- _In_ const FWPS_FILTER* filter,
- _In_ UINT64 flowContext,
- _Inout_ FWPS_CLASSIFY_OUT* classifyOut
- )
- {
- UNREFERENCED_PARAMETER(layerData);
- UNREFERENCED_PARAMETER(classifyContext);
- UNREFERENCED_PARAMETER(filter);
- UNREFERENCED_PARAMETER(flowContext);
- UINT32 RemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_ADDRESS].value.uint32;
- UINT16 RemotePort = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_PORT].value.uint16;
- IF_INDEX InterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_INTERFACE_INDEX].value.uint32;
- IF_INDEX SubInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_SUB_INTERFACE_INDEX].value.uint32;
- FWP_DIRECTION Direction = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_DIRECTION].value.uint32;
- FWPS_PACKET_INJECTION_STATE PacketInjectionState = FwpsQueryPacketInjectionState(g_InjectionHandle, layerData, NULL);
- classifyOut->actionType = FWP_ACTION_PERMIT;
- classifyOut->rights |= FWPS_RIGHT_ACTION_WRITE;
- if ((Direction == FWP_DIRECTION_INBOUND) && (PacketInjectionState == FWPS_PACKET_NOT_INJECTED) && (RemotePort == DNS_PORT) && (RemoteAddress == DNS_HOST_REDIRECT))
- {
- UINT32 IpHeaderSize = inMetaValues->ipHeaderSize;
- UINT32 TransportHeaderSize = inMetaValues->transportHeaderSize;
- PNET_BUFFER NetBuffer = NET_BUFFER_LIST_FIRST_NB((PNET_BUFFER_LIST)layerData);
- NdisRetreatNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, 0, NULL);
- PNET_BUFFER_LIST NetBufferList = NULL;
- NTSTATUS Status = FwpsAllocateCloneNetBufferList(layerData, NULL, NULL, 0, &NetBufferList);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsAllocateCloneNetBufferList() Status=%!STATUS!", Status);
- }
- NdisAdvanceNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, FALSE, NULL);
- if (!NetBufferList)
- {
- return;
- }
- DoTraceMessage(Default, "Modify DNS response");
- NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
- PIPV4_HEADER IpHeader = NdisGetDataBuffer(NetBuffer, sizeof(IPV4_HEADER), NULL, 1, 0);
- IpHeader->SourceAddress = DNS_HOST_ORIGINAL;
- UpdateIpv4HeaderChecksum(IpHeader, sizeof(IPV4_HEADER));
- Status = FwpsInjectTransportReceiveAsync(g_InjectionHandle, NULL, NULL, 0, AF_INET, inMetaValues->compartmentId, InterfaceIndex, SubInterfaceIndex, NetBufferList, DriverDatagramDataInjectComplete, NULL);
- if (!NT_SUCCESS(Status))
- {
- DoTraceMessage(Default, "FwpsInjectTransportReceiveAsync() Status=%!STATUS!", Status);
- FwpsFreeCloneNetBufferList(NetBufferList, 0);
- }
- classifyOut->actionType = FWP_ACTION_BLOCK;
- classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
- classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement