Agent-Tesla Analysis

Sep 6, 2025

Executive Summary

In this post, Xto9ot and R.D Tarun analyze a multi-stage Agent Tesla sample discovered on MalwareBazaar, delivered through a deceptive Windows batch (.bat) file. The attack employs a sophisticated multi-stage infection chain that leverages script obfuscation, living-off-the-land binaries (LOLBins), in-memory execution, and dynamic reflection to evade detection. The ultimate objective is credential and data theft, followed by exfiltration via SMTP.

The infection chain begins with an obfuscated .bat file containing embedded JavaScript, executed through Windows Script Host. This launches a PowerShell payload that sets up TLS, verifies internet connectivity, and downloads a disguised payload (mx1.jpg). Despite its benign extension, the file contains obfuscated PowerShell code that decodes and decompresses binary data, ultimately loading .NET assemblies directly into memory.

Subsequent stages involve .NET loaders that make heavy use of low-level IL instructions (calli) and dynamic method resolution to obfuscate control flow. These loaders hollow InstallUtil.exe and inject the Agent Tesla spyware into its process space. The final payload is a GZip-compressed .NET executable with control-flow obfuscation, persistence mechanisms, and credential-harvesting routines.

Once active, Agent Tesla enumerates system and user information, harvests credentials from browsers, email clients, FTP software, VPN tools, and communication applications, and exfiltrates the data via SMTP using hardcoded credentials. Optional keylogging and screen capture features are built in but disabled in this sample. The malware ensures it runs indefinitely in the background while preventing duplicate execution.

This layered approach demonstrates how Agent Tesla operators continue to refine their tradecraft by chaining together obfuscation, LOLBins, and fileless execution to maximize stealth, persistence, and resistance to detection.

Key Findings:

  • Initial Access via BAT File: The infection begins with a disguised .bat file containing embedded, obfuscated JavaScript. When executed, it invokes Windows Script Host to launch a PowerShell payload and deletes itself to evade detection.

  • Obfuscated PowerShell Downloader: The PowerShell script configures TLS 1.2, verifies internet connectivity, and downloads a disguised .jpg file containing an obfuscated PowerShell loader that decodes and executes binary data in memory.

  • Fileless Execution & Reflection: The loader leverages AppDomain.CurrentDomain.Load() and reflection to run .NET assemblies directly from memory, bypassing disk artifacts and complicating static analysis.

  • .NET Loader with Process Hollowing: A first-stage .NET DLL makes heavy use of calli instructions and dynamic method resolution. It leverages InstallUtil.exe to perform process hollowing and injects the Agent Tesla payload into memory.

  • Payload 1 – .NET Executable Loader:

    • Decompresses GZip-packed payloads at runtime.

    • Dynamically resolves methods using reflection and indirect calls.

    • Prepares and loads additional .NET assemblies without touching disk.

  • Payload 2 – Agent Tesla Spyware:

    • Implements control-flow obfuscation to hinder analysis.

    • Generates unique HWID and kills duplicate processes.

    • Steals credentials from browsers, email clients, FTP tools, VPNs, and chat apps.

    • Optional keylogger and screenlogger functions are included but disabled in this sample.

  • Data Exfiltration via SMTP: Stolen data is packaged into email messages and exfiltrated using SMTP with hardcoded credentials, blending into normal network traffic.

  • Persistence & Stealth: The malware runs indefinitely using Application.Run(), employs layered obfuscation, and minimizes disk I/O to maintain stealth and persistence.

Technical Analysis

Stage 0 - DOC20241.BAT

The Bat file with tags as AgentTesla found on malware bazaar opon opening the bat file in a text editor

The .bat file contains embedded JavaScript, which is heavily obfuscated and likely intended to evade detection. This technique leverages Windows Script Host (WSH) to execute the script, allowing the attacker to run complex logic or download additional payloads under the guise of a batch file. Upon execution, the batch file silently deletes itself (del "%~f0") after invoking the obfuscated JavaScript payload

After deobfuscation, it was determined that the script is designed to construct and execute a PowerShell payload using WScript.Shell (via ActiveXObject).

