2023 - 2nd CDEF Bulletin
  • Cover
  • Kata Pengantar
  • Daftar Isi
  • Cyber-horizon
    • Menulis Plugin Volatility 3 Pertamamu
    • Demam “slot-gacor” dan Evolusinya
    • Building Digital Fortresses: The Important Role of Security Hardening in Cyber Defense
    • 1-syslogpro: One-Way System Log Protection untuk Melindungi Log Sistem
    • A Malicious Activity Leads to Cyberattack Ransomware
    • Analisis Pengaruh Komponen Malicious PDF terhadap Deteksi Antivirus
    • Pemantauan Informasi Sensitif dan Rahasia Secara Otomatis pada Slack
    • Integrasi UU PDP pada Secure Software Development Life Cycle (Secure SDLC)
  • DUKUNGAN KOMUNITAS
    • Dukungan Komunitas
  • KUNJUNGI SOSIAL MEDIA KAMI
    • Kunjungi Sosial Media Kami
  • Tim Redaksi
Powered by GitBook
On this page
  • Referensi
  • Tentang Penulis
  1. Cyber-horizon

Menulis Plugin Volatility 3 Pertamamu

oleh Rifqi Ardia Ramadhan

PreviousDaftar IsiNextDemam “slot-gacor” dan Evolusinya

Last updated 1 year ago

Volatility adalah sebuah tools forensik yang terkenal akan kemampuannya untuk memproses hasil dump memory agar dapat mengambil suatu informasi terkait device asal memory dump tersebut diambil. Volatility 2 seringkali jadi pilihan utama ketika menganalisis memory, dikarenakan luasnya penggunaan tools versi ini. Namun demikian, Volatility 2 menuju senja – alias uzur – bersamaan dengan dihentikannya support untuk Python 2, sehingga mulai banyak yang melakukan migrasi ke Volatility 3 yang didasarkan pada Python 3. Dengan peningkatan performa dan standarisasi model plugin yang lebih efisien, membuat plugin untuk Volatility 3 tidak akan serumit versi sebelumnya. Di sini, kita akan mencoba untuk membuat plugin Volatility 3 sederhana dalam upaya memahami cara kerja plugin, dengan harapan dapat membuat plugin yang lebih kompleks dan bisa dimanfaatkan oleh seluruh pengguna Volatility 3.

Sebelum memulai, dibutuhkan keahlian dasar pemrograman Python 3 – tentu saja karena Volatility 3 dibuat di atas Python 3, jadi plugin juga berdasarkan pemrograman tersebut. Hal kedua yang dibutuhkan adalah sampel memory dari mesin Windows. Opsi IDE yang digunakan bisa menggunakan apapun, namun di sini kita akan menggunakan VS Code.

Dalam artikel ini kita akan membuat plugin Volatility 3 untuk sistem operasi versi Windows agar mempermudah anda untuk mengikuti proses dalam tutorial ini dan memiliki lingkungan yang sama (dikarenakan sistem operasi non-Windows perlu menyertakan versi sistem operasi yang unik dan mengambil sampel kernel debugging yang belum tentu ada di tiap versi kernel).

Kita akan membuat plugin sederhana yang membuat daftar proses dan PID yang ada di dalam memory dump.

  1. Langkah pertama adalah membuat file .py di dalam folder volatility3/plugins/windows. Nama ini akan menjadi parameter yang dipanggil ketika menggunakan plugin, jadi usahakan sama dengan nama Class untuk memudahkan identifikasi saat pengembangan plugin. Kita coba buat file testing.py.

  1. Kemudian di dalam file .py tersebut, buat sebuah class yang menurunkan dari interface PluginInterface. Pastinya plugins tidak di-recognize oleh Python, jadi kita perlu melakukan import terhadap plugins di volatility3.framework.interfaces. Kita namakan class tersebut Testing, karena kita sedang mencoba-coba membuat plugin.

from volatility3.framework.interfaces import plugins
class Testing(plugins.PluginInterface):
    _required_framework_version = (2, 0, 0)
  1. Saat membuat class, framework version perlu disesuaikan dengan versi Volatility 3 saat ini. Untuk sekarang kita buat value _required_framework_version menjadi (2, 0, 0). Jika setelah kita selesai membuat plugin ini dan muncul error di framework version ketika proses testing, ubah value menjadi (1, 0, 0), tergantung dari value yang diminta ketika error muncul.

    Contoh error:

    RuntimeError: Framework interface version 2 is incompatible with required version 1.

