Malware Analysis

Einstieg in statische Malware-Analyse

Ein strukturierter Workflow für den ersten Blick auf unbekannte Binaries — von Triaging über Disassembly bis zur IOC-Extraktion.

Bevor du eine unbekannte Probe in die Sandbox wirfst, lohnt sich ein disziplinierter statischer Überblick. Statische Analyse beantwortet nicht alles — aber sie liefert dir in wenigen Minuten Risikoeinschätzung, Verdachtsmomente und eine gezielte Hypothesenliste für die dynamische Phase.

Dieser Artikel beschreibt einen praxisnahen Workflow, den ich für Windows-PE-Samples nutze. Die Befehle sind copy-paste-fähig; Pfade und Dateinamen passe ich an ein fiktives Sample sample.exe an.


Vorbereitung: Lab & Hygiene

Arbeite niemals mit Malware auf deinem Host-System. Minimum-Setup:

Komponente Empfehlung
VM Isolierte Analyse-VM (Win10/11), keine Shared Folders
Snapshot Snapshot vor jeder Analyse — Rollback nach Session
Netzwerk VM-Netzwerk disabled oder auf Host-Only/FakeNet
Tools Remnux, FLARE-VM oder eigene Windows-Analyse-VM
Hashing SHA256 vor dem Öffnen dokumentieren

Arbeitsverzeichnis anlegen

mkdir -p ~/malware-lab/samples/2026-07-14-sample
cd ~/malware-lab/samples/2026-07-14-sample

Sample sicher übertragen

Sample per USB, geschütztem Share oder scp in die VM kopieren. Direkt hashen:

# Linux / Remnux
sha256sum sample.exe | tee sample.exe.sha256

# Windows PowerShell
Get-FileHash -Algorithm SHA256 .\sample.exe | Format-List

Beispielausgabe (fiktiv):

SHA256: 3f8a1b2c4d5e6f7890abcdef1234567890abcdef1234567890abcdef12345678

Hash in deine Analyse-Notizen übernehmen — später für IOCs, YARA und Austausch mit der Community.

Optional: VirusTotal-Check (nur Hash!)

curl -s --request GET \
  --url "https://www.virustotal.com/api/v3/files/<SHA256_HIER_EINFÜGEN>" \
  --header "x-apikey: <DEIN_VT_API_KEY>"

Hinweis: Upload nur, wenn du die Policy deines Labs/Arbeitgebers kennst. Für sensible Samples reicht oft der Hash-Lookup.


Phase 1: Triaging

Ziel: Was ist das für eine Datei? Ist sie gepackt? Enthält sie verdächtige Strings oder Imports?

1.1 Dateityp & Basisinformationen

file sample.exe

Typische Ausgabe:

sample.exe: PE32 executable (GUI) Intel 80386, for MS Windows
exiftool sample.exe

Achte auf: OriginalFileName, InternalName, CompanyName, CompileTimestamp — oft spoofed, aber dokumentationswürdig.

1.2 Entropie — Packer-Verdacht

Hohe Entropie (> 7.0) in einzelnen Sections deutet auf Packing/Verschlüsselung hin.

# mit binwalk
binwalk -E sample.exe

# alternativ: ent (falls installiert)
ent sample.exe

Interpretation:

Entropie (Section) Einschätzung
< 6.5 eher ungepackt / normale Code-Section
6.5 – 7.2 grenzwertig — genauer hinschauen
> 7.2 starker Verdacht auf Packer/Verschlüsselung

1.3 Detect It Easy (DIE) — Packer/Compiler

# Windows (DIE CLI, Pfad anpassen)
"C:\Tools\die\diec.exe" -d sample.exe

Beispielausgabe:

PE32
    Operation system: Windows(95)[I386]
    Protector: UPX(3.96)[NRV,brute]
    Language: C/C++

→ Sofort notieren: UPX → später upx -d testen (nur in isolierter VM).

1.4 PE-Struktur mit peframe

peframe sample.exe | head -60

Relevante Felder:

1.5 Strings extrahieren

strings -n 8 sample.exe | tee strings.txt
strings -el sample.exe | tee strings_unicode.txt   # UTF-16LE (Windows)

Verdächtige Muster suchen:

grep -iE '(http|https|ftp)://' strings.txt
grep -iE '(\.exe|\.dll|\.bat|cmd\.exe|powershell)' strings.txt
grep -iE '(HKEY_|Software\\Microsoft\\Windows\\CurrentVersion\\Run)' strings.txt
grep -iE '(VirtualAlloc|WriteProcessMemory|CreateRemoteThread)' strings.txt

Beispiel-Treffer (fiktiv):

http://malicious-c2.example.com/gate.php
cmd.exe /c whoami
Software\Microsoft\Windows\CurrentVersion\Run

