題外話:讀此文前,你要有思想準備,不是那麼簡單,你有可能懵圈。 git
這是一個Windows打印機後臺程序的本地提權漏洞,但這個漏洞與以往介紹的本地提權漏洞徹底不一樣,有必定的限制條件,但從理解windows的角度確實有意思。github
通常狀況下,我研究東西的速度很快,多是學的比較雜的緣故,每一個相關的方向都懂一點。但這個漏洞的復現我花了很多時間,走了一些彎路。windows
這個漏洞微軟修補時間爲今年的5月份,聽說和「震網」是同一個級別的漏洞(震網中也使用了打印機漏洞),固然興趣更濃了,必定要一睹風采。安全
1、POC
服務器
源碼:https://github.com/ionescu007/PrintDemon微信
我用vs2019編譯成exe,將整個源碼和exe打包放在:網絡
連接:https://pan.baidu.com/s/17CclA4J3TwT9mY-XcfpGoA函數
提取碼:hpen測試
2、漏洞影響範圍:spa
Windows的許多最新版本,包括Windows Server 200八、20十二、2016和2019以及Windows 七、8.1和10,危害挺大的。
3、復現過程
一、環境:win10 x64;
聲明,我當時測試時使用的是win7 x64;下面的說明先以win7爲例,後面的以win10爲例,我會在文中說明;
二、創建個普通權限的用戶,test
三、將打包中的exe放入此win測試機中;當運行時出現這樣的提示,說明test權限不夠,要用管理員權限才能複製程序;
四、將兩個主程序printserver.exe和printclient.exe復機到桌面,運行printserver.exe,
這時,看下打印機,多出一個PrintDemon;
看下打印機隊列;
多出一個任務「本地下層文檔」,隸屬於用戶test,「已暫停」狀態;
運行printclient.exe,出現錯誤提示;
出現不能識別的錯誤提示。。。提示打開00002.shd文件,在c:\windows\system32\spool\PRINTERS目錄下;
先記住這兩個文件和那個目錄;
找緣由,爲何報錯,看源代碼:
再找下 這個 only support Version 4:
哎,寫得清清楚楚,這個POC是用win10來作驗證的,這麼大說明都看不見啊,用win7固然報錯了。換成win10,好了,這下面都是win10的操做了。
五、一樣的步驟;
六、成功發送到打印機。
七、怎麼提權?這仍是test啊,沒有變成「管理員 test」啊。
八、咱們知道當使用普通權限登陸windows時,若是往windows裏複製文件都是提示要管理員權限才行,還記得咱們複製的運行printserver的兩個系統dll文件嗎,往上看圖,有個vcruntion140d.dll。說明在整個windows目錄下都是要管理員權限才能動的。
九、看源碼,發如今「c:\windows\tracing\」寫入了demoport.txt;
說明:發如今「c:\windows\tracing\」這裏是可寫入的權限;並且這個位置是程序設定的,那就意味着我能夠設定任何位置,如windows\system32下;
十、我來拖幾個文件進去,看看是否能夠寫入,
確實能夠,並且是在windows下。
這意味着:打印操做以SYSTEM特權運行,從而容許它覆蓋OS上任何位置的任何文件。低權限的 test用戶突破了沒法修改系統資源的安全限制。
4、成因
一、打印機工做機制
Windows系統的打印機有兩個核心組件:打印機驅動和打印機端口。
-
打印機驅動
在添加一個打印機時,須要安裝打印機驅動。在MSDN文檔描述中,早期系統要求只有具有SeLoadDriverPrivilege權限的用戶才能安裝打印驅動,但爲了便於標準用戶安裝驅動,從Windows Vista開始,只要打印機驅動是已經存在的可當即使用的驅動,就不須要任何特權便可安裝。例如,經過一條PowerShell命令便可安裝「Generic / Text-Only」驅動。這裏查看一下驅動;
打印機端口
在添加一個打印機時,須要設置打印機的端口。Windows支持多種類型的打印機端口:LPT1端口、USB端口、網絡端口和文件等。若是設置端口爲文件,則意味着打印機將數據打印到指定文件。例如,經過一條PowerShell命令便可添加一個輸出到指定文件的打印端口:
準備好驅動和端口後,經過一條PowerShell命令便可建立一個打印機。就用這個圖代替下,意思同樣,不用懵吧。
一個完整的打印機命令結果圖。
二、脫機打印的機制
在Windows系統上,若是系統配置啓用了假脫機服務,則全部的打印任務都不是當即執行。相反,系統使用Print Spooler來管理脫機打印任務。具體來講,當用戶調用打印操做後,系統將打印做業存儲在特定的假脫機文件夾中。
默認狀況下,Windows生成的脫機打印任務文件爲.SPL文件,此外Windows還會建立後綴名爲.SHD的shadow文件並同SPL文件作關聯。建立shadow文件的用途是:在打印程序出現問題或者打印任務被掛起後,PrintSpooler依然能夠經過SHD文件恢復打印任務。
在Windows系統重啓或Print Spooler服務重啓以後,.SHD和.SPL文件會被從新讀取以恢復打印任務。
三、打印提權的原理
脫機打印機制使得Windows系統在重啓後會恢復可能存在的未執行打印任務。可是,重啓後的Printer Spooler服務程序直接使用了System權限來恢復未執行的打印做業。對於打印機端口爲文件的打印任務,打印文件的寫入也就在System權限下被執行。所以,系統重啓使得脫機打印任務具有了System權限的任意文件寫入能力。
四、Windows系統提供了兩種添加打印機端口的API,分別是AddPort函數和XcvData函數。其中MSDN對AddPort的描述:
「AddPort函數瀏覽網絡以查找現有端口,並彈出對話框供用戶選擇。AddPort函數應該經過調用EnumPorts來驗證用戶輸入的端口名稱,以確保不存在重複的名稱。AddPort函數的調用方必須具備訪問端口所鏈接的服務器的SERVER_ACCESS_ADMINISTER權限。要添加端口而不顯示對話框,可調用XcvData函數而不是AddPort」。
經過控制面板添加打印機在底層是調用了AddPort函數,該函數會觸發spooler程序對端口的合法性校驗。經過PowerShell命令添加打印機在底層則是直接調用XcvData函數,該函數不會觸發spooler程序對用戶添加的端口進行安全校驗。
5、修復補丁
因爲該漏洞能影響衆多的Windows系統版本,並且能夠在標準用戶下發起漏洞攻擊,建議受影響的用戶及時進行系統更新或安裝漏洞補丁。
此外,微軟的安全更新只是對打印端口API進行了更嚴格的校驗。可是,若是惡意文件端口在漏洞修復前已經建立,則漏洞攻擊實際已經生效,此時進行系統更新仍然是不安全的。建議用戶先使用PowerShell命令Get-PrinterPort來檢查系統中是否存在可疑的打印機端口,在刪除可疑端口後再實施系統更新。
研究這個漏洞,花了數個晚上的時間,光寫此文,就整整花了我一中午的時間,約2個半小時。你細細地看完,收穫會很大。
本文分享自微信公衆號 - MicroPest(gh_696c36c5382b)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。