Skip to content

Commit

Permalink
added delete method
Browse files Browse the repository at this point in the history
  • Loading branch information
sagiesec committed Dec 16, 2024
1 parent ad8689f commit 10bc800
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 2 deletions.
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,47 @@
.vscode/launch.json
wtf-debug.ps1
native/x64/Debug/vc143.idb
native/x64/Debug/vc143.pdb
native/x64/Debug/wfp.Build.CppClean.log
native/x64/Debug/wfp.exe
native/x64/Debug/wfp.exe.recipe
native/x64/Debug/wfp.ilk
native/x64/Debug/wfp.log
native/x64/Debug/wfp.obj
native/x64/Debug/wfp.pdb
native/x64/Debug/wfp.vcxproj.FileListAbsolute.txt
native/x64/Debug/wfp.tlog/CL.command.1.tlog
native/x64/Debug/wfp.tlog/Cl.items.tlog
native/x64/Debug/wfp.tlog/CL.read.1.tlog
native/x64/Debug/wfp.tlog/CL.write.1.tlog
native/x64/Debug/wfp.tlog/link.command.1.tlog
native/x64/Debug/wfp.tlog/link.read.1.tlog
native/x64/Debug/wfp.tlog/link.write.1.tlog
native/x64/Debug/wfp.tlog/wfp.lastbuildstate
native/x64/Release/vc143.pdb
native/x64/Release/wfp.Build.CppClean.log
native/x64/Release/wfp.exe
native/x64/Release/wfp.exe.recipe
native/x64/Release/wfp.iobj
native/x64/Release/wfp.ipdb
native/x64/Release/wfp.log
native/x64/Release/wfp.obj
native/x64/Release/wfp.pdb
native/x64/Release/wfp.vcxproj.FileListAbsolute.txt
native/x64/Release/wfp.tlog/CL.command.1.tlog
native/x64/Release/wfp.tlog/Cl.items.tlog
native/x64/Release/wfp.tlog/CL.read.1.tlog
native/x64/Release/wfp.tlog/CL.write.1.tlog
native/x64/Release/wfp.tlog/link.command.1.tlog
native/x64/Release/wfp.tlog/link.read.1.tlog
native/x64/Release/wfp.tlog/link.write.1.tlog
native/x64/Release/wfp.tlog/link.write.2u.tlog
native/x64/Release/wfp.tlog/wfp.lastbuildstate
native/.vs/wfp/FileContentIndex/1ea7c8ef-a6e3-48ce-ad7d-cfd2e4521f0c.vsidx
native/.vs/wfp/v17/.suo
native/.vs/wfp/v17/Browse.VC.db
native/.vs/wfp/v17/Browse.VC.db-shm
native/.vs/wfp/v17/Browse.VC.db-wal
native/.vs/wfp/v17/Browse.VC.opendb
native/.vs/wfp/v17/ipch/AutoPCH/6a893ca213c7b4d3/WFP.ipch
native/.vs/wfp/v17/ipch/AutoPCH/a44b87551f39ffc5/WFP.ipch
135 changes: 135 additions & 0 deletions native/wfp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,60 @@

#pragma comment (lib, "fwpuclnt.lib")

