在當今網路安全環境中,攻擊者常使用各種技術探查目標系統,收集使用者帳戶和檔案資訊以利於入侵。本文將探討如何運用 Python 程式碼,在 Windows 系統上進行使用者帳戶和檔案探索,並解析程式碼運作原理。首先,我們會示範如何利用 WMI 模組取得使用者帳戶資訊,包含判斷是否為管理員帳戶以及帳戶狀態。接著,會介紹如何使用 os 模組遍歷檔案系統,並搭配正規表示式搜尋特設定檔案型別和內容,例如 docx 和純文字檔案中的敏感資訊。最後,我們將說明如何透過 Windows 事件記錄檔監控管理員登入嘗試,以提升系統安全性。

使用Python進行使用者帳戶與檔案探索

在網路安全領域中,攻擊者通常會利用各種技術來收集目標環境中的資訊。MITRE ATT&CK框架中的Discovery策略包含了27種不同的技術,用於從目標環境中收集資訊。本章將重點討論如何使用Python來收集使用者帳戶和檔案相關的資訊。

使用者帳戶探索

使用者帳戶的存取對於攻擊者擴充套件其對目標環境的存取許可權至關重要。為了獲得這些帳戶的存取許可權,攻擊者首先需要發現它們的存在並收集足夠的資訊以啟動智慧型攻擊。

收集使用者帳戶資料

在Windows或*nix系統上,關於使用者帳戶的資料並不被視為敏感資訊。任何使用者帳戶都可以收集系統上所有帳戶的高階資訊,這使得攻擊者能夠輕易地收集有價值的資料。

UserDiscovery.py 範例程式碼
import os
import wmi

# 初始化WMI介面
w = wmi.WMI()

# 取得管理員帳戶列表
admins = None
for group in w.Win32_Group():
    if group.Name == "Administrators":
        users = group.associators(wmi_result_class="Win32_UserAccount")
        admins = [a.Name for a in users]

# 列出裝置上的使用者帳戶
for user in w.Win32_UserAccount():
    print(user.Name)

內容解密:

  1. 匯入必要的模組:使用import osimport wmi來匯入作業系統介面和WMI(Windows Management Instrumentation)模組。
  2. 初始化WMI介面:透過w = wmi.WMI()初始化WMI介面,以便與Windows系統進行互動。
  3. 取得管理員帳戶列表:迴圈遍歷Win32_Group物件以尋找名為"Administrators"的群組,並取得該群組中的使用者帳戶列表。
  4. 列出裝置上的使用者帳戶:迴圈遍歷Win32_UserAccount物件以列出系統上的所有使用者帳戶。

檔案與目錄探索

除了收集使用者帳戶資訊外,攻擊者還可能試圖識別目標系統上的有價值資料。

FileDiscovery.py 範例程式碼

import os

# 指定要搜尋的目錄
target_dir = "C:\\Example\\Path"

# 搜尋目錄中的檔案
for root, dirs, files in os.walk(target_dir):
    for file in files:
        print(os.path.join(root, file))

內容解密:

  1. 匯入必要的模組:使用import os來匯入作業系統介面模組。
  2. 指定要搜尋的目錄:定義target_dir變數以指定要搜尋的目錄路徑。
  3. 搜尋目錄中的檔案:使用os.walk()函式遍歷指定目錄及其子目錄中的所有檔案,並列印出每個檔案的完整路徑。

防禦措施

為了防禦上述攻擊技術,系統管理員可以採取以下措施:

  • 限制不必要的使用者帳戶許可權,避免使用高許可權帳戶進行日常操作。
  • 定期審核系統上的使用者帳戶和群組成員資格。
  • 使用監控工具來檢測異常的檔案存取行為。
  • 實施適當的存取控制和加密措施,以保護敏感資料。

使用Python進行Windows使用者帳戶發現與監控

在進行滲透測試或紅隊演練時,瞭解目標系統的使用者帳戶資訊至關重要。本文將介紹如何使用Python指令碼來收集Windows系統中的使用者帳戶資料、識別管理員帳戶、以及監控可疑的帳戶活動。

使用者帳戶發現

首先,我們需要收集目標系統上的使用者帳戶資訊。這可以透過使用wmi模組來實作。以下是一個示例指令碼,用於列出系統上的使用者帳戶及其相關屬性:

import wmi

# 初始化WMI介面
w = wmi.WMI()

# 列出所有使用者帳戶
for user in w.Win32_UserAccount():
    print("使用者名稱:%s" % user.Name)
    print("是否為管理員:%s" % (user.Name in [admin.Name for admin in w.Win32_Group(name='Administrators')[0].associators(wmi_result_class="Win32_UserAccount")]))
    print("帳戶是否停用:%s" % user.Disabled)
    print("網域:%s" % user.Domain)
    print("本地帳戶:%s" % user.LocalAccount)
    print("密碼可變更:%s" % user.PasswordChangeable)
    print("密碼過期:%s" % user.PasswordExpires)
    print("需要密碼:%s" % user.PasswordRequired)
    print("\n")

# 印出Windows密碼策略
print("密碼策略:")
import os
print(os.popen("net accounts").read())

內容解密:

  1. 匯入wmi模組:使用wmi模組與Windows Management Instrumentation (WMI) 介面互動,以取得系統資訊。
  2. 列出使用者帳戶:遍歷Win32_UserAccount類別中的所有使用者帳戶,並印出其屬性,如名稱、是否為管理員、帳戶狀態等。
  3. 檢查管理員許可權:透過查詢Win32_Group類別中的Administrators群組,並使用associators方法取得該群組中的使用者,以判斷某使用者是否具有管理員許可權。
  4. 印出密碼策略:使用os.popen執行net accounts命令,以取得系統的密碼策略資訊。