→ C2-URL, Command Execution, Registry-Persistence — drei Hypothesen für Phase 3.

1.6 Imports clustern (fcli / pedump)

# fcli (FLARE) — Import-Übersicht
fcli sample.exe imports

# oder mit Python pefile
python3 << 'EOF'
import pefile
pe = pefile.PE("sample.exe")
for entry in pe.DIRECTORY_ENTRY_IMPORT:
    print(f"\n[DLL] {entry.dll.decode()}")
    for imp in entry.imports:
        if imp.name:
            print(f"  - {imp.name.decode()}")
EOF

Verdächtige API-Cluster:

API-Gruppe APIs Verdacht
Injection VirtualAllocEx, WriteProcessMemory, CreateRemoteThread Prozess-Injektion
Persistence RegSetValueEx, RegCreateKeyEx Registry-Persistence
Netzwerk InternetOpenUrl, HttpSendRequest, WSAStartup C2 / Exfiltration
Anti-Analysis IsDebuggerPresent, CheckRemoteDebuggerPresent Evasion
Droppers URLDownloadToFile, CreateProcess Download & Execute

Phase 2: Disassembly

Ziel: Entry Point verstehen, Kontrollfluss skizzieren, Obfuscation erkennen — nicht sofort alles deobfuscaten.

2.1 Ghidra — Projekt anlegen

# Ghidra Headless (Batch-Import)
analyzeHeadless /opt/ghidra/projects MalwareProj \
  -import sample.exe \
  -overwrite \
  -scriptPath /opt/ghidra/scripts

Oder interaktiv: Ghidra öffnen → New Project → Import sample.exe → Analyze (Standard-Optionen reichen für den Start).

2.2 Entry Point lokalisieren

In Ghidra:

  1. Window → Symbol Tree → Functions
  2. entry oder EntryPoint suchen
  3. Aufrufkette der ersten 10–20 Funktionen notieren

Was du dokumentierst:

entry()
  └── FUN_00401000()        ; vermutlich CRT-Init
        └── FUN_00401230()  ; Hauptlogik / Packer-Stub
              └── FUN_00401800()  ; Entpack-Routine?

2.3 Obfuscation erkennen

Typische Muster in der Disassembly:

; Junk-Code / opaque predicates
CMP EAX, 2
JNZ  loc_dead_code     ; wird nie genommen
...
loc_dead_code:
XOR EBX, EBX           ; Müll

; API-Hashing statt direkter Imports
PUSH 0x91AFCA54        ; Hash von kernel32.dll
CALL resolve_api_by_hash

Regel: Erst Struktur verstehen, dann gezielt deobfuscaten — nicht blind durch den ganzen Binary klicken.

2.4 Verdächtige Funktionen benennen

In Ghidra Funktionen sinnvoll umbenennen — spart Stunden:

Original Umbenennen zu Grund
FUN_00401800 unpack_stub Entropie + Schleife über Sections
FUN_00402100 resolve_apis PEB-Walk / GetProcAddress-Muster
FUN_00402500 persist_registry RegSetValueEx-Aufrufe

2.5 Optional: UPX entpacken

Nur wenn DIE UPX meldet und du in einer isolierten VM bist:

upx -d sample.exe -o sample_unpacked.exe

Danach Triaging wiederholen — Strings und Imports sind oft erst jetzt sichtbar:

strings -n 8 sample_unpacked.exe | grep -iE 'http'
peframe sample_unpacked.exe | head -30

Phase 3: Verhaltenshypothesen

Aus Phase 1 und 2 formulierst du testbare Fragen für die dynamische Analyse:

Hypothesen-Tabelle (Beispiel)

# Hypothese Statischer Beleg Dynamischer Test
H1 Sample persistiert via Run-Key String CurrentVersion\Run + RegSetValueEx Procmon: Registry-Writes
H2 C2-Kommunikation über HTTP String http://malicious-c2.example.com Wireshark / FakeNet
H3 Prozess-Injektion Imports WriteProcessMemory, CreateRemoteThread API-Monitor / x64dbg
H4 Anti-VM / Anti-Debug IsDebuggerPresent, Registry-Checks Sandbox mit/ohne Artefakte

Mini-Checkliste vor der Sandbox

[ ] SHA256 dokumentiert
[ ] Packer identifiziert (ja/nein, welcher)
[ ] Verdächtige Strings extrahiert
[ ] Import-Cluster notiert
[ ] Entry-Point-Call-Chain skizziert
[ ] Hypothesen-Tabelle erstellt
[ ] VM-Snapshot erstellt
[ ] Netzwerk isoliert oder FakeNet bereit

Phase 4: IOCs extrahieren & Übergabe

Statische Findings werden zu Indicators of Compromise — die Grundlage für Detection und Threat Hunting.

4.1 IOC-Sammlung (Beispiel)