During dynamic analysis of the .bat file, We launched ProcessHacker and FakeNet-NG to monitor system behavior and network activity. Upon execution, We observed the spawning of a PowerShell process. We utilized Process Monitor (Procmon) to capture detailed system events. By filtering for the powershell.exe process, We were able to extract the exact PowerShell command line being executed.

Here's the entire powershell script which is being executed:-

The extracted PowerShell script performs a sequence of operations designed to establish a secure connection, retrieve a remote payload, and execute it in-memory. Below is a breakdown of its key functionalities:

  1. Creates an Alias z for iex & Configures the HTTPS Security Protocol:

    • Sets the system’s security protocol to TLS 1.2 using .NET’s SecurityProtocolType, ensuring compatibility with secure HTTPS connections.

  2. Performs Internet Connectivity Check:

    • Continuously pings google.com using Test-Connection until a successful response is received. This step confirms the host system has active internet access before proceeding.

  3. Initializes a WebClient Object:

    • Constructs a System.Net.WebClient object via obfuscated strings and executes it to enable HTTP-based file downloads.

  4. Downloads Remote Payload:

    • Attempts to download content from:

    • Although the file has a .jpg extension, it is not an image. This is a disguised malicious payload, a common technique to evade file-type filters and user suspicion.

  5. Executes Payload In-Memory:

    • Uses Microsoft.VisualBasic.Interaction.CallByName in combination with .NET reflection to invoke methods dynamically.

    • This allows the payload to be executed directly in-memory.

Stage 1 - Mx1.jpg

Curled the jpg as txt

Upon inspecting the file inside a text editor it looks like a obfuscated powershell script.

Notepad++

The $u8yee variable contains obfuscated binary data where the character 'A' is used in place of '00'. At the end of the script, the following steps are performed:

  1. Replaces 'A' with '00' to form valid binary strings.

  2. Joins all binary strings using [System.String]::Join('', $u8yee).

  3. Decodes the binary into readable text using:

  4. Executes the result in memory using the alias z, which maps to iex (Invoke-Expression).

Decoded binary into readable text

We made a powershell script which decodes the binary and prints out the readable text, you can see the output in the above screenshot This PowerShell script defines a function (rt45fg00) that takes a compressed byte array as input, decompresses it using GZip, and returns the decompressed byte content.

Upon inspecting the variable $y74gh00rffd, it appears to contain a string resembling hexadecimal data. Toward the end of the code, we observe the following replacement operation:

This indicates that all instances of 'EV' are being replaced with '0x', converting the string into valid hexadecimal format.

Following this, the script assigns the below:

This suggests that it is preparing to load a .NET assembly into the current application domain.

It then calls the previously defined decompression function $rt45fg00, passing the processed hex data as input. The result of the decompression is stored in the variable $uWfkxGY, which likely contains the next-stage payload or shellcode to be executed in memory.

We made a similar script with a few modifications and dumped the decompressed payload into a bin file, inspecting it in Detect It Easy indicates that its obfuscated.

die.exe

We had another huge blob of data in the variable $eSQy upon inspecting at the end of the data we can see it does the same replacement as before.

End of the code with my comments

The above code snippet performs in-memory loading and execution of a .NET assembly using reflection. Specifically:

  1. Loads a .NET payload ($uWfkxGY) into memory using [AppDomain]::CurrentDomain.Load(...), avoiding any disk write.

  2. Invokes a method named Black from a class called toooyou within the loaded assembly.

  3. Passes InstallUtil.exe and a second argument ($eSQy) , We dumped out $eSQy and its a Gzip compressed .net executable

We dumped the .NET payload ($uWfkxgY) into a file for analysis.

Second Payload

Stage 2 - Loader

As we observed the first payload is a DLL , the class and method which will be executed is toooyou and Black.

dnspy

We can see it uses calli which is a low-level IL instruction that performs an indirect method call, calli takes a function pointer (in this case toooyou.HIJIRINi1) and calls it with specified parameters.

We see that a bunch of methods are loaded like this:

