0x00 前言
Powershell命令的歷史記錄有時會包含系統敏感信息,例如遠程服務器的連接口令,運行的PS腳本等各種有價值的信息等等,這裡總結一些滲透測試中常用導出歷史記錄的方法,結合利用思路,給出防禦建議。
0x01 簡介
本文將要介紹以下內容:
- 兩種Powershell命令的歷史記錄
- 導出Powershell命令歷史記錄的方法
- 防禦建議
0x02 兩種Powershell命令的歷史記錄
記錄Powershell命令的歷史記錄有兩種方式,可分別使用Get-History和Get-PSReadlineOption讀取。
1、Get-History
參考文檔:
<code>https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/Get-History?view=powershell-3.0/<code>
默認Powershell v2及以上支持
能夠記錄當前會話中輸入的命令,多個Powershell進程之間不共享,Powershell進程退出後自動清除所有記錄。
a.常用命令
獲得歷史記錄的完整信息:
<code>Get-History | Format-List -Property */<code>
包括:
- Id
- CommandLine
- ExecutionStatus
- StartExecutionTime
- EndExecutionTime
測試如下圖
![滲透技巧---獲得Powershell命令的歷史記錄](http://p2.ttnews.xyz/loading.gif)
刪除所有歷史記錄:
<code>Clear-History/<code>
按ID號刪除命令:
<code>Clear-History -Id 3/<code>
b. 利用思路
獲得了一臺Windows系統的權限,發現後臺有Powershell進程,想要讀取Powershell進程中的歷史記錄
(1)Powershell進程無法接收鍵盤輸入命令
例如Powershell加載了一個在後臺運行的腳本:
<code>Powershell -ep bypass -f 1.ps1/<code>
此時無法向Powershell進程發送鍵盤消息,這時可以通過讀取進程的命令行參數獲得有用的信息,開源代碼:
<code>https://github.com/3gstudent/Homework-of-C-Language/blob/master/GetProcessCommandLine.cpp/<code>
代碼實現了讀取指定進程的命令行參數,通常能夠獲得有用的信息
(2)Powershell進程能夠接收鍵盤輸入命令
這裡可以模擬發送鍵盤消息,導出歷史記錄
程序實現思路:
- 通過遍歷枚舉所有窗口
- 通過GetWindowThreadProcessId從窗口(HWND)獲得PID
- 比較PID,找到符合條件的窗口
- 向符合條件的窗口發送鍵盤消息(PostMessage)
程序細節:
1.Virtual-Key Codes
每一個鍵盤輸入消息對應一個Virtual-Key Code
<code>https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes/<code>
需要模擬鍵盤按下和鍵盤抬起兩個操作,開源的測試代碼:
<code>https://github.com/3gstudent/Homework-of-C-Language/blob/master/SendKeyboardMessageToPowershell.cpp/<code>
代碼實現了搜索指定pid的進程,向進程發送鍵盤消息,內容為:whoami
2.導出歷史記錄
命令如下:
<code>Get-History|export-csv $env:temp"\\history.csv"/<code>
其中需要考慮字符"|"、"$"和""",模擬鍵盤輸入時需要加Shift鍵
這裡的實現方法是先使用keybd_event按下Shift鍵,再用PostMessage發送按鍵的字母,最後抬起兩個按鍵
開源的測試代碼:
<code>https://github.com/3gstudent/Homework-of-C-Language/blob/master/SendKeyboardMessageToPowershell(Get-History).cpp/<code>
代碼實現了搜索指定pid的進程,向進程發送鍵盤消息,內容為:
<code>Get-History|export-csv $env:temp"\\history.csv"/<code>
c. 補充:查看cmd.exe的歷史記錄
命令如下:
<code>doskey /h/<code>
清空:
<code>doskey /reinstall/<code>
也可以通過發送鍵盤消息的方式導出cmd.exe的命令歷史記錄
2、Get-PSReadlineOption
參考文檔:
<code>https://docs.microsoft.com/en-us/powershell/module/psreadline/?view=powershell-5.1/<code>
默認Powershell v5支持
Powershell v3和Powershell v4需要安裝Get-PSReadlineOption後才可以使用
安裝後,所有Powershell命令的歷史記錄會保存在同一位置,可隨時查看
1. Powershell v3和Powershell v4的安裝和使用
這裡以64位系統為例,安裝方法如下:
(1)安裝PowerShellGet
下載:
<code>https://www.microsoft.com/en-us/download/details.aspx?id=51451/<code>
注:
安裝前需要關閉powershell進程
可以通過命令行實現隱蔽安裝,命令如下:
<code>msiexec /q /i PackageManagement_x64.msi/<code>
安裝成功後,在控制面板的已安裝程序列表(Control Panel\\Programs\\Programs and Features)有顯示:Package Management Preview - x64
可以通過刪除對應的註冊表項進行隱藏
Package Management Preview - x64的註冊表路徑為HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{57E5A8BB-41EB-4F09-B332-B535C5954A28}
只需要刪除這個註冊表項及子項即可實現在已安裝程序列表中隱藏
刪除註冊表項的cmd命令:
<code>reg delete HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{57E5A8BB-41EB-4F09-B332-B535C5954A28} /f/<code>
(2)安裝PSReadLine
通過Install-Module命令安裝
<code>Install-Module -Name PSReadLine/<code>
彈出提示:
<code>NuGet provider is required to continuePowerShellGet requires NuGet provider version '2.8.5.201' or newer to interactwith NuGet-based repositories. The NuGet provider must be available in'C:\\Program Files\\PackageManagement\\ProviderAssemblies' or'C:\\Users\\Administrator\\AppData\\Local\\PackageManagement\\ProviderAssemblies'.You can also install the NuGet provider by running 'Install-PackageProvider-Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet toinstall and import the NuGet provider now?[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"):/<code>
需要再次輸入Y進行安裝
如果需要實現一鍵安裝,可以先安裝NuGet,再安裝PSReadLine,完整命令如下:
<code>Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -ForceSet-PSRepository -Name PSGallery -InstallationPolicy TrustedInstall-Module -Name PSReadLine/<code>
(3)使用
所有powershell命令將會保存在固定位置:%appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt
查看命令的歷史記錄:
<code>Get-Content (Get-PSReadlineOption).HistorySavePath/<code>
清除命令的歷史記錄:
<code>Remove-Item (Get-PSReadlineOption).HistorySavePath/<code>
2. 利用思路
獲得了Windows系統的訪問權限,首先查看Powershell版本,如果是v5,可通過讀取文件%appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt獲得歷史記錄
如果系統是Powershell v3或Powershell v4,可通過命令行安裝PSReadLine,這樣就能記錄後續系統所有的Powershell命令
0x03 防禦建議
如果使用高版本的Windows系統,如Win10,默認Powershell版本為5.0,會記錄Powershell的命令,建議定時進行清除,位置:%appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt
清除命令的歷史記錄:
<code>Remove-Item (Get-PSReadlineOption).HistorySavePath/<code>
對於低版本的Powershell,如果命令中包含敏感信息(如遠程連接的口令),需要及時清除,命令為:Clear-History
對於cmd.exe,如果命令中包含敏感信息(如遠程連接的口令),需要及時清除,命令為:doskey /reinstal
閱讀更多 KillBoy安全實驗室 的文章