Windows注冊表運行鍵安全攻防指南
Windows注冊表是一個龐大而復雜的話題,因此,我們根本不可能通過一篇文章講清楚。然而,從安全的角度來看,一個特別值得關注的領域是注冊表運行鍵。在這篇文章中,我們將探討誰在使用運行鍵,如何發現該鍵的濫用情況,以及如何根除系統中的惡意運行鍵。
運行鍵簡介
什么是注冊表運行鍵?運行鍵是注冊表的一種開機運行機制:當用戶登錄或機器啟動時,在Windows系統上執行一些程序。
由于運行鍵很容易引發安全問題,所以,它自然會成為攻擊者的研究對象。例如,Fancy Bear(也被稱為APT28)、TA456和Group 123都喜歡用運行鍵來實現對被攻擊網絡的權限維持。同時,運行鍵還可以包含各種形式的惡意內容——從簡單的可執行文件到充滿宏代碼的電子表格。
MITRE ATT&CK將這種特殊的權限維持戰術記為子技術T1547.001。在入侵活動中,雖然這種技術并不常見,然而它卻可以實現權限維持——因此,我們更有理由進一步探索這種“默默無聞”的技術。

雖然高級攻擊者偶爾會利用運行鍵,但我發現,關于這種機制的探討卻非常少見。實際上,之所以很少有文章討論這種注冊表功能,并不是因為整個信息安全社區的技術差距。相反,運行鍵是Windows注冊表“配置數據庫”的一個不太引人注目的可執行組件。這意味著與更強大、更知名的攻擊技術和操作系統組件相比,它們往往沒有得到同等程度的關注。然而,我最近在信息安全社交圈中看到了下面的討論:

在我們介紹如何檢測惡意運行鍵之前,讓我們先來簡單聊一下Windows注冊表。
Windows注冊表
Windows注冊表是一個迷宮般的系統。從表面上看,它是一個集中式數據庫,用于存儲與用戶和機器設置有關的信息。不過現實情況卻是,它更像是一個由古怪和奇妙的功能組成的系統;盡管這些功能具有破壞性的潛力,但是,微軟對這些功能的說明并不詳盡。
我可以花幾個小時的時間,來講述關于Windows注冊表的不一致性和反復無常。同時,試圖了解其潛力的限制和參數確實會令人抓狂。但是,注冊表的雜亂無章的特性,貌似對攻擊者特別有利,因為這便于藏匿其權限維護機制,并在網絡外潛伏,直到藍隊轉移視線。
通常情況下,要想區分windows注冊表中哪些是良性的,哪些是惡性的,通常是不可能的,特別是在安全事件發生時。
運行鍵
我希望到目前為止,我已經講清楚了馴服注冊表是多么的困難。更糟糕的是,微軟對運行鍵的功能的介紹,也是少的令人發指,因為他們只用了六段話來描述運行鍵。
運行鍵存在于注冊表中。它們是可配置的,當用戶登錄或開機時,允許一個程序執行。“但是等一下!”,我聽到你憤怒地喊道,“Windows已經有一個任務調度器,這就是你安排任務的方式!!!”
不過,與Windows的任務調度器相比,運行鍵還是有一些重要的區別的,或者說它的功能更加有限。

與Windows任務調度器相比,注冊表運行鍵具有下列特點:
字符限制
運行鍵只能存儲少于280個字符的命令。因此,攻擊者的one-liner命令的字符數不能超過這個限制。我希望微軟并不是想以此作為一種底層的防御機制,因為腳本小子的許多反向shell的長度都少于50個字符。

此外,如果編譯惡意可執行文件并通過運行鍵執行的話,只需用到很少的字符,卻能達到最大的效果。因此,盡管與其他系統防御機制相比,字符限制是獨特的,但其作用是微不足道的。
特殊字符的行為
運行鍵的另一個特性是,特殊字符可以改變被調度命令的行為,尤其是感嘆號(!)和星號/通配符(*)。在默認情況下,運行鍵在執行后會自我刪除——無論任務的執行是否成功。這兩個特殊字符可以用來改變這一行為。
當您將來處理事件響應時,如果看到一個感嘆號,說明很可能遇到了一個運行鍵:它將持續存在,直到運行完指定的命令。如果由于某種原因,這個邪惡的命令沒有運行,感嘆號能夠確保它不會刪除自己,直到它運行成功為止。

我們可以通過在安全模式下引導計算機來消除運行鍵的前綴感嘆號。為了確保無論啟動模式如何都能執行運行鍵,攻擊者可以利用星號/通配符強制命令運行。

默認情況下,運行鍵被配置為在運行后自行擦除,這意味著除非您仔細檢查日志記錄,否則這些惡意活動很可能會被忽視。
圍獵運行鍵