識別管理員帳戶

識別具有管理員許可權的帳戶對於進一步的攻擊或滲透測試至關重要。上述指令碼已經展示瞭如何檢查使用者是否為管理員。

監控使用者帳戶活動

為了檢測潛在的安全威脅,監控使用者帳戶活動是必要的。以下是一個示例指令碼,用於檢查特定帳戶的最後登入時間:

from subprocess import check_output
import re

def check_last_login(user):
    res = check_output(["net", "user", user])
    logon = re.findall(r"Last logon\s*([^\r\n]+)", res.decode("utf-8"))[0]
    if logon != "Never":
        print("%s 最後登入時間:%s" % (user, logon))

# 定義要監控的帳戶
decoy_accounts = ["tester", "testuser"]
for user in decoy_accounts:
    check_last_login(user)

內容解密:

  1. check_output函式:使用subprocess.check_output執行net user命令,以取得指定使用者的資訊。
  2. 正規表示式解析:使用正規表示式從命令輸出中提取“Last logon”欄位的值,即最後登入時間。
  3. 監控特定帳戶:定義一個包含要監控的帳戶名稱的列表,並對每個帳戶呼叫check_last_login函式,以檢查其最後登入時間。

監控管理員登入嘗試與檔案探索

在進行系統偵察時,瞭解管理員帳戶的登入行為以及系統中敏感檔案的分佈至關重要。本章將探討如何使用Python指令碼監控管理員登入嘗試以及進行檔案和目錄的探索。

監控管理員登入嘗試

Windows事件記錄檔(Event Log)提供了豐富的系統活動資訊,其中事件ID 4672記錄了具有特殊許可權的帳戶登入嘗試。利用Python的win32evtlog模組,可以提取這些事件並分析管理員帳戶的登入行為。

DetectAdminLogin.py 程式碼解析

import win32evtlog

server = "localhost"
logtype = "Security"
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ

def QueryEventLog(eventID, filename=None):
    logs = []
    if not filename:
        h = win32evtlog.OpenEventLog(server, logtype)
    else:
        h = win32evtlog.OpenBackupEventLog(server, filename)
    while True:
        events = win32evtlog.ReadEventLog(h, flags, 0)
        if events:
            for event in events:
                if event.EventID == eventID:
                    logs.append(event)
        else:
            break
    return logs

def DetectAdministratorLogin():
    events = QueryEventLog(4672)
    for event in events:
        if event.StringInserts[0].startswith("S-1-5-21"):
            print("Login attempt by %s at %s" % (event.StringInserts[1], event.TimeGenerated))

DetectAdministratorLogin()

內容解密:

  1. win32evtlog 模組匯入:利用該模組存取Windows事件記錄檔。
  2. QueryEventLog 函式:根據指定的事件ID查詢事件記錄檔中的相關事件。
    • 若未指設定檔案名稱,則開啟本地安全日誌。
    • 使用迴圈讀取所有符合條件的事件,直到沒有更多事件為止。
  3. DetectAdministratorLogin 函式:專門用於檢測管理員登入嘗試。
    • 呼叫QueryEventLog查詢事件ID 4672的事件。
    • 篩選出SID以"S-1-5-21"開頭的事件,這些通常是使用者帳戶而非系統帳戶。
    • 列印出帳戶名稱和登入時間。

檔案與目錄探索

現代企業高度依賴電腦系統,這意味著系統中可能儲存著大量敏感和有價值的資料。攻擊者可能會尋找這些資料用於惡意目的,如資料竊取或勒索軟體攻擊。因此,識別系統中敏感檔案的位置對於防禦者來說至關重要。

FileDiscovery.py 程式碼解析

import os, re
from zipfile import ZipFile

email_regex = '[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}'
phone_regex = '[(]?[0-9]{3}[)]?-[0-9]{3}-[0-9]{4}'
ssn_regex = '[0-9]{3}-[0-9]{2}-[0-9]{4}'
regexes = [email_regex, phone_regex, ssn_regex]

def findPII(data):
    matches = []
    for regex in regexes:
        m = re.findall(regex, data)
        matches += m
    return matches

def printMatches(filedir, matches):
    if len(matches) > 0:
        print(filedir)
        for match in matches:
            print(match)

def parseDocx(root, docs):
    for doc in docs:
        filedir = os.path.join(root, doc)
        with ZipFile(filedir, "r") as zip:
            data = zip.read("word/document.xml")
            matches = findPII(data.decode("utf-8"))
            printMatches(filedir, matches)

def parseText(root, txts):
    for txt in txts:
        filedir = os.path.join(root, txt)
        with open(filedir, "r") as f:
            data = f.read()
            matches = findPII(data)
            printMatches(filedir, matches)

txt_ext = [".txt", ".py", ".csv"]

def findFiles(directory):
    for root, dirs, files in os.walk(directory):
        parseDocx(root, [f for f in files if f.endswith(".docx")])
        for ext in txt_ext:
            parseText(root, [f for f in files if f.endswith(ext)])

directory = os.path.join(os.getcwd(), "Documents")
findFiles(directory)

內容解密:

  1. 正規表示式定義:定義了用於匹配電子郵件、電話號碼和社會安全號碼的正規表示式。
  2. findPII 函式:在給定資料中查詢個人身份資訊(PII)。
    • 使用定義好的正規表示式進行匹配。
  3. printMatches 函式:列印出檔案路徑和匹配到的PII。
  4. parseDocxparseText 函式:分別用於解析.docx檔案和純文字檔案。
    • .docx檔案被視為ZIP壓縮檔處理,讀取其中的document.xml以提取文字內容。
  5. findFiles 函式:遍歷指定目錄及其子目錄,查詢包含PII的檔案。
    • .docx.txt.py.csv等型別的檔案進行解析。