From APT28 to RePythonNET: automating .NET malware analysis

From APT28 to RePythonNET: automating .NET malware analysis
This article describes Sekoia TDR’s methodology and tooling for reversing .NET malware, from manual string decryption of an APT28-modified Covenant Grunt to an automated pipeline using pythonnet, dnlib, and an MCP server to decompile, patch, and extract configuration at scale. The authors release RePythonNET-MCP to support AI-assisted, programmatic decompilation and automated configuration extraction for .NET samples. #Covenant #APT28

Keypoints

  • Many real-world malware samples are written in .NET, but dedicated tooling and write-ups are relatively scarce compared to the volume seen in the wild.
  • APT28 deployed a heavily obfuscated Covenant Grunt that used randomized symbol names, encrypted strings, and a custom outbound C2Bridge leveraging Koofr/Filen file uploads/downloads for communications.
  • The manual reversing workflow is time-consuming and tool-friction heavy: decrypting strings, incrementally renaming functions, and iterating on decompiled code is tedious with standard tools like dnSpy.
  • Sekoia TDR automated string decryption by fingerprinting the decryption routine in IL, extracting the decryption key from a static constructor, and patching ldstr/call patterns in-place using dnlib and pythonnet.
  • They extended automation to decompilation by combining dnlib with ILSpy’s decompiler via pythonnet (using reflection to instantiate internal types) to produce C# suitable for AI-assisted renaming and reasoning.
  • RePythonNET-MCP is published as an open-source MCP server exposing upload/download endpoints and a broad set of analysis, IL, decompilation, navigation, and patching primitives for programmatic and AI-driven .NET reverse engineering.

MITRE Techniques

  • [T1027 ] Obfuscated Files or Information – The sample used string encryption and randomized symbol names to hinder analysis (‘the samples were obfuscated, with randomized symbol names and encrypted strings’).
  • [T1546 ] Hijack Execution Flow – The infection ensured persistence by performing a user-level COM hijack that loads a malicious DLL (‘VBA macros to perform a user-level COM hijack, ensuring persistence by loading a malicious DLL’).
  • [T1564 ] Hide Data – Steganography was used to embed and extract shellcode from a benign PNG as part of the stager (‘steganography to extract a shellcode from a valid PNG file’).
  • [T1071 ] Application Layer Protocol – The attacker implemented a custom outbound C2 using cloud storage APIs, relying on file uploads and downloads for communications (‘relying entirely on file uploads and downloads to that service for its communications’).
  • [T1105 ] Ingress Tool Transfer – Covenant was used to retrieve additional modules and deliver specialized payloads (‘retrieving additional modules’ and using Covenant as a delivery vehicle for specialized modules).
  • [T1204 ] User Execution – Initial execution and delivery used lure documents with VBA macros to trigger payload execution (‘lure documents delivered via Signal Desktop … The infection leverages VBA macros’).

Indicators of Compromise

  • [File Hash ] sample referenced for analysis – 69609e89b04d8d27dc47bda2971376cfd760abb40ffe325f00d0cf3303be8906
  • [Repository / Project ] tooling and samples – https://github.com/SEKOIA-IO/RePythonNET-MCP, QuasarRAT (open-source .NET RAT)
  • [Cloud Services / APIs ] C2 channel used via cloud storage APIs – Koofr API, Filen API
  • [File Path ] example of patched output – C:output.dll
  • [Malware / Component Names ] referenced implants and modules – Covenant, BeardShell, SlimAgent (and MASEPIE, STEELHOOK, OCEANMAP)


Read more: https://blog.sekoia.io/apt28-to-repythonnet-automating-net-malware-analysis/