滲透技巧---獲得Powershell命令的歷史記錄

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命令的歷史記錄

刪除所有歷史記錄:

<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



分享到:


相關文章: