Add permit filters in DNS sublayer

This commit is contained in:
Odd Stranne
2021-12-03 09:37:44 +01:00
parent 090df512d6
commit e01ad18687
3 changed files with 169 additions and 26 deletions

View File

@@ -8,4 +8,6 @@ namespace
static const UINT64 ST_MAX_FILTER_WEIGHT = MAXUINT64;
static const UINT64 ST_HIGH_FILTER_WEIGHT = MAXUINT64 - 10;
static const UINT16 DNS_SERVER_PORT = 53;
} // anonymous namespace

View File

@@ -3,6 +3,8 @@
#include "constants.h"
#include "filters.h"
#define SUCCEED_OR_RETURN(status) if(!NT_SUCCESS(status)){ return status; }
namespace firewall
{
@@ -258,7 +260,7 @@ RegisterFilterPermitNonTunnelIpv4Tx
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV4_CONN_KEY;
filter.providerContextKey = ST_FW_PROVIDER_CONTEXT_KEY;
FWPM_FILTER_CONDITION0 cond;
FWPM_FILTER_CONDITION0 cond = { 0 };
//
// If there's no tunnel IPv4 interface then traffic on all interfaces
@@ -276,12 +278,10 @@ RegisterFilterPermitNonTunnelIpv4Tx
filter.numFilterConditions = 1;
}
auto status = FwpmFilterAdd0(WfpSession, &filter, NULL, NULL);
if (!NT_SUCCESS(status))
{
return status;
}
SUCCEED_OR_RETURN
(
FwpmFilterAdd0(WfpSession, &filter, NULL, NULL)
);
//
// Ipv4 inbound.
@@ -291,6 +291,59 @@ RegisterFilterPermitNonTunnelIpv4Tx
filter.layerKey = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV4_RECV_KEY;
SUCCEED_OR_RETURN
(
FwpmFilterAdd0(WfpSession, &filter, NULL, NULL)
);
//
// Create corresponding filters in the DNS sublayer.
// By convention, these filters should include a condition on the destination port.
//
// I.e. we'll be using 1 or 2 conditions.
//
FWPM_FILTER_CONDITION0 dnscond[2] = { 0, 0 };
dnscond[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
dnscond[0].matchType = FWP_MATCH_EQUAL;
dnscond[0].conditionValue.type = FWP_UINT16;
dnscond[0].conditionValue.uint16 = DNS_SERVER_PORT;
filter.filterCondition = dnscond;
if (TunnelIpv4 != NULL)
{
dnscond[1] = cond;
filter.numFilterConditions = 2;
}
else
{
filter.numFilterConditions = 1;
}
//
// Ipv4 outbound DNS.
//
filter.filterKey = ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_DNS_CONN_KEY;
filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
filter.subLayerKey = ST_FW_WINFW_DNS_SUBLAYER_KEY;
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV4_CONN_KEY;
SUCCEED_OR_RETURN
(
FwpmFilterAdd0(WfpSession, &filter, NULL, NULL)
);
//
// Ipv4 inbound DNS.
//
filter.filterKey = ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_DNS_RECV_KEY;
filter.layerKey = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV4_RECV_KEY;
return FwpmFilterAdd0(WfpSession, &filter, NULL, NULL);
}
@@ -300,14 +353,22 @@ RemoveFilterPermitNonTunnelIpv4Tx
HANDLE WfpSession
)
{
auto status = FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_CONN_KEY);
SUCCEED_OR_RETURN
(
FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_CONN_KEY)
);
if (!NT_SUCCESS(status))
{
return status;
}
SUCCEED_OR_RETURN
(
FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_RECV_KEY)
);
return FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_RECV_KEY);
SUCCEED_OR_RETURN
(
FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_DNS_CONN_KEY)
);
return FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_DNS_RECV_KEY);
}
NTSTATUS
@@ -339,7 +400,7 @@ RegisterFilterPermitNonTunnelIpv6Tx
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV6_CONN_KEY;
filter.providerContextKey = ST_FW_PROVIDER_CONTEXT_KEY;
FWPM_FILTER_CONDITION0 cond;
FWPM_FILTER_CONDITION0 cond = { 0 };
//
// If there's no tunnel IPv6 interface then traffic on all interfaces
@@ -357,12 +418,10 @@ RegisterFilterPermitNonTunnelIpv6Tx
filter.numFilterConditions = 1;
}
auto status = FwpmFilterAdd0(WfpSession, &filter, NULL, NULL);
if (!NT_SUCCESS(status))
{
return status;
}
SUCCEED_OR_RETURN
(
FwpmFilterAdd0(WfpSession, &filter, NULL, NULL)
);
//
// IPv6 inbound.
@@ -372,6 +431,56 @@ RegisterFilterPermitNonTunnelIpv6Tx
filter.layerKey = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV6_RECV_KEY;
SUCCEED_OR_RETURN
(
FwpmFilterAdd0(WfpSession, &filter, NULL, NULL)
);
//
// Create corresponding filters in the DNS sublayer.
//
FWPM_FILTER_CONDITION0 dnscond[2] = { 0, 0 };
dnscond[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
dnscond[0].matchType = FWP_MATCH_EQUAL;
dnscond[0].conditionValue.type = FWP_UINT16;
dnscond[0].conditionValue.uint16 = DNS_SERVER_PORT;
filter.filterCondition = dnscond;
if (TunnelIpv6 != NULL)
{
dnscond[1] = cond;
filter.numFilterConditions = 2;
}
else
{
filter.numFilterConditions = 1;
}
//
// Ipv6 outbound DNS.
//
filter.filterKey = ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_DNS_CONN_KEY;
filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
filter.subLayerKey = ST_FW_WINFW_DNS_SUBLAYER_KEY;
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV6_CONN_KEY;
SUCCEED_OR_RETURN
(
FwpmFilterAdd0(WfpSession, &filter, NULL, NULL)
);
//
// Ipv6 inbound DNS.
//
filter.filterKey = ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_DNS_RECV_KEY;
filter.layerKey = FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
filter.action.calloutKey = ST_FW_CALLOUT_PERMIT_SPLIT_APPS_IPV6_RECV_KEY;
return FwpmFilterAdd0(WfpSession, &filter, NULL, NULL);
}
@@ -381,14 +490,22 @@ RemoveFilterPermitNonTunnelIpv6Tx
HANDLE WfpSession
)
{
auto status = FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_CONN_KEY);
SUCCEED_OR_RETURN
(
FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_CONN_KEY)
);
if (!NT_SUCCESS(status))
{
return status;
}
SUCCEED_OR_RETURN
(
FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_RECV_KEY)
);
return FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_RECV_KEY);
SUCCEED_OR_RETURN
(
FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_DNS_CONN_KEY)
);
return FwpmFilterDeleteByKey0(WfpSession, &ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_DNS_RECV_KEY);
}
NTSTATUS

