Volatility 作為一款開源記憶體取證框架,在資安事件調查和惡意軟體分析中扮演著關鍵角色。藉由分析系統記憶體,Volatility 能夠揭示執行中程式、網路連線以及潛在的惡意活動。本文將探討如何應用 Volatility 的 malfind 和 netscan 外掛來識別系統中的可疑行為,例如具有讀寫執行許可權的記憶體區域和異常的網路連線。此外,文章還將示範如何開發一個自訂 Volatility 外掛,用於檢查 Windows 程式是否正確地啟用了地址空間佈局隨機化(ASLR)安全機制,進一步強化系統的防禦能力,避免遭受惡意程式碼攻擊。

恆發現與利用脆弱性

在資安領域中,恆發現與利用目標虛擬機器(VM)中的脆弱性是一項關鍵任務。為了達成這個目標,我們可以使用 Volatility 工具來分析目標 VM 是否存在可被利用的脆弱性。Volatility 提供了多種外掛,其中 malfind 外掛可以檢查程式記憶體範圍,以查詢可能包含注入程式碼的區域。這些區域通常具有讀取、寫入和執行的許可權,因此值得進一步調查,因為它們可能已經包含了某些已知的惡意軟體,或者我們可以將我們自己的惡意軟體覆寫到這些區域。

應用 malfind 外掛

以下是使用 Volatility 的 malfind 外掛來檢查目標 VM 中的潛在脆弱性的範例:

PS>vol -f WinDev2007Eval-7d959ee5.vmem windows.malfind

在這個指令中,Volatility 會掃描目標 VM 的記憶體映像檔,並列出具有讀取、寫入和執行許可權的記憶體範圍。以下是輸出結果的一部分:

Volatility 3 Framework 1.2.0-beta.1
Progress: 33.01 Scanning primary2 using PdbSignatureScanner
PID Process Start VPN End VPN Tag Protection CommitCharge
1336 timeserv.exe 0x660000 0x660fff VadS PAGE_EXECUTE_READWRITE 1
2160 MsMpEng.exe 0x16301690000 0x1630179cfff VadS PAGE_EXECUTE_READWRITE 269
2160 MsMpEng.exe 0x16303090000 0x1630318ffff VadS PAGE_EXECUTE_READWRITE 256
2160 MsMpEng.exe 0x16304a00000 0x16304bfffff VadS PAGE_EXECUTE_READWRITE 512

內容解密:

  • 程式 ID(PID):每個程式都有一個唯一的 PID,這裡列出了幾個程式,例如 timeserv.exeMsMpEng.exe
  • 程式名稱:這是程式的名稱,例如 timeserv.exeMsMpEng.exe
  • 起始虛擬位址(Start VPN)和結束虛擬位址(End VPN):這些是記憶體範圍的起始和結束位址。
  • Tag:表示記憶體區域的標籤。
  • Protection:表示記憶體區域的保護屬性,例如 PAGE_EXECUTE_READWRITE
  • CommitCharge:表示記憶體區域的提交負荷。

從這些結果中,我們發現了幾個具有讀取、寫入和執行許可權的記憶體範圍。例如,timeserv.exeMsMpEng.exe 都有多個這樣的記憶體範圍。

分析潛在問題

首先,我們需要了解這些程式是否真的是合法軟體。例如,timeserv.exe 是 FreeDesktopClock 的一部分,而 MsMpEng.exe 是 Windows 防毒服務。雖然這些程式通常是合法的,但如果它們被安裝在不正常的位置(例如不在 C:\Program Files),則可能是惡意軟體。此外,即使它們是合法的,我們也可以考慮將殼程式碼(shellcode)寫入這些記憶體區域,以使它們變得危險。

應用 netscan 外掛

接下來,我們可以使用 Volatility 的 netscan 外掛來列出目標 VM 在快照時間點所建立的所有網路連線。這些連線可能會提供一些攻擊的線索。以下是使用 netscan 外掛的範例:

PS>vol -f WinDev2007Eval-7d959ee5.vmem windows.netscan

以下是輸出結果的一部分:

Volatility 3 Framework 1.2.0-beta.1
Progress: 33.01 Scanning primary2 using PdbSignatureScanner
Offset Proto LocalAddr LocalPort ForeignAdd ForeignPort State PID Owner
...

內容解密:

  • Offset:記錄條目的偏移地址。
  • Proto:網路協定型別,例如 TCPv4。
  • LocalAddr 和 LocalPort:本地主機和埠號。
  • ForeignAdd 和 ForeignPort:遠端主機和埠號。
  • State:連線狀態,例如 LISTENING 或 CLOSED。
  • PID 和 Owner:程式 ID 和程式名稱。

