WFP and IP headers

大憨熊 提交于 2020-08-09 11:04:46

WFP & IP headers

Hi there,

I've recently decided I should probably learn some driver development and for better or for worse I've started with WFP.
I figured that this would be a good place to start as (correct me if im wrong) it's a much simpler API to use than NDIS and
I've always wanted to learn more about the network side of things without being swamped in too much detail too soon.

Anyway, I've been having a go at redirecting ip packets into a different network adapter by altering the ipv4 header source ip.
I have the following set up:

An exe for calling the WFE and adding my callout
At layer: FWPM_LAYER_OUTBOUND_IPPACKET_V4
Filtering on : FWPM_CONDITION_IP_LOCAL_ADDRESS
An associated WFP callout driver
Using PnP and the clone drop reinject pattern
Creating a g_Injection handle using FwpsInjectionHandleCreate(AF_INET, FWPS_INJECTION_TYPE_NETWORK, &g_InjectionHandle);

The following snippet of code is my classifyFn callback.

void ProcessNetworkData(
_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_PARAMETERS*/

NET_BUFFER_LIST* clonedNetBufferList = NULL;
NTSTATUS status = STATUS_SUCCESS;

FWPS_PACKET_INJECTION_STATE packetState = FwpsQueryPacketInjectionState(g_InjectionHandle, layerData, NULL);
if (packetState == FWPS_PACKET_INJECTED_BY_SELF || packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)
classifyOut->actionType = FWP_ACTION_PERMIT;
else
{
if (classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
{
classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
classifyOut->rights ^= FWPS_RIGHT_ACTION_WRITE;

NET_BUFFER_LIST* netBufferList = (NET_BUFFER_LIST*)layerData;
status = FwpsAllocateCloneNetBufferList(netBufferList, NULL, NULL, 0, &clonedNetBufferList);
if (NT_SUCCESS(status))
{
for (NET_BUFFER* netBuffer = NET_BUFFER_LIST_FIRST_NB(clonedNetBufferList); netBuffer != NULL; netBuffer = NET_BUFFER_NEXT_NB(netBuffer))
{
IPV4_HEADER* ipHeader = NdisGetDataBuffer(netBuffer, sizeof(IPV4_HEADER), NULL, 1, 0);
ipHeader->SourceAddress.S_un.S_addr = 3044277929;
//ipHeader->DestinationAddress.S_un.S_addr = 1387265705;
}

status = FwpsInjectNetworkSendAsync(g_InjectionHandle, NULL, 0, inMetaValues->compartmentId, clonedNetBufferList, PacketInjectionComplete, NULL);
}
}
}

if (!NT_SUCCESS(status) && clonedNetBufferList != NULL)
FwpsFreeCloneNetBufferList(clonedNetBufferList, 0);
}

I've excluded the other calls for brevity. (EvtDriverUnload, DriverEntry, EvtDeviceAdd) I'm pretty sure they're not of interest here but can be provided if desired.

Why can I use the above code to successfully redirect a ping request (ICMP) down a different NIC (to a different destination if desired), but I can't redirect tcp(http) down a different NIC - they just timeout?
What I'm seeing is that reinjected packets for tcp(http) never appear in the classifyFn callback again (and hence never hit classifyOut->actionType = FWP_ACTION_PERMIT)
I would have thought that altering the source address of all ip packets would have sent all network traffic down the second NIC?

I think this can be achieved with ALE_BIND_REDIRECT but I'm more interest in why my example is not working?

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!