mirror of
https://github.com/wavestone-cdt/EDRSandblast.git
synced 2026-06-08 16:37:12 +00:00
48a75a7029
Co-authored-by: Maxime Meignan <maxime.meignan@wavestone.com>
222 lines
6.3 KiB
C++
222 lines
6.3 KiB
C++
extern "C" {
|
|
#include "../EDRSandblast.h"
|
|
#include "FirewallOps.h"
|
|
}
|
|
|
|
HRESULT ComInitNetFwPolicy2(INetFwPolicy2** ppNetFwPolicy2) {
|
|
HRESULT hrStatus = S_OK;
|
|
|
|
hrStatus = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
|
|
|
|
// Ignore RPC_E_CHANGED_MODE (Microsoft documentation stating that the existing mode does not matter).
|
|
if (hrStatus != RPC_E_CHANGED_MODE && FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Error while initializing COM (CoInitializeEx failed: 0x%08lx)\n"), hrStatus);
|
|
return hrStatus;
|
|
}
|
|
|
|
hrStatus = CoCreateInstance(__uuidof(NetFwPolicy2), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2), (void**)ppNetFwPolicy2);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Error while initializing the INetFwPolicy2 interface (CoCreateInstance for INetFwPolicy2 failed: 0x%08lx)\n"), hrStatus);
|
|
return hrStatus;
|
|
}
|
|
|
|
return hrStatus;
|
|
}
|
|
|
|
extern "C" HRESULT IsFirewallEnabled(BOOL* firewallIsOn);
|
|
HRESULT IsFirewallEnabled(BOOL* firewallIsOn) {
|
|
HRESULT hrComInit = E_FAIL;
|
|
HRESULT hrStatus = S_OK;
|
|
|
|
INetFwPolicy2* pNetFwPolicy2 = NULL;
|
|
long CurrentProfilesBitMask = 0;
|
|
VARIANT_BOOL vbFirewallsEnabled = VARIANT_TRUE;
|
|
VARIANT_BOOL vbFirewallProfileEnabled = VARIANT_FALSE;
|
|
|
|
struct ProfileMapElement {
|
|
NET_FW_PROFILE_TYPE2 Id;
|
|
LPCWSTR Name;
|
|
};
|
|
|
|
ProfileMapElement ProfileMap[3];
|
|
ProfileMap[0].Id = NET_FW_PROFILE2_DOMAIN;
|
|
ProfileMap[0].Name = L"Domain";
|
|
ProfileMap[1].Id = NET_FW_PROFILE2_PRIVATE;
|
|
ProfileMap[1].Name = L"Private";
|
|
ProfileMap[2].Id = NET_FW_PROFILE2_PUBLIC;
|
|
ProfileMap[2].Name = L"Public";
|
|
|
|
hrComInit = ComInitNetFwPolicy2(&pNetFwPolicy2);
|
|
if (FAILED(hrComInit)) {
|
|
hrStatus = E_FAIL;
|
|
goto cleanup;
|
|
}
|
|
|
|
hrStatus = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Could not determine Firewall status (failed to get the active Firewall profiles - get_CurrentProfileTypes failed: 0x%08lx)\n"), hrStatus);
|
|
goto cleanup;
|
|
}
|
|
|
|
for (DWORD i = 0; i < 3; i++) {
|
|
if (CurrentProfilesBitMask & ProfileMap[i].Id) {
|
|
hrStatus = pNetFwPolicy2->get_FirewallEnabled(ProfileMap[i].Id, &vbFirewallProfileEnabled);
|
|
if (FAILED(hrStatus)) {
|
|
wprintf_or_not(L"[!] Could not determine Firewall status (failed to retrieve FirewallEnabled settings for %s profile - get_FirewallEnabled failed: 0x%08lx)\n", ProfileMap[i].Name, hrStatus);
|
|
goto cleanup;
|
|
}
|
|
if (vbFirewallProfileEnabled == VARIANT_FALSE) {
|
|
wprintf_or_not(L"[*] The Windows Firewall is off on the (active) '%s' profile.\n", ProfileMap[i].Name);
|
|
vbFirewallsEnabled = VARIANT_FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
*firewallIsOn = (BOOL)(vbFirewallsEnabled == VARIANT_TRUE);
|
|
|
|
cleanup:
|
|
if (pNetFwPolicy2) {
|
|
pNetFwPolicy2->Release();
|
|
pNetFwPolicy2 = NULL;
|
|
}
|
|
|
|
if (SUCCEEDED(hrComInit)) {
|
|
CoUninitialize();
|
|
}
|
|
|
|
return hrStatus;
|
|
}
|
|
|
|
extern "C" HRESULT CreateFirewallRuleBlockBinary(TCHAR* binaryPath, NET_FW_RULE_DIRECTION direction, TCHAR* ruleName);
|
|
HRESULT CreateFirewallRuleBlockBinary(TCHAR* binaryPath, NET_FW_RULE_DIRECTION direction, TCHAR* ruleName) {
|
|
HRESULT hrComInit = E_FAIL;
|
|
HRESULT hrStatus = S_OK;
|
|
|
|
INetFwPolicy2* pNetFwPolicy2 = NULL;
|
|
INetFwRules* pFwRules = NULL;
|
|
INetFwRule* pFwRule = NULL;
|
|
|
|
BSTR bstrRuleName = NULL;
|
|
BSTR bstrRuleDescription = NULL;
|
|
BSTR bstrRuleApplication = NULL;
|
|
|
|
hrComInit = ComInitNetFwPolicy2(&pNetFwPolicy2);
|
|
if (FAILED(hrComInit)) {
|
|
hrStatus = E_FAIL;
|
|
goto cleanup;
|
|
}
|
|
|
|
// Rules parameters.
|
|
generateRandomString(ruleName, FW_RULE_NAME_MAX_LENGTH);
|
|
bstrRuleName = SysAllocString(ruleName);
|
|
bstrRuleDescription = SysAllocString(ruleName);
|
|
bstrRuleApplication = SysAllocString(binaryPath);
|
|
|
|
// hrStatus = pNetFwPolicy2->get_Rules(&pFwRules);
|
|
hrStatus = pNetFwPolicy2->get_Rules(&pFwRules);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Could not retrieve current Firewall rules (pNetFwPolicy2->get_Rules failed: 0x%08lx).\n"), hrStatus);
|
|
goto cleanup;
|
|
}
|
|
|
|
// Create a new Firewall Rule object.
|
|
hrStatus = CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwRule), (void**)&pFwRule);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Error while attempting to initiate the INetFwRule (CoCreateInstance failed: 0x%08lx).\n"), hrStatus);
|
|
goto cleanup;
|
|
}
|
|
|
|
// Populates the rule's parameters.
|
|
pFwRule->put_Name(bstrRuleName);
|
|
pFwRule->put_Description(bstrRuleDescription);
|
|
pFwRule->put_ApplicationName(bstrRuleApplication);
|
|
pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
|
|
pFwRule->put_Direction(direction);
|
|
pFwRule->put_Profiles(FW_PROFILE_TYPE_ALL);
|
|
pFwRule->put_Action(NET_FW_ACTION_BLOCK);
|
|
pFwRule->put_Enabled(VARIANT_TRUE);
|
|
|
|
// Add the new rule.
|
|
hrStatus = pFwRules->Add(pFwRule);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Error while adding the firewall blocking rule for %s (INetFwRule->Add failed: 0x%08lx)\n"), binaryPath, hrStatus);
|
|
}
|
|
|
|
cleanup:
|
|
|
|
if (pFwRule) {
|
|
pFwRule->Release();
|
|
}
|
|
|
|
if (pFwRules) {
|
|
pFwRules->Release();
|
|
}
|
|
|
|
if (pNetFwPolicy2) {
|
|
pNetFwPolicy2->Release();
|
|
}
|
|
|
|
if (bstrRuleName) {
|
|
SysFreeString(bstrRuleName);
|
|
bstrRuleName = NULL;
|
|
}
|
|
|
|
if (bstrRuleDescription) {
|
|
SysFreeString(bstrRuleDescription);
|
|
bstrRuleDescription = NULL;
|
|
|
|
}
|
|
|
|
if (bstrRuleApplication) {
|
|
SysFreeString(bstrRuleApplication);
|
|
bstrRuleApplication = NULL;
|
|
}
|
|
|
|
if (SUCCEEDED(hrComInit)) {
|
|
CoUninitialize();
|
|
}
|
|
|
|
return hrStatus;
|
|
}
|
|
|
|
extern "C" HRESULT DeleteFirewallRule(TCHAR* ruleName);
|
|
HRESULT DeleteFirewallRule(TCHAR* ruleName) {
|
|
HRESULT hrComInit = E_FAIL;
|
|
HRESULT hrStatus = S_OK;
|
|
|
|
INetFwPolicy2* pNetFwPolicy2 = NULL;
|
|
INetFwRules* pFwRules = NULL;
|
|
|
|
hrComInit = ComInitNetFwPolicy2(&pNetFwPolicy2);
|
|
if (FAILED(hrComInit)) {
|
|
hrStatus = E_FAIL;
|
|
goto cleanup;
|
|
}
|
|
|
|
hrStatus = pNetFwPolicy2->get_Rules(&pFwRules);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Could not retrieve current Firewall rules (pNetFwPolicy2->get_Rules: 0x%08lx).\n"), hrStatus);
|
|
goto cleanup;
|
|
}
|
|
|
|
hrStatus = pFwRules->Remove(ruleName);
|
|
if (FAILED(hrStatus)) {
|
|
_tprintf_or_not(TEXT("[!] Error while removing Firewall rule \"%s\" (failed with: 0x%08lx)\n"), ruleName, hrStatus);
|
|
_tprintf_or_not(TEXT("[!] The rule can be removed manually using: netsh advfirewall firewall delete rule name=%s\n"), ruleName);
|
|
}
|
|
else {
|
|
_tprintf_or_not(TEXT("[+] Successfully removed Firewall rule \"%s\"\n"), ruleName);
|
|
}
|
|
|
|
cleanup:
|
|
|
|
if (pFwRules) {
|
|
pFwRules->Release();
|
|
}
|
|
|
|
if (SUCCEEDED(hrComInit)) {
|
|
pNetFwPolicy2->Release();
|
|
}
|
|
|
|
return hrStatus;
|
|
} |