從這些結果中,我們可以看到一些 LISTENING 的連線。例如,nc64.exe 是一個未知的程式,它正在監聽埠 4444。這值得深入調查。此外,我們也看到一些已經關閉的連線,這些可能沒有太大價值。

volshell 介面

除了命令列介面之外,Volatility 還提供了一個 volshell 介面,這是一個自訂 Python shell。它結合了 Volatility 的強大功能和完整的 Python shell 功能。以下是使用 volshell 介面來分析 Windows 快照檔案的一個範例:

PS> volshell -w -f WinDev2007Eval-7d959ee5.vmem

內容解密:

在 volshell 中,我們可以像使用一般 Python shell 一樣來操作 Volatility 外掛。例如:

>>> from volatility.plugins.windows import pslist
>>> dpo(pslist.PsList, primary=self.current_layer, nt_symbols=self.config['nt_symbols'])

自訂 Volatility 外掛

除了使用 Volatility 提供的外掛之外,我們還可以編寫自己的自訂外掛來滿足特定需求。Volatility 提供了簡單易用的框架來建立外掛。只要遵循它們的模式,我們就可以建立自己的外掛來分析特定情況下需要的資訊。

預測未來趨勢

隨著技術不斷演進及攻擊者技巧日益精湛,未來 Volatility 或其他數位取證工具將需要更加智慧化及自動化以應對複雜且高度隱蔽化之威脅行為進行分析與追蹤。除此之外與其相關之資安技術如雲端防護、人工智慧驅動之安全自動化系統及零信任架構將會成為應對威脅之重要關鍵技術。

玄貓認為隨著資料洩漏事件日益頻繁及攻擊者手法複雜多樣化之情況下 ,未來資安專業人員將需要更高層次之綜合分析能力及數位取證技術以進行有效之威脅偵測及回應。

網路連線監控及分析

在進行網路安全監控時,「此圖示」展示瞭如何透過監控特定網路連線狀態以瞭解系統之安全健康狀況。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Volatility 脆弱性分析與 ASLR 保護檢測

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

內容解密:

「此圖示」說明瞭本地系統與內部/外部網路之間存在著多種 TCP 操作情況:監聽中之 TCP 聯絡即可能為未知應用程式「nc64.exe」,此情況值得注意;而大部分已關閉之聯絡則代表為非即時風險來源。

總結而言,「此圖示」強調對異常網路行為之監控及追蹤對於維持系統安全至關重要。「此圖示」所展示出之詳細情報有助於快速識別並應對潛在安全問題。「此圖示」邏輯清晰地呈現了不同元素間之關係及流向並幫助使用者輕易理解每一步驟重要性及相互依賴關係。「此圖示」同時支援透過視覺化方式去分析安全事件並提供後續行動參考指引。「此圖示」中的每個節點皆有其特定功能及目的且其相互聯絡促使系統保持完整性及穩定性。

再次強調,「此圖示」強調了針對異常網路行為進行盯梢與跟蹤以維持系統安全狀態至關重要,「此圖示」所展示出詳細資料有助於快速辨認並回應潛在安全事件。「此圖示」藉由視覺化方式幫助分析安全事件並提供後續操作指引。「此圖示」清晰地顯示不同元素間互動流向以便理解每一步驟重要性與彼此間依賴關係。「此圖示」支援透過視覺化方式去分析安全事件並提供後續行動參考指引。

最終,「此圖示」顯示每個節點皆具有特定功能與目的其相互聯絡促使系統保持完整性與穩定性以確保整體運作正常與安全無虞。」

分析 Windows 程式是否啟用地址空間佈局隨機化(ASLR)

Windows 的地址空間佈局隨機化(Address Space Layout Randomization,ASLR)是一種重要的安全技術,用於提升系統的防護能力。ASLR 會隨機化程式的虛擬記憶體位置,包括堆積、堆疊以及其他作業系統分配的資源。這樣可以有效地增加攻擊者成功利用漏洞的難度。在本文中,玄貓將介紹如何開發一個自訂外掛,以檢查 Windows 系統中的程式是否啟用了 ASLR。

機器碼及架構概述

首先,讓我們來看一下一個典型外掛的框架:

imports ...  # 必要的模組匯入

class CmdLine(interfaces.plugin.PluginInterface):
    @classmethod
    def get_requirements(cls):
        pass  # 定義外掛的需求

    def run(self):
        pass  # 主要執行邏輯

    def generator(self, procs):
        pass  # 生成器方法,可選但建議使用