This is done inside ConcurrentSetGetLastWriteEventError(). Essentially, it's creating a list of method pointers using ldfn, and storing them in toooyou.HIJIRINi1.

Looking at IsolationDllNamegetNIname we can see that it takes a string A_5 which is InstallUtils.exe and A_6 which is our Compressed Bytes

Inspecting the method DecompressBytes we can see that it decompresses bytes and returns the bytes

Looking at IsolationDllNamegetNtIname, we can see it takes a string A_5 and a byte array A_6.

  • A_5 = "InstallUtil.exe"

  • A_6 = our compressed payload

So now we have an array like:

This array is then passed into:

nejndsf()

This method dynamically resolves a MethodInfo and returns it.

That means at runtime, the malware figures out which method to call, and then uses .Invoke() to run it, passing in our array which contains:

  1. The path to InstallUtil.exe

  2. The decompressed bytes

This technique makes static analysis harder since the actual method being called is only known at runtime. Since the method is resolved dynamically, we couldn’t get it to run properly during testing. we tried building a custom loader that loads the DLL and tries to execute the method manually, but we kept running into errors.

During our research, we found that InstallUtil.exe is commonly used by Agent Tesla malware for process hollowing. Here’s how it works:

  • InstallUtil.exe is launched

  • Its memory is overwritten with the Agent Tesla payload

  • Execution is transferred to the injected payload

Agent Tesla is responsible for the usual stuff like:

  • Data exfiltration

  • C2 communication

  • Keylogging, stealing credentials, etc.

Stage 3 - Payload

As we saw earlier the second payload was compressed with GZip so i decompressed it, Detect-It-Easy indicates that there's Modified Entry Point and Control Flow Obfuscation

Decompressed Second Payload

Inspecting the entry point of the executable in DnSpy we can see the control flow obfuscation, what it does is

  1. Sets up and enables TLS

  2. Executes a function F7b0kY7

  3. Runs the application in an infinite loop so that it never ends and runs in background.

Inspecting the method F7b0kY7 we notice the same control flow obfuscation, a few keylogging methods, screenlogging methods.

Flow of the method

  • Executes 0PRvorRu2Qv

  • Executes BHFk()

  • Executes dJEDgQmz9()

  • Checks if keylogger is enabled

    • If yes:

      • Initializes and runs keylogger

  • Checks if screen logger is enabled

    • If yes:

      • Initializes and runs screen logger

  • Exits

After inspecting the configuration flags, We found that only EnableContacts is set to true, while both EnableKeylogger and EnableScreenLogger are disabled.

config

What 0PRvorRu2Qv does:

  • Gets the current process name and ID

  • Finds all running processes with the same name

  • Kills all of them — except itself

This is often used by malware to:

  • Prevent multiple instances from running at the same time

  • Remove sandbox clones or duplicates (used in analysis environments)

Inspecting the BHFk method it

  1. Generates and stores a unique HWID using disk, CPU, and MAC info

  2. Gets path of the executing assembly

  3. Builds startup directory and installation path

  4. Captures machine info: <Username>/<ComputerName>

  5. Checks if public IP grabbing is enabled which is not in the config's

  6. If enabled → grabs public IP

Inspecting the dJEDgQmz9() method :

Summary of dJEDgQmz9()

  • Fetches contact data:

    • Calls jCE6Hwa.HDOJUM32Ar() to get a list of EOF objects representing contact info.

    • Stores it in a List<EOF>.

  • Skips execution if contact list is empty:

    • Checks if the list is empty.

    • If it is, it jumps to the end (IL_0158) and optionally logs contacts if enabled.

  • Initializes and builds data:

    • Creates a StringBuilder instance.

    • Iterates through the list using enumerator.

    • Appends the result of eof.iaWNGcMbkQ() to the string builder for each EOF.

  • Sends the collected data:

    • If the StringBuilder has content:

      • Sends the contact data using

  • Cleans up:

    • Clears the StringBuilder and list.

  • Conditionally calls another contact method:

    • If FSNN0ox.EnableContacts is true:

      • Calls WCRV.smethod_0()

