自從買了印表機(誰動了我的印表機)
2023-04-19 23:04:17 3
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月的補丁將可以正式解決該問題。
,