這是您現在的表情嗎?反正這是我第一次遇到運行鍵時的表情。說實話,這種表情一直持續至今。
雖然運行鍵可能看起來很復雜和晦澀,但我向你保證它們并不復雜。它們非常引用檢測和監控,而且當攻擊者操縱它們的值時,它們會在SIEM中顯示得非常清楚,這一點會在下面看到。
尋找運行鍵
有許多地方可以部署惡意的運行鍵。我們只是要關注前四個位置,但如果你閱讀一些紅隊的文檔,就會發現還有更多的注冊表位置可以實現運行鍵的持久性。
總之,在Windows注冊表中,只需在HKey Local Machine和Current User目錄下尋找,只需越過幾個目錄,就能找到Run和RunOnce。
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
"HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
"HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
目錄在這里很重要,因為運行鍵的行為取決于它所在的注冊表位置:
如果被寫入到HKLM:\的話,這意味著這是作為一個高權限用戶(很可能是管理員)或SYSTEM寫入的。
寫在這里的運行鍵可以在機器啟動時執行。
如果被寫入到HKCU:\中的話,這意味著這只是作為一個普通用戶寫入的。
寫在這里的運行鍵只有在用戶登錄時才會執行。
如果被寫入到\RunOnce的話,它將在執行后被刪除。
如果被寫入到\Run的話,它在執行后并不會被刪除。
這些都會因為我們已經討論過的特殊字符行為而變得愈加復雜。
運行鍵在現實生活中是什么樣子的?
在現實生活中,我們必須從注冊表過濾掉一些噪音后,才能看到運行鍵的內容。下面我們舉例說明,第一個例子是沒有經過PowerShell的過濾,第二個例子則通過PowerShell進行了相應的過濾。
看看這一團糟。這到底是什么?我們根本就不需要紅框中的東西,那些只是噪音。事后看,我們知道這里表示“HKLM”驅動器和“Run”ChildName,但是,乍一看,的確是一言難盡……

下面,讓我們利用PowerShell過濾掉這些噪音:
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" | select -property * -exclude PS* | fl

看看這有多優雅。想象一下,如果能夠通過類似方式讓數以千計的端點以這種清晰、無噪音的方式返回信息,這簡直就是藍隊的夢想。這種用于過濾的PowerShell非常適合在企業范圍內運行,以識別網絡中標準構建之外的異常。
如果看一下運行鍵,就會發現條目的名稱和附帶的命令。不過,運行鍵的合法內容可能有所不同,我們需要了解企業中什么東西是正常的,因為這樣才能知道哪些東西是不正常的。
在進行安全審計時,有時需要過濾掉注冊表運行鍵中合法的啟動項目。這其實很容易做到。為此,只需使用與上述相同的PowerShell,不過這次需要加上-exclude
標志,然后是需要排除的PS*,后面加上一個逗號,以及其他不想看到的運行鍵名稱。
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" | select -property * -exclude PS*, Vmware*,bginfo* | fl

惡意的運行鍵
下面,讓我們模仿一下攻擊者的一些行為。我們將在一個運行鍵中插入一些惡意的東西,同時,我將向您展示:
第一,如何通過循環方式自動找到它。
第二,如何在不破壞其他合法運行鍵的情況下將其從機器上清除。
假設我們已經入侵了一臺機器,并希望在這臺機器上面維持相應的權限。為此,我們編譯了evilcommand.exe,它能夠繞過人類已知的所有反病毒軟件,并向我們一個反向shell。我們可以命令其中一個運行鍵來執行我們的惡意程序:
Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name '!Delete After Running' -Value "evilcommand.exe"
如果我們能夠在單行Powershell命令的末尾加上-whatif,它就不會真正運行你的命令。相反,它將向您顯示如果您運行它會產生什么效果。

當您想真正運行一些命令時,請使用-verbose標簽。

這就是我們強制運行鍵為我們做的事情:創建了一個名為“Delete_After_Running”的運行鍵,其執行值為“evilcommand.exe”。注意前面這個感嘆號,正如我們已經討論過的,它將確保程序在自我刪除之前運行,以歡迎我們再次光顧這臺被入侵的機器。

任務調度器不會注意到這一點。它不會也無法識別這個運行鍵已被調度。如果我是微軟,我可能會在任務調度器中加入這一功能……

如何尋找惡意的運行鍵
利用Powershell的for循環,我們可以收集上述四個注冊表位置的內容。
在構思這個腳本時,我設法通過確保代碼產生的輸出被預先過濾并添加顏色,以便于辨認是否存在異常的東西及其所在的位置。


如果我們看得足夠仔細,就會發現一些異常情況。一旦我們取得可執行文件并對其進行逆向分析,我們就可以確定它是否是來自攻擊者的惡意可執行文件。

如果發現惡意的運行鍵,那么就需要將它從機器上刪除,具體方法將在后面介紹。
監測惡意運行鍵的行為
讓我們從檢測和監控的角度討論一下惡意運行鍵的行為。
在這里,我們將使用內置的Windows事件查看器,并為Sysmon和Florian Roth配置相應的規則來檢測惡意的運行鍵。然后,你可以將這些Sysmon日志數據輸入SIEM,并監控數十萬個端點的運行鍵惡意行為(以及其他東西)。