Taking a look at jCE6Hwa.HDOJUM32Ar()

End of HDOJUM32Ar Func

The function HDOJUM32Ar is responsible for stealing credentials from a wide range of applications and services. These include web browsers, email clients, FTP software, VPN tools, and communication platforms. Specifically, it targets:

Web Browsers:

  • Safari for Windows

  • Flock Browser

  • Chromium-based browsers

  • Falkon Browser

  • QQBrowser

  • UC Browser

  • Microsoft Edge

  • Mozilla Firefox

  • Internet Explorer

Email Clients:

  • Windows Mail App

  • Outlook

  • Opera Mail

  • Becky!

  • The Bat!

  • FoxMail

  • Mailbird

  • PocoMail

  • Claws Mail

  • IncrediMail

  • EmClient

  • Eudora

FTP Clients and Tools:

  • FileZilla

  • WinSCP

  • SmartFTP

  • FTP Navigator

  • FlashFXP

  • FTPGetter

  • FTP Commander

  • FTPCore

  • WS_FTP

VPN Clients:

  • NordVPN

  • Private Internet Access (PIA)

  • OpenVPN

Communication and Misc. Applications:

  • Discord

  • Psi / Psi+

  • Trillian

  • Internet Download Manager (IDM)

  • JDownloader 2.0

  • MySQL Workbench

In our case while dynamically analyzing the contact list was empty so it jumped to IL_0158

Looking at the method WCRV.3ElY9Ob7Kq

  • Calls a function V5IPRq.hJmQ5KyTxE()

    • This returns a list of r40fU objects.

  • Initializes an empty list list2

    • This list holds D8eWYS objects .

  • Loops through each r40fU object in the returned list:

    • Checks if r40fU.gg4LHL.Count > 0 (i.e., if it contains data).

    • If true, creates a new D8eWYS object with:

      • Extension: "txt"

      • FileBytes: UTF8-encoded contents of r40fU.XJ5avnp()

      • Filename: r40fU.NdNaOR247 + ".txt"

      • MimeType: "text/plain"

    • Adds this new D8eWYS object to list2.

  • Calls

Looking at the hJmQ5KyTxE function its used for credential harvesting from the thunderbird application as i don't have thunderbird application the data is Null

Here as the count is 0 it wont add the File Content into list2.

Going forward to the method sdz5zDMbsd which is one of the parameters of

sdz5zDMbsd

This function is responsible for extracting the username, machine/host name, the result at the end of the while loop can be seen below

Now taking a look at the iUA1EiI81sW method the second parameter

This method is responsible for extracting the system information the complete filled-in array can be seen below

Finally analyzing the rgrnSZc method which is responsible for building and sending an email using SMTP with optional attachments (exfiltrated data). It's a key part of Agent Tesla’s data exfiltration routine.

First it loads the receiver mailaddress into mailaddress2 , taking a look at what SmtpReciever is i saw the configuration

Configuration of the sample.

SMTP Server

mail.knowow.net

SMTP Port

587

Sender Email

mxl@knowow.net

Receiver Email

mx2@knowow.net

SMTP Password

americanboy21@

Enable Attachments

false

Then it constructs the MailMessage with its body, attachments (if any), Headers, Subject etc. The fully constructed MailMessage object can now be viewed in memory.

The malware then configures the SmtpClient by setting the SMTP server details then it creates a NetworkCredential object using the sender's email and password, and assigns it to the client

We can see the SmtpClient and the NetworkCredential below after its fully configured

After sending the email, the malware checks if Keylogging or Screenlogging is enabled in our case it isn't so it enters an infinite execution state by invoking Application.Run(), ensuring it continues running in the background.

IOCS

FileName
Description
Sha256
ImpHash

DOC20241.BAT

Initial Access

d9002ae6089045126350070c7b0790b4eb478e9b764bfdae3ee61e2e62a0e277

mx1.jpg

Stager

5adf2390c4e31cec5aeec546d1d24cac3f3ef5cf8685f01829a7104c6f80f47

GC.dll

Loader

22eaeecc4d723e01b373b4f15fa59851566022d9c4466e2ce467d2e041b9a834

