谁动了我的打印机?

IoT 2年前 (2021) admin
1,001 0 0

01 背景

微软从2020年开始陆续修复了一系列Print Spooler服务中的漏洞,这些修复有时候也会影响到正常的打印功能。


到2021年10月,问题开始变得严重起来,大量安装了10月补丁的Windows 10用户发现他们不能正常的使用网络打印机了。


最常见的问题是在添加网络打印机时操作失败,错误提示“Windows无法连接到打印机”。在安装补丁之前已经添加好的网络打印机,也很可能在使用过程中碰到各种的错误。常见的错误代码有0x000006e4 、0x0000007c、0x00000709等。

谁动了我的打印机?


2021年11月的补丁并没有修复Windows 10的问题,而之前还正常的Windows 11在安装了11月补丁之后也开始出现了同样的问题。

谁动了我的打印机?


因此,本文对该问题的本质原因进行了分析,并尝试给出一个临时的解决方案。


02 原因分析

网事不决问Wireshark,先抓个包来看一下:

谁动了我的打印机?


这里的12号报文引起了注意:

谁动了我的打印机?


报文类型为Fault(3)说明之前请求的操作失败了,状态为nca_s_fault_access_denied(0x00000005)说明失败的原因是拒绝访问。


因为该报文是对之前的9号报文的响应,而9号报文的报文类型为AUTH3(16)说明是一个认证请求,所以这里的问题是RPC调用的认证失败了。

 

为什么认证会失败呢?来看看9号报文中的NTLM Secure Service Provider信息:

谁动了我的打印机?


从Domain name、User name、Host name可以看出,这里用来认证的凭据是当前登录的本地用户的,而不是登录到打印机服务器时所用的凭据。通常情况下,本地用户的凭据对打印机服务器来说是无效的,因此这里的认证会失败。


那么为什么这里会用当前登录的本地用户来认证呢?要回答这个问题,需要先弄清楚为什么这里会进行一次认证。


从抓包来分析,客户端之所以会发出进行认证的9号报文,是因为服务端在8号报文中发起了NTLMSSP CHALLENGE:

谁动了我的打印机?


而服务端发起NTLMSSP CHALLENGE则是因为客户端在5号报文中附加了NTLMSSP NEGOTIATE:

谁动了我的打印机?


因此,这里的认证应该是在RPC Binding过程中发起的。考虑到其他的RPC调用并无此现象,只有网络打印相关操作会进行此认证,问题可能出在RPC Binding的回调函数中。

 

网络打印相关的操作在win32spl.dll中实现,RPC调用NdrClientCall3的第一实参通常是winspool_ProxyInfo,这是一个MIDL_STUBLESS_PROXY_INFO类型的对象,从中可以定位到RPC Binding的回调函数为STRING_HANDLE_bind。

谁动了我的打印机?


在函数STRING_HANDLE_bind的末尾,调用RpcBindingFromStringBindingW函数进行Binding之后,增加了一个对RpcBindingSetAuthInfoExW函数的调用:

谁动了我的打印机?


在安装10月补丁之前是没有这一调用的:

谁动了我的打印机?


正是这里对RpcBindingSetAuthInfoExW函数的调用,使得RPC调用的过程中会再进行一次认证,而这次认证会因为使用了本地用户的凭据而失败,从而使RPC调用失败,进而使得网络打印相关的操作无法正常进行。


03 解决方案

找到了问题的根本原因后,解决起来就很简单了。既然问题是由对RpcBindingSetAuthInfoExW函数的调用引起的,而安装10月补丁之前并没有这一调用,说明该调用并不是必须的,那么可以尝试跳过该函数来看一看。

 

对spoolsv.exe进程进行调试,将对RpcBindingSetAuthInfoExW函数的调用修改为空指令(注意这里需要将寄存器eax中的返回值清零):

谁动了我的打印机?


此时再尝试添加网络打印机就可以顺利完成了,相关功能也都能正常使用了。

谁动了我的打印机?


微软在2021年11月22日发布的预览版补丁中修复了该问题。

谁动了我的打印机?


Windows 10的预览版补丁是KB5007253:

谁动了我的打印机?


Windows 11的预览版补丁是KB5007262:

谁动了我的打印机?


该补丁的处理思路跟前述解决方案是一致的,在调用RpcBindingSetAuthInfoExW函数之前,先调用IsAuthenticationRequiredForNamedPipeRpc函数来判断是否需要调用,只在特定情况下才调用该函数。

谁动了我的打印机?


IsAuthenticationRequiredForNamedPipeRpc函数根据是否加入了域分情况进行处理。在加入了域的情况下,如果RpcNamedPipeAuthentication注册表项不等于2,并且设置了RpcAuthnLevelPrivacyEnabled注册表项,则返回True。在没有加入域的情况下,如果RpcNamedPipeAuthentication注册表项等于1,则返回True。其他情况下一律都返回False。

谁动了我的打印机?


这样,在之前网络打印会出现问题的环境中,IsAuthenticationRequiredForNamedPipeRpc函数将会返回False,从而跳过对RpcBindingSetAuthInfoExW函数的调用,进而避免因为认证失败而无法进行网络打印的相关操作,临时的解决网络打印机不能正常工作的问题。


04 总结

微软2021年10月的补丁,在错误的Context中调用RpcBindingSetAuthInfoExW函数,使得网络打印相关的RPC调用因认证失败而无法执行,从而导致网络打印机不能正常工作。


跳过对RpcBindingSetAuthInfoExW函数的调用,可以临时的解决该问题。


微软2021年11月的预览版补丁修复了该问题,预计12月的补丁将可以正式解决该问题。


谁动了我的打印机?

绿盟科技天机实验室专注于攻防对抗技术。研究方向主要包括漏洞挖掘技术研究、漏洞分析技术研究、漏洞利用技术研究、安全防御机制及对抗技术研究等。研究目标涵盖主流操作系统、流行的应用系统及软件、重要的基础组件库以及新兴的技术方向。


谁动了我的打印机?

M01N Team

聚焦高级攻防对抗热点技术

绿盟科技蓝军技术研究战队


原文始发于微信公众号(M01N Team):谁动了我的打印机?

版权声明:admin 发表于 2021年12月8日 上午11:16。
转载请注明:谁动了我的打印机? | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...