這里有大量的信息需要考察:
藍色的箭頭:事件信息
事件ID 13涉及注冊表值的修改,這個ID在任何環境下都是一致的。
EventType和Task Category也準確地指出了這里發生的事情:一個注冊表值正在被設置。
紅色箭頭:具體信息
TargetObject顯示了我們正在改變的運行鍵注冊表的完整路徑。它還顯示了我們給它起的名字,并包括改變行為的特殊字符
Details部分顯示了運行鍵強制執行的命令/可執行文件
粉紅色的箭頭:MITRE ATT&CK參考
這個可能不是在每個symon配置中都有。然而,Florian Roth將MITRE ATT&CK戰術編號列入了某個事件中。
與其為每個Event 13生成攻擊警報,我建議你去了解一下環境中的運行鍵通常做什么。
在整個企業中,它們是否有一致的內容?
還是財務部門運行的軟件合法地改變了運行鍵?
你是否能夠以這個為基準,然后為財務部門的工作站的任何新的、不一致的運行鍵變化創建一個小警報?
這比從一百萬個事件中抓住一個流氓Event 13更有價值。
交互式檢測
如果您想獲得更多的交互式檢測體驗,我會推薦使用Michael Cohen博士的Velociraptor這樣的工具。
Velocitaptor是一個非常棒的工具,但是,我們這里只做簡單的介紹。總的來說,Velociraptor就是一個端點響應代理,我們可以把它安裝到企業中的所有端點上,并通過運行在服務器上的Web應用對其進行協調。這種分布式工具使我們能夠同時查詢成千上萬的機器。
Velociraptor內置了一個搜索功能,專門查詢每臺Windows機器的啟動過程,而這個搜索功能的一部分就包括查詢運行鍵。正如你所看到的,這個搜索功能的目標就是一些注冊表的運行鍵。此外,Velociraptor的目標還有另外幾個運行鍵,以及其他一些啟動位置。

如果我們啟動了這個啟動檢測搜索,我們將得到一個格式優美的結果表。在真實的生產環境中,你會發現噪音會更多一些,所以請注意!現在,看看我們檢測到了什么:域中的一臺機器正在運行C:\evil.exe,這個名字真是太嚇人了。

幸運的是,現在我們已經找到了惡意的運行鍵,不僅如此,我們還可以從主機中刪除它。
鏟除惡意運行鍵
現在,是時候鏟除惡意的運行鍵了。

下面,我們開始外科手術。如果使用的命令不夠精確,則會意外地刪除合法的運行鍵。重要的是,這里也要用-verbose完成刪除操作,并仔細檢查它是否已經消失,以確保刪除對象的確已經被清除了。
在PowerShell的for語句的后面,復制并粘貼前面檢測到的惡意運行鍵的完整路徑,并再次檢查確認。
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" | select -property * -exclude PS*| fl

然后,選擇要刪除的運行鍵的確切名稱,然后復制粘貼該名稱。注意,這里必須包括相應的特殊字符,但是,不要復制冒號后面的可執行文件的詳細數據。
Remove-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "*Run Safe Mode too" -verbose

這樣,就會返回詳盡的消息,以確認刪除的的確是我們的目標運行鍵。

然后,讓我們再檢查一下,以確認它的確已經被清除。如果這里還有惡意運行鍵的話,請仔細檢查復制和粘貼的內容是否正確,因為發生誤操作也不是不可能的事情。
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" | select -property * -exclude PS*| fl

撥開運行鍵的迷霧
運行鍵是一種非常晦澀難懂的權限維持機制。但我希望這篇文章能讓我們對監視、檢測、控制和清除涉及運行鍵的任何惡意活動有所幫助。
作為一個防御者,許多時候我們的角色與入侵者相比一直處于劣勢。他們可以利用zero-day漏洞,他們可以欺騙用戶,他們可以用更大的預算跨時區運行。所以,這就要求我們進行全方位的防護,但對他們來說,只需要拿下一個突破口就行了。所有這些都是真實不虛的,但我發現有時我們可以把這種觀點顛倒一下,把重點放在我們與攻擊者相比所擁有的優勢上。
環境是我們的,注冊表是我們的,運行鍵也是我們的。同時,我們知道這一切是如何運作的,我們應該在這里等待對手在我們的領域里打噴嚏。雖然這是我們的地盤,但我們并不天真,我們有時候的確會被攻陷。但是,我們會抓住入侵者,把他們踢出去,并提高入侵難度。

了解您的環境中什么是正常的,這樣您就可以知道注冊表運行鍵操作何時不合適,并培植一個對抗性的網絡,讓攻擊者寸步難行。
小結
當然,還有許多其他古怪的注冊表項,它們可以通過運行鍵做一些奇怪的事情。例如,我們沒有提到整個文件夾是如何通過注冊表運行鍵實現權限維護的!