DAE02F32A21E03CE65412F6E56942DAA

bae1cb1e-50ef-4d61-98fa-976f3bb18426.exe

Payload

94491241E60BD744FF41C9F33CD39B02EE968CFCE120720BE9E8A849B8E39C0E

F34D5F2D4577ED6D9CEEC516C1F5A744

Indicator
Description

https[:]//didaktik-labor.de/mx1.jpg

Download Server

mail.knowow.net

SMTP Server

mxl@knowow.net

Sender Email

mx2@knowow.net

Receiver Email

americanboy21@

SMTP Password

587

SMTP Port

MITRE ATT&CK MAPPING

Initial Access

T1204.002 – User Execution: Malicious File.

Initial stage is a malicious .bat (DOC20241.BAT) used to start the chain (user/execution of a delivered file).

Execution

T1059.003 – Windows Command Shell.

.bat executes embedded logic (launches Windows Script Host / further stages).

T1059.007 – JavaScript/JScript.

Obfuscated JavaScript embedded inside the .bat runs under WSH (ActiveXObject/WScript) and constructs/launches PowerShell.

T1059.001 – PowerShell.

Multiple heavily obfuscated PowerShell stages (set TLS1.2, Test-Connection loop, WebClient download, runtime decode/exec).

T1105 – Ingress Tool Transfer.

Remote file fetched (http://didaktik-labor.de/mx1.jpg) — a disguised stage payload downloaded over HTTP.

T1620 – Reflective Code Loading.

.NET assemblies / payload bytes are decoded/decompressed and loaded into the current AppDomain (AppDomain.CurrentDomain.Load()), then invoked via reflection (in-memory execution).

T1218.004 – InstallUtil (Signed Binary Proxy Execution: InstallUtil).

The loader prepares InstallUtil.exe as the target host (passes InstallUtil path and decompressed bytes to the invoked method), indicating abuse of InstallUtil as a LOLBin/proxy for execution.

T1055.012 – Process Hollowing (sub-technique of Process Injection).

Loader logic and parameters (InstallUtil + payload bytes) indicate process hollowing / in-memory replacement of a legitimate process to run the payload.

Defense Evasion

T1027 – Obfuscated Files or Information.

Heavy obfuscation across stages: token replacements (A00, EV0x), binary-as-text, control-flow obfuscation in .NET, disguised file extensions (.jpg).

T1140 – Deobfuscate/Decode Files or Information.

Runtime decoding/decompression: binary→text conversions, token replacement, GZip decompression, and dynamic assembly loading to reconstruct payloads in memory.

T1070.004 – Indicator Removal on Host: File Deletion.

Initial .bat self-deletes (del "%~f0") after launching the script to reduce on-disk artifacts.

Credential Access

T1555.003 – Credentials from Web Browsers.

The .NET payload enumerates and attempts to harvest stored credentials from many browsers (Chromium variants, Firefox, Edge, etc.).

T1552.001 – Credentials in Files.

Harvesting routines target application configuration and credential files (FTP clients, The Bat!, other local credential files).

Collection

T1114.001 – Local Email Collection.

The malware collects local contact/email data (enumerates clients, builds contact blobs, prepares attachments).

T1005 – Data from Local System.

General collection of application data, exported artifacts and files assembled for exfiltration.

Discovery

T1082 – System Information Discovery.

Malware gathers username, hostname, HWID (disk/CPU/MAC fingerprinting) and execution path info.

T1057 – Process Discovery.

Enumerates running processes and kills other instances of the same process name (avoids duplicates/sandbox clones).

Exfiltration / C2

T1048.003 – Exfiltration Over Unencrypted Non-C2 Protocol (SMTP).

Stolen contacts/credentials/data are packaged and sent via SMTP (constructed MailMessage/SmtpClient with credentials).

T1071.003 – Application Layer Protocol: Mail Protocols.

Uses SMTP (mail protocols) as the application-layer channel for data transfer/exfiltration.

Authors

Xto9ot - Linkedin

R.D Tarun - Linkedin

Last updated