這個框架包含了建立新類別、定義外掛需求、實作主執行邏輯以及生成器方法等幾個主要步驟。生成器方法是可選的,但將其與主執行邏輯分離可以使程式碼更易理解並提升效能。

自訂外掛:檢查 ASLR 保護

接下來,玄貓將根據這個框架,開發一個自訂外掛來檢查 Windows 程式是否啟用了 ASLR。

函式庫匯入與預備工作

首先,我們需要匯入必要的模組和函式庫:

from typing import Callable, List
from volatility.framework import constants, exceptions, interfaces, renderers
from volatility.framework.configuration import requirements
from volatility.framework.renderers import format_hints
from volatility.framework.symbols import intermed
from volatility.framework.symbols.windows import extensions
from volatility.plugins.windows import pslist
import io
import logging
import os
import pefile

vollog = logging.getLogger(__name__)
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040
IMAGE_FILE_RELOCS_STRIPPED = 0x0001

這些模組和函式庫將幫助我們分析可攜式執行檔(PE)檔案並檢查其是否啟用了 ASLR。

助手函式:檢查 ASLR 保護

接著,玄貓將定義一個助手函式 check_aslr,用來檢查給定的 PE 檔案是否啟用了 ASLR:

def check_aslr(pe):
    pe.parse_data_directories([
        pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG']
    ])
    dynamic = False
    stripped = False
    if (pe.OPTIONAL_HEADER.DllCharacteristics &
        IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE):
        dynamic = True
    if pe.FILE_HEADER.Characteristics & IMAGE_FILE_RELOCS_STRIPPED:
        stripped = True
    if not dynamic or (dynamic and stripped):
        aslr = False
    else:
        aslr = True
    return aslr

這個函式會解析 PE 檔案並檢查其是否具有動態基址設定以及相關位元資訊。如果 PE 檔案不具有動態基址設定或被剝離了重定位資料,則認為該檔案未啟用 ASLR。

自訂外掛類別:AslrCheck

現在,玄貓將定義 AslrCheck 類別,這是我們的自訂外掛:

class AslrCheck(interfaces.plugins.PluginInterface):
    @classmethod
    def get_requirements(cls):
        return [
            requirements.TranslationLayerRequirement(
                name='primary', description='Memory layer for the kernel',
                architectures=["Intel32", "Intel64"]),
            requirements.SymbolTableRequirement(
                name="nt_symbols", description="Windows kernel symbols"),
            requirements.PluginRequirement(
                name='pslist', plugin=pslist.PsList, version=(1, 0, 0)),
            requirements.ListRequirement(name='pid',
                                        element_type=int,
                                        description="Process ID to include (all others are excluded)",
                                        optional=True),
        ]

這段程式碼定義了外掛的需求,包括記憶體層、符號表以及其他必要的外掛和設定。

建立過濾器函式

為了處理可選的程式 ID,玄貓定義了一個過濾器函式:

@classmethod
def create_pid_filter(cls, pid_list: List[int] = None) -> Callable[[interfaces.objects.ObjectInterface], bool]:
    filter_func = lambda _: False
    pid_list = pid_list or []
    filter_list = [x for x in pid_list if x is not None]
    if filter_list:
        filter_func = lambda x: x.UniqueProcessId not in filter_list
    return filter_func

這個過濾器函式會根據給定的程式 ID 清單來過濾程式。

生成器方法

最後,玄貓定義了生成器方法 _generator

def _generator(self, procs):
    pe_table_name = intermed.IntermediateSymbolTable.create(
        self.context,
        self.config_path,
        "windows",
        "pe",
        class_types=extensions.pe.class_types)
    procnames = list()
    for proc in procs:
        procname = proc.ImageFileName.cast("string",
                                           max_length=proc.ImageFileName.vol.count, errors='replace')
        if procname in procnames:

這段程式碼會遍歷所有程式並重建其 PE 檔案,然後檢查每個 PE 檔案是否啟用了 ASLR。

內容解密:

在這段程式碼中,玄貓匯入了必要的模組和函式庫,並定義了一個助手函式 check_aslr 用來檢查 PE 檔案是否啟用了 ASLR。接著,玄貓建立了一個自訂外掛類別 AslrCheck,並在其中定義了外掛的需求、過濾器函式以及生成器方法。這些步驟確保我們可以有效地檢查 Windows 程式是否啟用了 ASLR。

這樣的一個自訂外掛不僅能夠幫助安全研究人員分析系統中的安全狀況,還能夠提供更深入的技術洞察。透過詳細的分析和實務經驗的結合,玄貓能夠提供更具體且實際的技術解決方案。