npcap
npcap copied to clipboard
Npcap: use granular ACL to control access to capture/injection
Currently (Npcap 0.9984), Npcap can only control access to capture and inject at the device level, where the device is the special name and handle that the Npcap driver creates on the system, through which Packet.dll requests handles based on network interface name/GUID. In order to increase security, Npcap offers "Admin-only mode," which uses SDDL for Device Objects to restrict access to users with Builtin Admin privilege. This requires UAC elevation and applies to all Npcap functions on all interfaces. It is not possible to grant access to individual users or groups.
Instead of relying on device-level access control, Npcap could check the calling user's security identifier against a fully-featured ACL within the IRP_MJ_CREATE handler. This could enable us to do very specific access control like "Members of the Npcap Read domain group can do packet capture on these interfaces, but not packet injection."
Challenges:
- Where and how should the ACL be stored? Probably the Registry, but need specifics and format.
- How should system admins update or modify the ACLs? Probably a helper program, but it would be best to use existing Windows APIs and dialogs for identifying principals and editing ACEs.
- Synchronization between Registry and running driver, avoiding race conditions.
This could enable us to do very specific access control like "Members of the Npcap Read domain group can do packet capture on these interfaces, but not packet injection."
$ ls -l /dev/bpf0
crw-r----- 1 root access_bpf 23, 0 Mar 25 18:49 /dev/bpf0
Unfortunately, macOS's devfs doesn't support ACLs, as I remember from when I checked, many years ago, but....
So, yes, those sorts of controls are available, at least on UN*Xes that 1) grant capture device access through devices (so that's *BSD, macOS, AIX, and Solaris 11, but not Linux), and fine-grained ACLs are available if the file system in question supports ACLs.
(macOS's default configuration is "root only". Wireshark installs a script that runs at startup time and provides read and write capabilities to the BPF devices to the access_bpf group; I just temporarily changed the permissions there to show "root can inject, access_bpf members can't".)
Apparently I filed #96 for the same issue. There are good ideas there as well, but we'll consolidate to this one for discussion.
Current status on this: I'm thinking that the Npcap install directory is a better place than the Registry to store ACLs. Specifically, Npcap's access levels can be easily mapped from filesystem access levels, so having the user set a filesystem ACL on a particular file would allow them to use built-in Windows tools (Properties -> Security tab, icacls, powershell, or whatever enterprise solution they already use) to manage access easily.
Challenges/danger spots:
- Doing "name structure" access control (MS's term for this) means we have to drop the
FILE_DEVICE_SECURE_OPENflag fromIoCreateDeviceSecure(), so we'll have to make sure that accesses to\Devices\Npcapare treated the same as\Devices\Npcap\, since the I/O manager will only enforce our device SDDL for the former. - Have to make sure the
Full ControlorModifyprivileges on the "ACL storage" files are not granted to any low-privilege accounts, otherwise it'd be trivial to escalate. We only care about "Read" (capture) and "Write" (inject) privileges for now, but have to consider that the ACLs are also protecting the file itself. - The installer must preserve existing ACLs on upgrade, but should also avoid propagating bad permissions: if
$INSTDIRis world-writeable (often the case if user has used debug-to-file build of Packet.dll), then anyone can replace the ACL files with new ones.
Moving parts that we would have to implement:
- Driver reads ACLs from files in install dir in DriverEntry (for defaults) and FilterAttach (for device-specifics).
- Sane default ACLs for no files present as well as a "default permissions" file for user-defined ACL on all devices without more-specific ACL file.
- New DeviceIoControl code to tell the driver to re-read the ACLs from the filesystem. Would be valid only on the root device and would be accessible via a new option to NPFInstall.exe.
- Validate the ACL in
NPF_OpenAdapter()(IRP_MJ_CREATE).
References:
- https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/introduction-to-file-systems-security
- OSR article on security descriptors, acls, and using them in a driver: http://www.osronline.com/article.cfm%5eid=23.htm