View File

@@ -92,6 +92,22 @@ DEFINE_GUID(ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_CONN_KEY,
DEFINE_GUID(ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_RECV_KEY,
0x7835dfd7, 0x24ae, 0x44f4, 0x8a, 0x8a, 0x5e, 0x9c, 0x76, 0x6a, 0xae, 0x63);
// {EDB743A8-1A77-4BA9-906B-C594A7DDB75B}
DEFINE_GUID(ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_DNS_CONN_KEY,
0xedb743a8, 0x1a77, 0x4ba9, 0x90, 0x6b, 0xc5, 0x94, 0xa7, 0xdd, 0xb7, 0x5b);
// {5373BF17-937E-438B-A307-CD50E125DFF9}
DEFINE_GUID(ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV4_DNS_RECV_KEY,
0x5373bf17, 0x937e, 0x438b, 0xa3, 0x7, 0xcd, 0x50, 0xe1, 0x25, 0xdf, 0xf9);
// {355F9524-8CE0-4C85-902F-EDF0252556D4}
DEFINE_GUID(ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_DNS_CONN_KEY,
0x355f9524, 0x8ce0, 0x4c85, 0x90, 0x2f, 0xed, 0xf0, 0x25, 0x25, 0x56, 0xd4);
// {282B9C48-4029-4D27-8FE0-8C3C4B84F952}
DEFINE_GUID(ST_FW_FILTER_PERMIT_SPLIT_APPS_IPV6_DNS_RECV_KEY,
0x282b9c48, 0x4029, 0x4d27, 0x8f, 0xe0, 0x8c, 0x3c, 0x4b, 0x84, 0xf9, 0x52);
// {D8602FF5-436B-414A-A221-7B4DE8CE96C7}
DEFINE_GUID(ST_FW_FILTER_BLOCK_ALL_SPLIT_APPS_TUNNEL_IPV4_CONN_KEY,
0xd8602ff5, 0x436b, 0x414a, 0xa2, 0x21, 0x7b, 0x4d, 0xe8, 0xce, 0x96, 0xc7);
@@ -116,6 +132,14 @@ DEFINE_GUID(ST_FW_FILTER_BLOCK_ALL_SPLIT_APPS_TUNNEL_IPV6_RECV_KEY,
DEFINE_GUID(ST_FW_WINFW_BASELINE_SUBLAYER_KEY,
0xc78056ff, 0x2bc1, 0x4211, 0xaa, 0xdd, 0x7f, 0x35, 0x8d, 0xef, 0x20, 0x2d);
//
// This sublayer is defined and registered by `winfw`.
// It's used to restrict traffic with destination port 53 (DNS).
// We need to install a filter there to make exceptions for excluded processes.
//
DEFINE_GUID(ST_FW_WINFW_DNS_SUBLAYER_KEY,
0x60090787, 0xcca1, 0x4937, 0xaa, 0xce, 0x51, 0x25, 0x6e, 0xf4, 0x81, 0xf3);
// {FDC95593-04EF-415C-AE68-46BD8B4821A8}
DEFINE_GUID(ST_FW_PROVIDER_CONTEXT_KEY,
0xfdc95593, 0x4ef, 0x415c, 0xae, 0x68, 0x46, 0xbd, 0x8b, 0x48, 0x21, 0xa8);