Pada dasarnya dalam mengembangkan plugin, hanya ada 3 hal yang perlu ditulis, yakni

  • Requirement. Requirement berisikan syarat library, dependency, dan input parameter agar bisa menjalankan plugin ini. Biasanya jika ada syarat dependency yang tak terpenuhi, Volatility tidak akan menuliskan plugin tersebut di daftar runnable plugin (ketika menjalankan vol.py --help). Hal ini juga diperlukan untuk mewadahi proses error handling. Jika terdapat parameter yang belum terpenuhi, maka Volatility akan return error.

  • Run. Run merupakan fungsi pertama yang dijalankan saat plugin dijalankan. Dijalankan, setelah requirement terpenuhi, fungsi run() akan langsung dijalankan. Misalkan baris perintah berikut ini:

vol.py -f xxx windows.testing

  • Generator. Generator digunakan sebagai fungsi untuk membuat list data yang di-return setelah pemrosesan. Digunakan di dalam run untuk generate list hasil pemrosesan.

Kita mulai dari hal yang pertama, yakni Requirement.

@classmethod
    def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
        return [
            requirements.TranslationLayerRequirement(name = 'primary',
                           description = 'Memory layer for the kernel',
                           architectures = ["Intel32", "Intel64"]),
            requirements.SymbolTableRequirement(name = "nt_symbols",
                            description = "Windows kernel symbols"),

Yang dibutuhkan agar kode tersebut berjalan adalah dependency untuk requirement tersebut. Berikut merupakan contoh dependency yang dibutuhkan:

from volatility3.framework.configuration import requirements
from volatility3.framework import interfaces
from typing import List

Secara umum terdapat dua pendekatan dalam menulis requirement untuk plugin Windows. Pertama adalah menulis requirement module kernel. Jika menggunakan metode ini, kita perlu mengisi parameter pada module lain yang diperlukan untuk dapat menggunakan module tersebut. Misalnya pada module pslist diperlukan parameter context, layer_name, dan symbol_table. Untuk dapat menggunakan module ini dengan pendekatan pertama, module dapat dipakai dengan:

...
@classmethod
    def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
        return [
            requirements.ModuleRequirement(name="kernel",
                description="Windows kernel",
                architectures=["Intel32", "Intel64"],
            )
	]

...
kernel = self.context.modules[self.config["kernel"]]
tasks = pslist.PsList.list_processes(self.context, kernel.layer_name, kernel.symbol_table_name)

Pendekatan kedua adalah dengan secara eksplisit menuliskan layer_name dan symbol_table sebagai context. Sehingga penulisan pendekatannya akan menjadi seperti berikut:

def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
        return [
            requirements.TranslationLayerRequirement(name = 'primary',
                           description = 'Memory layer for the kernel',
                           architectures = ["Intel32", "Intel64"]),
            requirements.SymbolTableRequirement(name = "nt_symbols",
                            description = "Windows kernel symbols"),
        ]
...
tasks = pslist.PsList.list_processes(self.context, self.config['primary'],
                                                self.config['nt_symbols'])

Untuk artikel ini kita akan memakai pendekatan pertama karena module kernel sedikit lebih lengkap dan lebih mudah dipahami.

Selanjutnya adalah Run.

Pada dasarnya, kode yang ada di sini disesuaikan dengan kebutuhan dari pembuat plugin, dan juga logic program utama bisa diletakkan di sini. Dalam konteks artikel ini, karena kita akan mencoba untuk melakukan proses listing, kita membutuhkan fungsi list_processes dari module pslist.

Jika merunut dengan pendekatan Requirements pertama, maka bentuknya akan seperti ini:

from volatility3.plugins.windows import pslist
...
def run(self):
        kernel = self.context.modules[self.config["kernel"]]
        tasks = pslist.PsList.list_processes(self.context, kernel.layer_name, kernel.symbol_table_name)

Jika kita membutuhkan module lain, kita juga bisa include dengan meng-import module tersebut. Kita perlu membaca tiap file plugin untuk bisa tahu fungsi yang dapat kita manfaatkan.

Di bagian paling akhir, untuk melakukan render text, diperlukan module renderers untuk melakukan printing rapi dari hasil analisis. Di sini kita akan menggunakan TreeGrid, yang merupakan default output dari plugin Volatility 3 pada umumnya.

from volatility3.framework import renderers
...
return renderers.TreeGrid([("PID", str), ("Image", str)], self._generator(tasks))

renderers.TreeGrid() menerima dua parameter, parameter pertama adalah List yang berisikan Tuple (“nama kolom”, tipedata) yang ukurannya disesuaikan dengan bentuk output, dan self._generator() yang merupakan fungsi Generator yang akan dibahas selanjutnya.

Dan yang terakhir adalah Generator.

Generator adalah, sesuai namanya, generator untuk hasil analisis.

def _generator(self, data):
        for task in data:
            yield (0, [
                    int(task.UniqueProcessId),
                    task.ImageFileName.cast("string", 
                            max_length = task.ImageFileName.vol.count, 
                            errors = 'replace')
                ])

Fungsi _generator() bisa diberikan parameter sesuai kebutuhan. Dalam konteks ini karena kita akan melakukan listing dari proses, kita memerlukan satu parameter, sebut saja data, dan melihat dari fungsi sebelumnya, data adalah tasks. Output dari pslist (`tasks`) sebelumnya adalah Iterable, sehingga untuk dapat melihat semua list proses dari tasks , perlu dilakukan iterasi dengan menggunakan looping for task in data:.

Output yang diperlukan dari _generator() adalah List dari (0, [output1, output2,…]). Nilai ini bisa di-provide dengan return maupun yield. PID dapat diambil dari task dengan UniqueProcessId yang di-cast dalam int, sedangkan nama executable dapat diambil dengan ImageFileName yang di-cast ke string, dan ditentukan max_length nya.

Sehingga seluruh code untuk testing.py akan berbentuk seperti ini:

from typing import List

from volatility3.framework import renderers, interfaces
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
from volatility3.plugins.windows import pslist

class Testing(plugins.PluginInterface):
    _required_framework_version = (2, 0, 0)

    @classmethod
    def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
        return [
            requirements.ModuleRequirement(name="kernel",
                description="Windows kernel",
                architectures=["Intel32", "Intel64"],
            )
        ]
    
    def run(self):
        kernel = self.context.modules[self.config["kernel"]]
        tasks = pslist.PsList.list_processes(self.context,
                                                kernel.layer_name,
                                                kernel.symbol_table_name)

        return renderers.TreeGrid([("PID", int), ("Image", str),], self._generator(tasks))
    
    def _generator(self, data):
        for task in data:
            yield (0, [
                    int(task.UniqueProcessId),
                    task.ImageFileName.cast("string", 
                            max_length = task.ImageFileName.vol.count, 
                            errors = 'replace')
                ])

Untuk mencoba kode tersebut, maka kita jalankan dengan perintah berikut:

`python vol.py -f <sample memory> windows.testing`

kemudian akan muncul informasi sebagai berikut:

PID     Image

4       System
296     smss.exe
380     csrss.exe
416     csrss.exe
424     wininit.exe
448     winlogon.exe
512     services.exe
520     lsass.exe
528     lsm.exe
...

Selamat! Kalian telah membuat plugin Volatility 3 dalam 30-an baris kode saja. Sekarang dengan pemahaman dasar ini, kita bisa mengeksplor lebih jauh fungsi-fungsi yang telah disediakan oleh Volatility 3 dan mengembangkan lebih jauh untuk keperluan memory analysis.

Referensi

Tentang Penulis

Rifqi Ardia Ramadhan adalah seorang cybersecurity engineer, saat ini bekerja di Blibli.com. Lulusan Informatika Institut Teknologi Sepuluh Nopember, di sana dia menggeluti dasar pemrograman, terutama Python. Selama 2 tahun bekerja sambil mempelajari bidang keamanan blue team, baik dari sisi end-user maupun enterprise. Di waktu luangnya dia mengikuti lomba Capture the Flag yang berfokus pada defensive security dan post-mortem machine analysis. Saat ini sedang berfokus meneliti tentang memory dump analysis dan pengembangan toolsnya di Python.

Writing a Volatility 3 PluginRME-DisCo Research Group
Logo
Gambar 1 - Membuat file testing.py pada folder plugins/windows