Windows minifilter文件过滤驱动修改进程权限级别实现方法
Windows Minifilter拦截EXE加载阶段切换进程SYSTEM/Administrator权限的可用内核API
先说句实在的:内核态改进程权限是高危操作,IRQL不对、对象没解引用、版本兼容没做好,分分钟蓝屏或者触发PatchGuard,上线前一定要在全版本系统测透
前置拦截时机校验
在minifilter里拦EXE加载,首先得在IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION的预操作回调里把过滤条件写对,别乱拦无关请求:
- 先校验请求的页保护属性是否带
PAGE_EXECUTE,不带的就不是可执行映像加载,直接放过 - 再校验目标文件对象的
SectionObjectPointer->ImageSectionObject是否为空,非空说明这个EXE已经加载过了,不用重复处理 - 这里有个高频坑:这个回调触发点偏早,部分Win10/Win11版本里,刚进回调的时候目标进程的主令牌还没初始化完,这时候直接操作令牌大概率触发访问违例蓝屏。碰到这种情况就配合
PsSetCreateProcessNotifyRoutineEx注册进程创建回调,等进程初始化流程走完再执行权限调整,别在回调里阻塞硬等。
核心可用内核API
按操作流程分类如下:
进程/线程对象获取类
PsLookupProcessByProcessId:传入进程PID获取EPROCESS结构指针,用完必须调用ObDereferenceObject释放对象引用,不然会出现内核内存泄漏。要拿System进程对象直接传PID=4即可,不需要额外绕弯。IoThreadToProcess:如果回调触发时当前线程处于目标进程上下文(EXE加载阶段默认满足该条件),可直接调用该API获取当前进程的EPROCESS指针,不需要通过PID查找,执行效率更高。ObReferenceObject/ObDereferenceObject:对所有拿到的内核对象(进程、令牌、工作项等)做引用计数管理,避免对象提前释放或残留泄漏。
令牌操作类(权限切换核心)
PsReferencePrimaryToken/PsDereferencePrimaryToken:从EPROCESS结构中获取进程的主访问令牌指针,用完必须解引用。ZwOpenProcessTokenEx:内核态下打开进程令牌句柄,调用时需根据操作类型传入对应访问掩码:调整特权需要TOKEN_ADJUST_PRIVILEGES,修改令牌完整性/组属性需要TOKEN_ADJUST_DEFAULT,替换主令牌需要TOKEN_ASSIGN_PRIMARY和TOKEN_DUPLICATE权限。SeAssignPrimaryToken:内核态为目标进程分配新的主令牌,是直接替换进程令牌实现权限切换的核心API:提权到SYSTEM时可直接引用System进程的主令牌传入;降权到Administrator时需先复制现有令牌、调整特权和完整性级别后再传入。ZwAdjustPrivilegesToken:调整令牌内的单个特权状态(启用/禁用),如果不需要完全替换令牌,仅通过增删特权调整权限级别时用该API即可,比如给Administrator权限的进程开启SeDebugPrivilege、SeTcbPrivilege等高特权,或给SYSTEM权限进程移除敏感特权实现降权。ZwSetInformationToken:设置令牌的属性,降权场景下需要传入TokenIntegrityLevel信息类,将令牌的完整性级别从SYSTEM级(RID 16384)调整到高完整性级(RID 12288,对应Administrator默认完整性)。RtlCreateSid:创建权限调整需要的SID值,比如Administrators组SID(S-1-5-32-544)、SYSTEM账户SID(S-1-5-18)、完整性级别SID等。SeImpersonateClientEx/PsRevertToSelf:如果当前上下文没有足够权限操作目标进程令牌,可先模拟System令牌上下文执行操作,操作完成后必须调用PsRevertToSelf恢复原上下文,禁止在模拟状态下直接返回上层回调。
异步执行类
IoQueueWorkItem:如果回调运行在IRQL >= APC_LEVEL,必须将权限操作封装成工作项丢到系统工作线程(PASSIVE_LEVEL)执行,避免高IRQL下调用令牌操作API触发蓝屏,同时避免回调中阻塞等待造成死锁。
关键注意事项
- 别照搬网上野教程硬编码EPROCESS的Token偏移直接改内存,Win10之后几乎每个大版本甚至部分累积更新都会调整内核结构偏移,硬编码跨版本必崩,老老实实用微软公开的内核API。
- 从SYSTEM降权到Administrator不是光改个完整性级别就完事,必须把令牌里SYSTEM独有的高特权(比如
SeTcbPrivilege、SeLoadDriverPrivilege这些)清掉,不然看起来是High完整性,实际权限比普通Admin高得多,等于没做降权。 - 替换主令牌之前先清理目标进程里挂的模拟令牌,不然后续进程运行时权限状态混乱,出问题根本没法排查。
- 所有内核API调用都要校验返回值,拿令牌失败、权限不足的时候直接放弃操作,别硬往下走,内核态没有用户态那么多容错空间。
内容的提问来源于stack exchange,提问作者Zig Shanklin
相关产品推荐
相关产品推荐