GUID GetLayerGUID(const wchar_t* layerName) {
if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_IPPACKET_V4") == 0) return FWPM_LAYER_INBOUND_IPPACKET_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_IPPACKET_V6") == 0) return FWPM_LAYER_INBOUND_IPPACKET_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_IPPACKET_V4") == 0) return FWPM_LAYER_OUTBOUND_IPPACKET_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_IPPACKET_V6") == 0) return FWPM_LAYER_OUTBOUND_IPPACKET_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_IPPACKET_V4_DISCARD") == 0) return FWPM_LAYER_INBOUND_IPPACKET_V4_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_IPPACKET_V6_DISCARD") == 0) return FWPM_LAYER_INBOUND_IPPACKET_V6_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD") == 0) return FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_IPPACKET_V6_DISCARD") == 0) return FWPM_LAYER_OUTBOUND_IPPACKET_V6_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_IPFORWARD_V4") == 0) return FWPM_LAYER_IPFORWARD_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_IPFORWARD_V6") == 0) return FWPM_LAYER_IPFORWARD_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_IPFORWARD_V4_DISCARD") == 0) return FWPM_LAYER_IPFORWARD_V4_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_IPFORWARD_V6_DISCARD") == 0) return FWPM_LAYER_IPFORWARD_V6_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_TRANSPORT_V4") == 0) return FWPM_LAYER_INBOUND_TRANSPORT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_TRANSPORT_V6") == 0) return FWPM_LAYER_INBOUND_TRANSPORT_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_TRANSPORT_V4") == 0) return FWPM_LAYER_OUTBOUND_TRANSPORT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_TRANSPORT_V6") == 0) return FWPM_LAYER_OUTBOUND_TRANSPORT_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD") == 0) return FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_TRANSPORT_V6_DISCARD") == 0) return FWPM_LAYER_INBOUND_TRANSPORT_V6_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD") == 0) return FWPM_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD") == 0) return FWPM_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_STREAM_V4") == 0) return FWPM_LAYER_STREAM_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_STREAM_V6") == 0) return FWPM_LAYER_STREAM_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_STREAM_V4_DISCARD") == 0) return FWPM_LAYER_STREAM_V4_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_STREAM_V6_DISCARD") == 0) return FWPM_LAYER_STREAM_V6_DISCARD;
else if (wcscmp(layerName, L"FWPM_LAYER_DATAGRAM_DATA_V4") == 0) return FWPM_LAYER_DATAGRAM_DATA_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_DATAGRAM_DATA_V6") == 0) return FWPM_LAYER_DATAGRAM_DATA_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_ICMP_ERROR_V4") == 0) return FWPM_LAYER_INBOUND_ICMP_ERROR_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_ICMP_ERROR_V6") == 0) return FWPM_LAYER_INBOUND_ICMP_ERROR_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_ICMP_ERROR_V4") == 0) return FWPM_LAYER_OUTBOUND_ICMP_ERROR_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_ICMP_ERROR_V6") == 0) return FWPM_LAYER_OUTBOUND_ICMP_ERROR_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4") == 0) return FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V6") == 0) return FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_AUTH_LISTEN_V4") == 0) return FWPM_LAYER_ALE_AUTH_LISTEN_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_AUTH_LISTEN_V6") == 0) return FWPM_LAYER_ALE_AUTH_LISTEN_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4") == 0) return FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6") == 0) return FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_AUTH_CONNECT_V4") == 0) return FWPM_LAYER_ALE_AUTH_CONNECT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_AUTH_CONNECT_V6") == 0) return FWPM_LAYER_ALE_AUTH_CONNECT_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4") == 0) return FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_FLOW_ESTABLISHED_V6") == 0) return FWPM_LAYER_ALE_FLOW_ESTABLISHED_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET") == 0) return FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET;
else if (wcscmp(layerName, L"FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET") == 0) return FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V4") == 0) return FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V6") == 0) return FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_CONNECT_REDIRECT_V4") == 0) return FWPM_LAYER_ALE_CONNECT_REDIRECT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_CONNECT_REDIRECT_V6") == 0) return FWPM_LAYER_ALE_CONNECT_REDIRECT_V6;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_BIND_REDIRECT_V4") == 0) return FWPM_LAYER_ALE_BIND_REDIRECT_V4;
else if (wcscmp(layerName, L"FWPM_LAYER_ALE_BIND_REDIRECT_V6") == 0) return FWPM_LAYER_ALE_BIND_REDIRECT_V6;

// Default to a null GUID if not found
return GUID_NULL;
}

