问题描述
遇到了个问题,win10以上防火墙服务mpssvc无法通过服务管理器来修改启动方式,也无法关闭服务。
防火墙服务变动:
Windows 10 - 1511 - 10.0.10586,旧的防火墙
Windows 10 - 1607 - 10.0.14393,旧的防火墙
Windows 10 - 1703 - 10.0.15063,旧的防火墙
Windows 10 - 1709 - 10.0.16299.15,新的防火墙
2017年4月11日,微软发布Windows 10创意者更新Creators Update,版本号1703;
2017年10月18日,微软发布Windows 10创意者秋季更新Fall Creators Update,版本号1709。
新旧版本防火墙服务对比:
Win10系统1709版本后,变更了系统防火墙,官方说法是改了个名字,其实不止。
1.名称变化
1703:Windows Firewall
1709:Windows Defender Firewall
2.参数变化
1703:C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
1709:C:\Windows\system32\svchost.exe -k LocalServiceNoNetworkFirewall -p
3.服务组变化
1703:BFE、CoreMessagingRegistar、DPS、Mpssvc在同一个组里,LocalServicesNoNetwork
1709:把BFE与mpssvc单独拉了一个防火墙组出来,LocalServicesNoNetworkFirewall
4.服务可接收控制命令变化,不再接受停止
sc query mpssvc命令可以查询到服务可接收控制命令
1703:STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN
1709:NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN
5.服务安全描述符变化(应该是回收了一些权限)
1703:
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCRP;;;S-1-5-80-2006800713-1441093265-249754844-3404434343-1444102779)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
1709:
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
6.服务依赖和注册表
无明显变动,就不详细列出来了
尝试内容:
1.停止服务
服务无法停止
sc stop mpssvc
停止服务会执行出错。错误5: 拒绝访问。
如果你更改成了旧版本的安全描述符。错误1052: 请求的控件对此服务无效。
也就是说,服务无法停止,要么开机时候不启动,只要启动了就停不下来,可以不用尝试停止了。
另外,不要尝试杀进程的方式停防火墙服务,你敢杀,它就敢蓝屏给你看。
2.修改注册表,更改启动方式
方法好用,可修改启动方式,需要重启生效;
修改注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mpssvc之中的
start的值,比如改成2自动,3手动,都可以变更启动方式;
如果开机后,服务禁用+停止,这时通过注册表修改成2自动,再去启动服务;
就会报错“错误1058,无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动”;
当启动了mpssvc的所有依赖项目后,再启动mpssvc,发现还是这个错误。
3.删文件+更新策略
RD /S /Q “%WinDir%/System32/GroupPolicyUsers”
RD /S /Q “%WinDir%/System32/GroupPolicy”
gpupdate /force
实测结果为无效
这倒霉方法谁想的,删文件+更新策略,这玩意能把服务管理器界面上的防火墙服务的按钮搞成可用?
谁要是试了好使,请评论一下。
4.使用Windows PowerShell(管理员)执行命令
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
命令本身好使,对我而言,无实际意义
命令本质修改的是防火墙功能中的域、专用、公用开关为关闭;
但是我要处理的是防火墙服务,非防火墙功能,
5.提升执行操作进程,将其用户提升至SYSTEM
结果为无效(2023.01.31补,这里其实有效,只是我的测试程序权限申请过多了)
使用psexec.exe,把cmd和我的进程都提升到SYSTEM用户。
结果发现SYSTEM用户与管理员用户administrator对于防火墙服务的权限无明显区别;
6.官方给出的修复防火墙的工具(链接在参考资料里)
结果为无效
一点不吃惊,呵呵,感觉微软给出的修复方案,要是能好使,我反而会吃惊。
7.尝试变动服务可接收控制命令,使其接受停止服务
结果为无效
目前未找到任何可通过其他进程来合规修改服务的可接收控制命令的方法,或许有卡系统BUG的方法,但是这样不合规,万一哪天微软修复了,岂不是白做?
了解一下服务控制器获取服务信息的步骤;
1)开机时,服务控制器从注册表中获取当前需要加载的服务,并根据服务启动的顺序,依次对服务进行加载和启动;
2)服务控制器从注册表中获取到服务的启动方式、路径等信息,但是它此时并不知道服务可接收哪些控制命令;
3)服务进程启动后,由服务进程向服务控制器汇报当前服务状态,以及接收哪些控制命令,即调用SetServiceStatus;此时,服务控制器才知道服务可接收的控制命令都要什么。
4)当发生服务可接收的控制命令时,服务控制器会调用服务来处理该控制命令;当发生服务不接收的控制命令时,服务控制器会拒绝掉这个控制命令。
在c++代码实现里:
服务启动时,ServiceMain里需要先调用SetServiceStatus,设置当前服务状态和可接收控制命令(服务状态此时设置为SERVICE_START_PENDING),然后调用RegisterServiceCtrlHandler注册回调函数,以便处理不同的控制命令。
待服务进程初始化完成,再调用SetServiceStatus来设置当前服务状态为SERVICE_RUNNING。
服务控制器会根据发生的控制命令,决定是否调用RegisterServiceCtrlHandler函数所注册的回调函数,并执行该回调中相关控制命令的操作。
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch(dwOpcode)
{
case SERVICE_CONTROL_STOP:
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
}
}
SERVICE_STATUS_HANDLE hServiceStatus=RegisterServiceCtrlHandler(szServiceName,ServiceStrl);
SERVICE_STATUS status;
status.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
status.dwCurrentState=SERVICE_START_PENDING;
status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode=0;
status.dwServiceSpecificExitCode=0;
status.dwCheckPoint=0;
status.dwWaitHint=0;
SetServiceStatus(hServiceStatus,&status);
解决方案:
1.使用高权限运行修改
1709以上,system权限允许使用API修改服务启动方式,管理员权限不允许;
有一点要注意,OpenService不要无脑申请所有权限SERVICE_ALL_ACCESS,做什么操作申请什么权限。
比如我需要查询当前服务配置,如果不是自动就改成自动,那么申请读取配置权限和变更配置权限就行了。
hService = OpenService( hSvrMgr, _T( “mpssvc” ), SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG );
无脑申请一大堆权限,如果申请了当前用户不具备的权限,OpenService就报错退出了。
2.修改启动方式+启动服务(管理员权限)
开机后,服务禁用+停止,1709以上常规方法无法启动服务,可用下面方法可以不重启电脑启动服务
(1)查看当前的安全描述符
sc sdshow mpssvc
(2)更改安全描述符为旧版本的
sc sdset mpssvc D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCRP;;;S-1-5-80-2006800713-1441093265-249754844-3404434343-1444102779)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
(3)变更启动方式
变更为自动:
sc config mpssvc start=auto
或者变更为手动:
sc config mpssvc start=demand
(4)启动服务
sc start mpssvc
(5)还原安全描述符为新版本的(要是觉得用旧的也行了,可以不操作这步)
sc sdset mpssvc D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
2.停止服务
不用考虑了,没有常规的、不用重启的方法来停止服务。
可以用替代方法,比如,关闭域、专用、公用三个配置文件的防火墙开关。
参考资料:
1.WIN10版本历史更新记录
2.WIN10创意者更新(1709)可用(Windows 10 Fall Creators Update (1709) fully available)
3.Windows 10 秋季创意者更新中的新增功能
4.非微软官方的一个更新内容,其中有关于Fall Creators Update的内容
5.建议确保Windows防火墙服务已启动并配置为自动启动
6.官方给出的修复防火墙的工具连接
7.openServiceA
8.服务安全性和访问权限