Netfilter Driver Security Best Practices
Overview
This document provides security configuration guidelines for applications using the Netfilter SDK driver. It addresses critical security considerations for restricting both service-level and device object access to prevent unauthorized users from obtaining read/write handles to the driver device.
For general security best practices across all platforms, see the Security Best Practices guide.
Security Challenge
The Netfilter SDK driver, by default, creates its device object with Everyone/GENERIC_ALL permissions. Additionally, the SDK does not explicitly set any permissions on the partner_netfilter driver, resulting in default OS permissions being applied. This default configuration allows any user, including non-administrative users, to open the device with read and write access, potentially creating security vulnerabilities.
SDK Limitations and Responsibilities
Using NetFilter features please note that:
The SDK does not explicitly set permissions on the partner_netfilter driver
Using IoCreateDeviceSecure to address this issue is not feasible since partner_netfilter2.sys is a third-party driver from Netfilter SDK, and we cannot modify its source code
Installation and removal of the Netfilter driver is the responsibility of Apps, not the SDK, as referenced here.
Important Note on Security Layers
There are two distinct security layers to consider:
Service permissions - Controls who can start, stop, and manage the driver service
Device object permissions - Controls who can open handles to the driver device for I/O operations
Setting ACLs on the driver service using tools like sc sdset
controls service permissions but does not affect the driver device object permissions. For comprehensive security, both layers should be configured.
Solution 1: Registry-Based Device Object Security (Primary)
Netfilter provides a built-in mechanism to configure device object security through Windows registry settings. This approach allows administrators to restrict device access without modifying the driver source code.
Registry Configuration
Configure the following registry setting to enable device security:
Registry Path: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<driver_name>
Value Name: seclevel
Value Type: REG_DWORD
Recommended Value: 3
Security Level Options
The seclevel
value uses a bitmask to determine access permissions:
0
No restrictions
Everyone has access (default, not recommended)
1
LocalSystem only
Only LocalSystem account can access
2
Administrators only
Only members of Administrators group
3
LocalSystem + Administrators
Recommended setting
4
All authenticated users
Any authenticated user can access
Solution 2: Service-Level Security (Complementary)
While the registry-based approach controls device object permissions, you can additionally restrict service-level permissions to control who can manage the driver service itself. This provides an additional layer of security through defense in depth.
Service ACL Configuration
To properly restrict access to the Netfilter driver service, set more restrictive ACLs after driver installation using the service controller (sc.exe). The recommended ACL grants general access only to the local system (SY) and built-in admin (BA) accounts:
sc.exe sdset <name-of-installed-netfilter-driver> "D:P(A;;FA;;;SY)(A;;GA;;;BA)"
This command must be executed with administrative privileges.
Implementation Considerations
This approach controls service permissions and is consistent with standard Windows service security practices
While we could theoretically set more restrictive SDDL during the SDK installation process, this approach would only be effective if the partner_netfilter driver has been installed prior to the SDK
The SDK cannot guarantee this installation sequence, as Netfilter driver installation is not part of the SDK installation process
This has been tested and validated to work correctly with all standard Netfilter-related functionality
Complete Implementation Guide
Installation Process
Follow these steps during application installation to properly secure both the service and device object:
Install the driver service (do not start it yet)
sc create <service_name> type= kernel binPath= <path_to_driver>
Set service-level permissions (optional but recommended)
sc.exe sdset <service_name> "D:P(A;;FA;;;SY)(A;;GA;;;BA)"
Set the device object security level in the registry (optional but recommended)
reg add HKLM\SYSTEM\CurrentControlSet\Services\<driver_name> /v "seclevel" /t REG_DWORD /d 3 /f
Start the driver service
sc start <service_name>
Example Implementation
For a driver named partner_netfilter2
:
rem Install driver service
sc create partner_netfilter2 type= kernel binPath= C:\Drivers\partner_netfilter2.sys
rem Set service-level permissions (optional but recommended)
sc.exe sdset partner_netfilter2 "D:P(A;;FA;;;SY)(A;;GA;;;BA)"
rem Set device object security level to LocalSystem + Administrators
reg add HKLM\SYSTEM\CurrentControlSet\Services\partner_netfilter2 /v "seclevel" /t REG_DWORD /d 3 /f
rem Start the service
sc start partner_netfilter2
Critical Implementation Notes
Timing Requirements
The
seclevel
registry value MUST be set before starting the driver serviceSecurity configuration is applied during driver initialization
Setting the value after the driver starts will have no effect until the next restart
Service ACLs can be set at any time but take effect immediately for service operations
Modifying Existing Installations
If the driver is already running, you must:
Stop the driver service
Set the service permissions (if desired)
Set the registry value
Restart the driver service
sc stop <service_name>
sc.exe sdset <service_name> "D:P(A;;FA;;;SY)(A;;GA;;;BA)"
reg add HKLM\SYSTEM\CurrentControlSet\Services\<driver_name> /v "seclevel" /t REG_DWORD /d 3 /f
sc start <service_name>
Verification
After implementing the security configuration, verify that only authorized users can access the device.
Testing Device Access
Here is a minimal code snippet to test if the device can be opened:
#include <windows.h>
#include <stdio.h>
#include <string>
#include <iostream>
int main() {
// Expected device name format is \\.\CtrlSM<netfilter-driver-name>
std::string symbolicDeviceName = "\\\\.\\CtrlSMpartner_netfilter2";
std::cout << "Checking access to device: " << symbolicDeviceName << std::endl << std::endl;
HANDLE hDevice = CreateFileA(
symbolicDeviceName.c_str(),
READ_CONTROL,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
std::cout << "[-] Could not open the device. Error: " << GetLastError() << std::endl;
}
else {
std::cout << "[!] Device handle opened successfully. If not running as admin, please verify device object security settings." << std::endl;
CloseHandle(hDevice);
}
std::cout << "Press any key to exit...";
std::cin.get();
return 0;
}
Important: For this test to work correctly, the netfilter driver must be in running state, and the SDK service must be stopped. Otherwise, opening the device will fail with errors other than 5 (error 1 or 2).
Expected Test Results
If device cannot be accessed due to restrictive ACL (expected for non-admin users):
[-] Could not open the device. Error: 5
(Error 5 is the Windows error code for "Access denied")
If device is opened successfully (due to less restrictive ACL or app being run as admin):
[!] Device handle opened successfully. If not running as admin, please verify device object security settings.
Expected Behavior
Note: The following outputs are generated by a custom application created specifically for testing device permissions. These are not standard Windows system outputs or error messages.
Normal User Access (should fail):
Checking access to \\.\<device_name>
[-] Could not access device as <username> (Normal User). Error 5 - Access is denied.
Administrator Access (should succeed):
Checking access to \\.\<device_name>
[+] SUCCESS: Opened device handle as <username> (Admin)
Access Control List Verification
When properly configured with seclevel=3
, the device ACL should show:
NT AUTHORITY\SYSTEM - Full access
BUILTIN\Administrators - Full access
No other security principals should have access to the device.
Service Permission Verification
You can verify service permissions using:
sc sdshow <service_name>
The output should show the restricted SDDL string if properly configured.
Troubleshooting
Common Issues
Device still accessible by normal users after configuration
Verify the registry value is set correctly
Ensure the driver was restarted after setting the registry value
Check that the correct service name is used in the registry path
Access denied errors for legitimate services
Ensure required services are running with appropriate privileges
Consider if LocalSystem access is sufficient (seclevel=1)
Verify service ACLs are not overly restrictive
Shared access conflicts
Some services may open the device without shared access
This can cause legitimate access attempts to fail with Error 1
Consider service dependencies and startup order
Service management issues
If administrators cannot manage the service after setting ACLs, verify the SDDL string is correct
Ensure the account performing service operations has appropriate permissions
Last updated
Was this helpful?