我正在编写一个使用 WSAIoctl/WSARecv 的 C++ 应用程序,传递 SIO_RCVALL 标志以混杂拦截所有流量,然后有状态地阻止不符合特定条件的流量。
出于本示例的目的,应将流量视为任意端口(例如 5000)上的 UDP 流量。所需的行为是保持监视功能,同时从其他应用程序的角度丢弃流量。
我试过以下方法:
SIO_RCVALL匹配规则?
fwpFilter.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;
fwpFilter.flags = FWPM_FILTER_FLAG_CLEAR_ACTION_RIGHT;
fwpFilter.action.type = FWP_ACTION_PERMIT;
fwpFilter.subLayerKey = GetSublayerKey();
fwpFilter.weight.type = FWP_UINT8;
fwpFilter.weight.uint8 = 0xF; // High weight
fwpFilter.numFilterConditions = 1;
fwpFilter.filterCondition = fwpFilterConditions;
fwpFilter.displayData.name = const_cast<wchar_t*>(L"Allow Promiscuous");
fwpFilter.displayData.description = const_cast<wchar_t*>(L"Support all traffic capture.");
fwpFilter.flags = FWPM_FILTER_FLAG_CLEAR_ACTION_RIGHT; // Prevent BLOCK by other rules/layers?
fwpFilterConditions[0].fieldKey = FWPM_CONDITION_FLAGS;
fwpFilterConditions[0].matchType = FWP_MATCH_FLAGS_ALL_SET;
fwpFilterConditions[0].conditionValue.type = FWP_UINT32;
fwpFilterConditions[0].conditionValue.uint32 = FWP_CONDITION_FLAG_IS_RAW_ENDPOINT; // Match to raw socket with no further conditions
交通特定规则:
fwpFilter.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;
fwpFilter.action.type = FWP_ACTION_BLOCK;
fwpFilter.subLayerKey = GetSublayerKey();
fwpFilter.weight.type = FWP_UINT8; // Medium Weight
fwpFilter.weight.uint8 = 0xA;
fwpFilter.numFilterConditions = 3;
fwpFilter.filterCondition = fwpFilterConditions;
fwpFilter.displayData.name = const_cast<wchar_t*>(L"Block specific");
fwpFilter.displayData.description = const_cast<wchar_t*>(L"Port/IP specific block.");
fwpFilterConditions[0].fieldKey = FWPM_CONDITION_FLAGS;
fwpFilterConditions[0].matchType = FWP_MATCH_FLAGS_NONE_SET;
fwpFilterConditions[0].conditionValue.type = FWP_UINT32;
fwpFilterConditions[0].conditionValue.uint32 = FWP_CONDITION_FLAG_IS_RAW_ENDPOINT;
fwpFilterConditions[1].fieldKey = FWPM_CONDITION_IP_LOCAL_PORT;
fwpFilterConditions[1].matchType = FWP_MATCH_EQUAL;
fwpFilterConditions[1].conditionValue.type = FWP_UINT16;
fwpFilterConditions[1].conditionValue.uint16 = sourcePort;
fwpFilterConditions[2].fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS;
fwpFilterConditions[2].matchType = FWP_MATCH_EQUAL;
fwpFilterConditions[2].conditionValue.type = FWP_UINT32;
fwpFilterConditions[2].conditionValue.uint32 = sourceIP;
然后可以观察到一些奇怪的行为:一旦规则到位,流量将被 all 应用程序阻止,而应用程序被绑定到本地端口。解除绑定后,应用程序会按预期使用 SIO_RCVALL 捕获流量。
澄清一下,我知道这是使用标注的一种效率较低且不灵活的方法,但我试图尽可能避免使用标注驱动程序如果可能。如果这完全不是一个选择,我将不得不探索那条路线,但我想在进入那个兔子洞之前我会进行理智检查。