ea56cf43d33bcc713bbd715bd83a1b3adb5562e8266bf47bed96ab8c54163217petpack: ea56cf43d33b — AES-managed .NET loader with Serbian banking lure
Executive Summary
A .NET Framework 4.0 PE32+ loader compiled in August 2024. Its internal namespace is Petpack (sub-types Rock and InjectMem), and it arrives as a Serbian/Croatian banking-themed executable (kopija_bankovnog_placanja.exe — "copy of bank payment"). The sample decrypts an AES-encrypted payload at runtime using AesManaged with key material derived from a hardcoded 11-byte seed (p6D14wkm2EW), then loads it reflectively via Marshal.GetDelegateForFunctionPointer and P/Invoke LoadLibrary. No C2 strings are recoverable statically; dynamic analysis was skipped due to no CAPE Windows guest.
What It Is
| Field | Value |
|---|---|
| SHA-256 | ea56cf43d33bcc713bbd715bd83a1b3adb5562e8266bf47bed96ab8c54163217 |
| File type | PE32+ executable (console) x86-64 Mono/.Net assembly, 2 sections ^[file.txt] |
| Size | 1,525,360 bytes |
| Timestamp | Mon Aug 5 16:16:25 2024 UTC ^[pefile.txt:40] ^[rabin2-info.txt:11] |
| CLR version | v4.0.30319 (.NET Framework 4.x) ^[parse_dotnet.py] |
| Filename | kopija_bankovnog_placanja.exe (Serbian/Croatian: "copy of bank payment") ^[triage.json:5] |
| YARA | PE_File_Generic only ^[yara.txt] |
| Authenticode | Timestamped via Sectigo/USERTrust chain; no code signature ^[binwalk.txt] ^[rabin2-info.txt:29] |
The PE has two sections (.text, .rsrc) with moderate entropy (~6.0), no packing, and a valid but non-standard PE32+ layout: AddressOfEntryPoint = 0x0 (characteristic of .NET CIL entry). ^[pefile.txt:56]
Build / RE
Toolchain
Compiled to CIL for the .NET Framework 4.0 runtime. The module metadata contains 42 methods, 17 types, and 2 assembly references. ^[parse_dotnet.py] Version-info fields are populated with nonsense values (CompanyName: Uruparijilocumabogay, ProductName: Iwinacit, OriginalFileName: Ivijapiqocipitol). ^[exiftool.json:36-41]
Obfuscation
All type and method names in the #Strings heap are mangled with Arabic/Persian Unicode glyphs (e.g. ﴊﵩﮝپ﵃ﱛڢﰌﱠﶊﴢﰩﭤﰋﴀﲙﶣﶓﰪﮍﲨﴊٚۤﶃڅ). Only framework API names (AesManaged, CreateDecryptor, GetString, ReadAllBytes, InjectMem, AllocConsole, FreeConsole, LoadLibrary) and the internal namespace Petpack/Rock survive as plain ASCII. ^[parse_dotnet.py] ^[strings.txt:52-75]
This is not a commercial obfuscator (no ConfuserEx, SmartAssembly, or Dotfuscator signatures). The mangling appears custom or generated by a simple name-scrambling tool.
Crypto
The binary references AesManaged (deprecated since .NET Framework 4.6 in favour of Aes), CreateDecryptor, set_Key, and set_IV. ^[parse_memberref.py] A hardcoded 11-byte ASCII string p6D14wkm2EW appears seven times in the binary, interleaved with what appears to be ciphertext or padding material. ^[strings.txt search]
The FieldRVA table has 1 row, suggesting a small embedded data blob (likely the AES key/IV or encrypted payload header) mapped directly into a static field. ^[parse_dotnet.py]
Anti-analysis
- No debug checks, no VM detection strings, no
IsDebuggerPresent. - No TLS callbacks, no delay imports.
- Console-allocation APIs (
AllocConsole/FreeConsole) are imported via P/Invoke, likely to create a visible window or hide console presence. ^[parse_memberref.py]
Embedded payload
No manifest resource or RCData payload is evident in static analysis. The .rsrc section contains only the standard UAC manifest and timestamping certificates. ^[binwalk.txt] The encrypted payload is likely supplied as an external file (the ReadAllBytes API strongly suggests file-based staging) or appended to the binary beyond the certificate block. The PAPADDINGXX strings after the certificate block (offset 0xa0c0d) suggest trailing data that may include the ciphertext.
Notable methods
InjectMem— name recovered from#USheap; suggests in-memory PE injection or reflective mapping. ^[parse_dotnet.py]Petpack.Strept— recovered from#USheap; possibly a class/type name (Strept≈ "streptococ" fragment, or truncated). ^[parse_dotnet.py]- Entry-point method (MethodDef 6, RVA
0x327d) is a tiny 8-byte stub that chains three.ctorcalls before returning. ^[dump_il.py]
Deploy / ATT&CK
Static-only inference (CAPE skipped — no Windows guest available). ^[dynamic-analysis.md]
| Tactic | Technique | Evidence |
|---|---|---|
| DEFENSE EVASION | T1620 Reflective Code Loading | LoadLibrary P/Invoke, InjectMem naming, GetDelegateForFunctionPointer, Marshal usage. ^[capa.txt] ^[parse_memberref.py] |
| DEFENSE EVASION | T1027 Obfuscated Files or Information | AES-encrypted payload, Unicode name mangling. |
| EXECUTION | T1059 Command and Scripting Interpreter | .NET assembly loaded reflectively; AesManaged + CreateDecryptor decrypts and executes. ^[capa.txt] |
| EXECUTION | T1106 Execution via API | LoadLibrary, AllocConsole, FreeConsole via P/Invoke. ^[parse_memberref.py] |
| PERSISTENCE | — | Not observed statically. No registry, schtasks, or startup strings. |
| C2 | — | Not observed statically. No hardcoded URLs, IPs, or domain names. |
Attribution
- Linguistic: The filename and lure theme are Serbian/Croatian (
kopija bankovnog plaćanja= "copy of bank payment"). The target geography is likely the Balkans. - Build date: August 2024 — relatively fresh at time of collection (May 2026).
- Namespace:
Petpackis not a known public malware family. No siblings found in the corpus. - Confidence: Medium. This is a single-sample observation with no CAPE confirmation.
C2 Infrastructure
None recoverable statically. The sample may fetch its payload from a remote URL at runtime (not present in strings), or it may be designed to receive the encrypted payload as a companion file. ReadAllBytes implies local file reading; network C2 is unproven.
Interesting Tidbits
- The hardcoded seed
p6D14wkm2EWis an 11-byte mixed-alphanumeric string that repeats seven times with different trailing bytes — likely used to derive a 128-bit or 256-bit AES key via a KDF or simple expansion. ^[strings.txt search] - The
#US(user string) heap contains three plaintext literals:something,p6D14wkm2EW, andPetpack.Strept— a rare leak of internal naming through the user-string table. ^[parse_dotnet.py] - The assembly references two empty-named assemblies (
'' v0.0.0.0) — possibly merged or obfuscated dependencies. ^[parse_memberref.py] - The PE carries a valid Authenticode timestamp (Sectigo/USERTrust) but no actual code signature, giving it superficial legitimacy without a revocable cert. ^[binwalk.txt]
AesManagedwas deprecated in favour ofAesin .NET Framework 4.6 (2015). Using the older API suggests the builder targets broad compatibility or the author simply copied an older template.
How To Mess With It (Homelab Replication)
Goal: Build a minimal .NET AES-loader that decrypts a payload from disk and loads it via Assembly.Load.
- Toolchain: Visual Studio or
dotnet new console --framework net40. - Code skeleton:
byte[] key = Encoding.UTF8.GetBytes("p6D14wkm2EW".PadRight(32, 'X')); byte[] iv = new byte[16]; byte[] cipher = File.ReadAllBytes("stage2.bin"); using (AesManaged aes = new AesManaged()) { aes.Key = key; aes.IV = iv; ICryptoTransform decryptor = aes.CreateDecryptor(); byte[] plain = decryptor.TransformFinalBlock(cipher, 0, cipher.Length); Assembly.Load(plain).EntryPoint.Invoke(null, null); } - Verification: Compile, run
capa— should hitcompiled to the .NET platform,invoke .NET assembly method,read file in .NET.
Deployable Signatures
YARA
rule Petpack_DotNet_Loader {
meta:
description = "Detects Petpack .NET AES loader family"
author = "pp-hermes"
date = "2026-06-18"
sha256 = "ea56cf43d33bcc713bbd715bd83a1b3adb5562e8266bf47bed96ab8c54163217"
strings:
$namespace1 = "Petpack" ascii wide
$namespace2 = "Petpack.dll" ascii wide
$inject = "InjectMem" ascii wide
$aes = "AesManaged" ascii wide
$seed = "p6D14wkm2EW" ascii wide
$str_read = "ReadAllBytes" ascii wide
$str_create = "CreateDecryptor" ascii wide
$str_delegate = "GetDelegateForFunctionPointer" ascii wide
$str_loadlib = "LoadLibrary" ascii wide
condition:
uint16(0) == 0x5A4D and
($namespace1 or $namespace2) and
($inject or $seed) and
any of ($aes, $str_read, $str_create) and
filesize < 3MB
}
Behavioral Hunt Query (KQL / Microsoft Defender)
DeviceProcessEvents
| where InitiatingProcessFileName =~ "kopija_bankovnog_placanja.exe"
or FileName contains "Petpack"
or ProcessCommandLine contains "p6D14wkm2EW"
| union (DeviceFileEvents
| where FileName contains "stage2.bin"
or FileName contains "kopija_bankovnog_placanja")
| union (DeviceNetworkEvents
| where InitiatingProcessFileName =~ "kopija_bankovnog_placanja.exe")
IOCs
| Type | Value | Notes |
|---|---|---|
| SHA-256 | ea56cf43d33bcc713bbd715bd83a1b3adb5562e8266bf47bed96ab8c54163217 |
Primary sample |
| Filename | kopija_bankovnog_placanja.exe |
Lure |
| String | p6D14wkm2EW |
Likely AES key seed |
| Namespace | Petpack / Petpack.Rock / Petpack.Strept |
Internal .NET namespace |
| P/Invoke | kernel32.dll::LoadLibrary |
Reflective loading |
| P/Invoke | kernel32.dll::AllocConsole / FreeConsole |
Console manipulation |
| Timestamp | Mon Aug 5 16:16:25 2024 UTC |
Compilation time |
Behavioral Fingerprint
This binary is a .NET Framework console application that imports kernel32.dll via P/Invoke for AllocConsole, FreeConsole, and LoadLibrary. At launch it initialises one or more AesManaged instances using a hardcoded key seed (p6D14wkm2EW), reads an encrypted payload from disk via ReadAllBytes, decrypts it in-memory, and reflectively loads the resulting assembly via Assembly.Load or Marshal.GetDelegateForFunctionPointer. No network C2 is hardcoded; payload delivery is either file-based or runtime-resolved. The binary carries a Sectigo/USERTrust timestamp block but no Authenticode signature.
Detection Signatures
| ATT&CK Technique | Detection Source |
|---|---|
| T1620 Reflective Code Loading | capa static analysis ^[capa.txt] |
| T1059 Command and Scripting Interpreter | capa static analysis ^[capa.txt] |
| T1027 Obfuscated Files or Information | AES payload + name mangling |
| T1106 Native API | P/Invoke LoadLibrary, AllocConsole |
References
- Artifact ID:
488d5a43-906b-45ab-86b4-9f33d7ce38b5 - Source: MalwareBazaar / OpenCTI
- Related wiki pages: petpack-dotnet, unclassified-dotnet, dotnet-manifest-resource-decryption
Provenance
file.txt—filecommand output (PE32+ Mono/.Net assembly)pefile.txt— pefile 2023.2.7 header dumprabin2-info.txt— radare2 binary header summarycapa.txt— Mandiant flare-capa v7 static capability detectionexiftool.json— ExifTool 12.76 version-info extractionstrings.txt— GNU strings extraction (1333 lines)binwalk.txt— Binwalk embedded-artefact scan (certificate block, XML manifest)dynamic-analysis.md— CAPE sandbox status (skipped, no Windows guest)triage.json— OpenCTI triage metadataparse_dotnet.py/parse_memberref.py/dump_il.py— Custom Python CLR metadata parsersfloss.txt— FireEye flare-floss (failed: CLI argument error)
Analysis completed 2026-06-18. Static-only; no CAPE detonation. Confidence: medium.