# iocs/sample_2026-07-14.yml
hashes:
  sha256: "3f8a1b2c4d5e6f7890abcdef1234567890abcdef1234567890abcdef12345678"

file:
  filename: "sample.exe"
  size_bytes: 245760

network:
  domains:
    - "malicious-c2.example.com"
  urls:
    - "http://malicious-c2.example.com/gate.php"

host:
  registry_keys:
    - "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\WindowsUpdate"
  mutex:
    - "Global\\MalwareMutex_0x4141"   # falls in Strings gefunden

imports_flagged:
  - "WriteProcessMemory"
  - "CreateRemoteThread"
  - "RegSetValueExA"

4.2 Einfache YARA-Regel (String-basiert)

rule AetherSec_Sample_C2_String {
    meta:
        author = "AetherSec"
        description = "Detects sample with hardcoded C2 URL"
        date = "2026-07-14"
        hash = "3f8a1b2c4d5e6f7890abcdef1234567890abcdef1234567890abcdef12345678"

    strings:
        $c2 = "malicious-c2.example.com" ascii wide
        $run = "CurrentVersion\\Run" ascii wide

    condition:
        uint16(0) == 0x5A4D and
        filesize < 5MB and
        $c2 and $run
}

Testen:

yara -s aethersec_sample.yar sample.exe

4.3 Übergabe an dynamische Analyse

Was du der Sandbox mitgibst:

  1. Hypothesen-Tabelle (Phase 3)
  2. IOC-YAML (Phase 4)
  3. Entpacktes Binary (falls vorhanden: sample_unpacked.exe)
  4. Ghidra-Projekt-Export (optional: Function-Namen als Referenz)

Dynamische Tools je nach Hypothese:

Hypothese Tool Was du beobachtest
Persistence Procmon RegSetValue auf Run-Keys
C2 Wireshark / FakeNet HTTP-Requests, DNS
Injection API Monitor WriteProcessMemory + CreateRemoteThread
Evasion x64dbg / ScyllaHide Debugger-Checks, Timing

Komplett-Workflow auf einen Blick

# === VORBEREITUNG ===
mkdir -p ~/malware-lab/samples/$(date +%Y-%m-%d)-sample && cd $_
sha256sum sample.exe | tee sample.exe.sha256

# === TRIAGING ===
file sample.exe
binwalk -E sample.exe
diec sample.exe                          # oder peframe
strings -n 8 sample.exe | tee strings.txt
strings -el sample.exe | tee strings_u.txt
grep -iE '(http|HKEY_|VirtualAlloc|cmd\.exe)' strings.txt

# === DISASSEMBLY ===
# Ghidra: Import → Analyze → Entry Point → Call-Chain dokumentieren

# === OPTIONAL: UNPACK ===
upx -d sample.exe -o sample_unpacked.exe  # nur bei UPX, nur in VM!

# === IOCs ===
yara -s aethersec_sample.yar sample.exe

Häufige Fehler (und wie du sie vermeidest)

Zu früh dynamisch analysieren.
→ Erst statisch triagen. Du sparst Sandbox-Zeit und vermeidest, dass ein Evasion-Mechanismus deine Session verdirbt.

Alles auf einmal deobfuscaten.
→ Struktur vor Details. Entry Point → Hauptfunktionen → dann gezielt tiefer.

Keine Dokumentation.
→ Jeder Befehl, jede Ausgabe, jeder Hash in Notizen. Dein zukünftiges Ich (und dein Team) wird es dir danken.

Netzwerk an in der VM.
→ Isolation first. C2-Callbacks auf echte Infrastruktur sind vermeidbar.

Sample ohne Snapshot öffnen.
→ Ein Klick auf die falsche Datei — VM weg. Snapshot ist Pflicht.


Tooling-Referenz

Phase Tool Zweck
Hashing sha256sum, Get-FileHash Integrität & IOC
Triaging file, binwalk, die, peframe Typ, Entropie, Packer
Strings strings, grep C2, Pfade, Mutex, Registry
Imports fcli, pefile API-Verhalten ableiten
Disassembly Ghidra, IDA, Binary Ninja Kontrollfluss, Deobfuscation
Unpacking upx -d, manuell in Debugger Entpackte Analyse
Detection YARA Regelbasierte Erkennung
Dynamisch Procmon, Wireshark, x64dbg Hypothesen testen

Fazit

Statische Malware-Analyse ist kein Ersatz für dynamisches Verhalten — aber der effizienteste Startpunkt. Ein disziplinierter 30–60-Minuten-Block vor der Sandbox liefert dir:

Wer hier sauber dokumentiert, analysiert schneller und trifft in der dynamischen Phase bessere Entscheidungen.


Feedback, Sample-Hinweise oder Korrekturen gerne über GitHub oder X.