const wchar_t* GetLayerName(GUID layerId) {
if (IsEqualGUID(layerId, FWPM_LAYER_INBOUND_IPPACKET_V4)) return L"FWPM_LAYER_INBOUND_IPPACKET_V4";
else if (IsEqualGUID(layerId, FWPM_LAYER_INBOUND_IPPACKET_V6)) return L"FWPM_LAYER_INBOUND_IPPACKET_V6";
Expand Down Expand Up @@ -49,6 +103,58 @@ const wchar_t* GetLayerName(GUID layerId) {
else return L"Unknown Layer";
}

void AddBypassFilter(const std::wstring& filterName, const GUID& layerKey, const GUID& subLayerKey) {

HANDLE engineHandle = NULL;
FWPM_SESSION session = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC;

// Open the WFP engine
if (FwpmEngineOpen(NULL, RPC_C_AUTHN_DEFAULT, NULL, NULL, &engineHandle) != ERROR_SUCCESS) {
printf("Failed to open WFP engine.\n");
return;
}

// Prepare the filter details
FWPM_FILTER0 filter = { 0 };
filter.displayData.name = const_cast<wchar_t*>(filterName.c_str());

// Set the layer key
filter.layerKey = layerKey;

// Set the sublayer key
filter.subLayerKey = subLayerKey;

// Set filter conditions (none in this case for a complete bypass)
filter.numFilterConditions = 0;
filter.filterCondition = NULL;

// Set action type to permit
filter.action.type = FWP_ACTION_PERMIT;

// Set the highest possible weight to ensure this filter takes precedence
UINT64 maxValue = UINT64_MAX;
filter.weight.type = FWP_UINT64;
filter.weight.uint64 = &maxValue;

// Additional filter flags
filter.flags = FWPM_FILTER_FLAG_NONE;

// Persistent filter that survives system reboot
filter.flags |= FWPM_FILTER_FLAG_PERSISTENT;

// Attempt to add the filter
UINT64 filterId = 0;
DWORD result = FwpmFilterAdd0(engineHandle, &filter, NULL, &filterId);

if (result == ERROR_SUCCESS) {
wprintf(L"Successfully added bypass filter '%s' with ID: %llu\n", filterName.c_str(), filterId);
}
else {
wprintf(L"Failed to add bypass filter. Error: 0x%x\n", result);
}
}


// Function to enumerate and list all filters and their layers
void ListWFPFilters(const std::wstring& layerNameFilter = L"", boolean deleteit=false) {
Expand Down Expand Up @@ -130,12 +236,21 @@ void ListWFPFilters(const std::wstring& layerNameFilter = L"", boolean deleteit=
FwpmEngineClose(engineHandle);
}


GUID GetDefaultSubLayerKey() {
static const GUID MICROSOFT_DEFENDER_SUBLAYER_WSH =
{ 0xb3cdd441, 0xaf90, 0x41ba, { 0xa7, 0x45, 0x7c, 0x60, 0x08, 0xff, 0x23, 0x00 } };

return MICROSOFT_DEFENDER_SUBLAYER_WSH;
}

int wmain(int argc, wchar_t* argv[]) {
if (argc < 2) {
std::wcerr << L"Usage: " << argv[0] << L" <command> <name>\n";
std::wcerr << L"Commands: \n";
std::wcerr << L" /list - List all layers with substring matches name\n";
std::wcerr << L" /delete - Delete a specific layer with substring matches name\n";
std::wcerr << L" /bypass <layer_name> <filter_name> - Add a bypass filter\n";
return 1;
}

Expand All @@ -150,6 +265,26 @@ int wmain(int argc, wchar_t* argv[]) {
else if (command == L"/delete") {
ListWFPFilters(input, true);
}
else if (command == L"/bypass") {
// Check if both layer name and filter name are provided
if (argc < 4) {
std::wcerr << L"Error: /bypass command requires two arguments: <layer_name> <filter_name>\n";
std::wcerr << L"Example: " << argv[0] << L" /bypass FWPM_LAYER_INBOUND_IPPACKET_V4 \"My Bypass Filter\"\n";
return 1;
}

std::wstring layerName = argv[2];
std::wstring filterName = argv[3];

GUID layerGUIDKey = GetLayerGUID(layerName.c_str());
if (layerGUIDKey == GUID_NULL)
{
std::wcerr << L"Error: could not find a matching layer GUID (please consult https://learn.microsoft.com/en-us/windows/win32/fwp/management-filtering-layer-identifiers-)\n";
return 1;
}

AddBypassFilter(filterName, layerGUIDKey, GetDefaultSubLayerKey());
}
else {
std::cerr << "Invalid command. Use /list or /delete.\n";
return 1;
Expand Down
4 changes: 2 additions & 2 deletions native/wfp.vcxproj.user
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>/list Interface</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>/bypass FWPM_LAYER_ALE_AUTH_CONNECT_V4 WSHBypassFilter</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>/list allow</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>/bypass FWPM_LAYER_ALE_AUTH_CONNECT_V4 WSHBypassFilter</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

0 comments on commit 10bc800

Please sign in to comment.