From 10bc800d1d09fe9da923b1c3ad6e0982525137f1 Mon Sep 17 00:00:00 2001 From: sagiezero <61778471+sagiezero@users.noreply.github.com> Date: Mon, 16 Dec 2024 10:02:07 +0000 Subject: [PATCH] added delete method --- .gitignore | 45 ++++++++++++++ native/wfp.cpp | 135 ++++++++++++++++++++++++++++++++++++++++ native/wfp.vcxproj.user | 4 +- 3 files changed, 182 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 788c737..f43254c 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/native/wfp.cpp b/native/wfp.cpp index 2e750d3..946b3e3 100644 --- a/native/wfp.cpp +++ b/native/wfp.cpp @@ -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"; @@ -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(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) { @@ -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" \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 - Add a bypass filter\n"; return 1; } @@ -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: \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; diff --git a/native/wfp.vcxproj.user b/native/wfp.vcxproj.user index 387c3d7..a404722 100644 --- a/native/wfp.vcxproj.user +++ b/native/wfp.vcxproj.user @@ -1,11 +1,11 @@  - /list Interface + /bypass FWPM_LAYER_ALE_AUTH_CONNECT_V4 WSHBypassFilter WindowsLocalDebugger - /list allow + /bypass FWPM_LAYER_ALE_AUTH_CONNECT_V4 WSHBypassFilter WindowsLocalDebugger \ No newline at end of file