Analyzing A Recent Agent Tesla Sample
I've been poking at infostealers now as a I start my way through malware analysis so it's only fitting that I pick up this classic, Agent Tesla. This week I grabbed the Agent Tesla sample from MalwareBazaar and spent some time picking it apart. This was the most recently found sample of Agent Tesla as it was last seen 01/30/2026. Here's what I found.
Spoiler: Static analysis told me almost nothing. The interesting stuff only showed up once I executed it.
What's Agent Tesla?
Before diving in, some quick background. Agent Tesla is an infostealer that's been around since 2014. It's sold as malware-as-a-service, which means pretty much anyone can buy access and use it without writing their own code.
It steals credentials from browsers, email clients, VPNs, FTP clients, basically anything that stores passwords. It can also do keylogging and take screenshots. The reason it's still popular is that it keeps getting updates and it's cheap to use.
The Attack Chain (High Overview)
Initial access
├─ User executes WinForms EXE
└─ Masquerades as Oracle tool
↓
In-memory staging
├─ Runtime unpacks payload
└─ No payload on disk
↓
Credential enumeration
├─ Probes browser/mail stores
└─ PATH NOT FOUND = logic works
↓
Persistence
├─ Startup folder shortcut
└─ ZoRodAS0tns.lnk → payload
↓
Environment awareness
├─ ip-api.com hosting check
└─ Potential sandbox evasion
↓
Data exfiltration
├─ Credential harvest
└─ FTP to operator infra
The Sample
| File | sample.exe |
|---|---|
| SHA256 | ad131f58df2bb784cc7182a2afb12c7dbc9c139bcd881d913eb7776e9b399c02 |
| FTP | ftp[:]//ftp[.]duct-master[.]com |
[redacted]@duct-master[.]com | |
| Payload | ZoRodAS0tns[.]lnk |
| MalwareBazaar | View Sample |
| VirusTotal | View Analysis |
sample.exead131f58df2bb784cc7182a2afb12c7dbc9c139bcd881d913eb7776e9b399c02ftp[:]//ftp[.]duct-master[.]com[redacted]@duct-master[.]comZoRodAS0tns[.]lnkStage 0: Static Analysis (The Boring Part)
I started off by examining the initial file, which I renamed to sample.exe. I loaded it in DIE (Detect It Easy) to see what type of file it was. Then threw the sample into ILSpy since it's a .NET executable. The metadata immediately looked suspicious:
AssemblyProduct: Advanced Query Builder
AssemblyCompany: Oracle
AssemblyCopyright: Copyright © Oracle 2026
This didn't stand out to me right away as being deceiving because I don't know much about what's recent and what's not but given the nature of Agent Tesla, I know they loves to masquerade as database tools and admin utilities. This fit the pattern.
I kept poking around in sample.exe but couldn't find anything unique or fun. I couldn't find any payload. No embedded config, no obvious malicious code, just what looked like a basic WinForms app. The resources were all UI stuff.
I spent way too long looking for something hidden before realizing this is the point. The sample is a dropper. The actual payload doesn't exist until runtime.
Lesson learned: Don't assume static analysis will give you everything. Sometimes you just have to run it.
Stage 1: Behavioral Analysis
I spun up the sample in my lab VM with ProcMon running. Unfiltered, I got over a thousand events. Way too noisy. I narrowed it down with these filters:
- Operations:
Process Create,WriteFile,CreateFile,SetDispositionInformationFile,Load Image - Paths:
AppData,Temp,ProgramData,Users\Public
That brought it down to about 100 relevant events.
Credential Enumeration
The first interesting behavior: the process started hitting credential storage locations for a bunch of applications.
Browsers:
- SeaMonkey, Waterfox, IceDragon, Flock, QQBrowser
Email clients:
- Thunderbird, Postbox, Foxmail, Opera Mail, Mailbird, Trillian
Legacy/obscure stuff:
- The Bat!, Claws Mail, K-Meleon
It was looking for files like profiles.ini, accounts.ini, accounts.dat, and various mail databases.
Most of these came back PATH NOT FOUND because my lab VM doesn't have these apps installed. At first I thought this might be sandbox detection, but it's not, it's just the malware checking everywhere it knows to check. The failures actually confirm the harvesting logic is real.
Stage 2: Persistence
After the credential sweep, things got more interesting. ProcMon caught this:
WriteFile: C:\Users\<VM>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\ZoRodAS0tns.lnk
A Startup folder persistence. It dropped a shortcut pointing to a copy of itself:
C:\Users\<VM>\AppData\Roaming\ZoRodAS0tns.exe
A randomized filename (ZoRodAS0tns) is typical for Agent Tesla but at this point it didn't really matter. Nothing fancy, but it works.
Stage 2.5: The Payload
Once persistence was set, I took a look at the dropped executable. String analysis showed:
mscoree.dll
System.Net.Http
System.ServiceModel.Http
LoadLibraryExW
This tells me it's running managed .NET code in-process. No child processes spawned, everything happens inside the same process and it's pretty short-lived.
Environment Check
The payload makes a request to:
http[:]//ip-api[.]com/line/?fields=hosting
This checks if it's running in a hosting/VPS environment. What I've found in my research, to be a simple sandbox evasion technique, if the response indicates a hosting provider, the malware might bail. When I ran it offline, I just got noisy .NET networking exceptions.
Exfiltration Config
This is where memory analysis paid off. I found these strings near the networking code:
FTP Endpoint: ftp[:]//ftp[.]duct-master[.]com
Operator Email: [redacted][@]duct-master[.]com
The operator email has been partially redacted. I have it, just felt off putting someone's creds on blast even in this context.
So this sample uses FTP for exfiltration. Agent Tesla has also been seen to use SMTP, HTTP, or Telegram depending on how the operator configured it.
The Full Attack Chain
Putting it all together:
Decoy EXE executed
↓
Unpacks in memory
↓
Credential enumeration
↓
Drops to AppData\Roaming
↓
Startup persistence (.lnk)
↓
ip-api.com env check
↓
Harvest + FTP exfil
IOCs
| Type | Indicator | Context |
|---|---|---|
| SHA256 | ad131f58df2bb784cc7182a2afb12c7dbc9c139bcd881d913eb7776e9b399c02 | Sample hash |
| URL | http[:]//ip-api[.]com/line/?fields=hosting | Environment check |
| FTP | ftp[:]//ftp[.]duct-master[.]com | Exfil endpoint |
[redacted][@]duct-master[.]com | Operator email | |
| File path | C:\Users\<user>\AppData\Roaming\ZoRodAS0tns.exe | Dropped payload |
| File path | ...\Start Menu\Programs\Startup\ZoRodAS0tns.lnk | Persistence |
| .NET | v4.5 | Framework version |
ad131f58df2bb784cc7182a2afb12c7dbc9c139bcd881d913eb7776e9b399c02http[:]//ip-api[.]com/line/?fields=hostingftp[:]//ftp[.]duct-master[.]com[redacted][@]duct-master[.]comC:\Users\<user>\AppData\Roaming\ZoRodAS0tns.exe...\Start Menu\Programs\Startup\ZoRodAS0tns.lnkv4.5Detection Ideas
Here are some KQL queries I'd use to hunt for this kind of activity in Sentinel.
Startup Folder Persistence
This catches .lnk files being created in the Startup folder. I'm excluding common legitimate installers to cut down on noise.
DeviceFileEvents
| where ActionType == "FileCreated"
| where FolderPath has @"\Start Menu\Programs\Startup\"
| where FileName endswith ".lnk"
| where InitiatingProcessFileName !in ("explorer.exe", "msiexec.exe", "setup.exe")
| project
Timestamp,
DeviceName,
FileName,
FolderPath,
InitiatingProcessFileName,
InitiatingProcessFolderPath,
InitiatingProcessCommandLine
Executables Dropped to AppData\Roaming
Agent Tesla copied itself to AppData\Roaming with a random name. This looks for executables written there by processes that aren't installers.
DeviceFileEvents
| where ActionType == "FileCreated"
| where FolderPath has @"\AppData\Roaming\"
| where FileName endswith ".exe"
| where InitiatingProcessFolderPath !has "Program Files"
| where InitiatingProcessFileName !in ("msiexec.exe", "setup.exe", "Update.exe")
| project
Timestamp,
DeviceName,
FileName,
FolderPath,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
SHA256
Credential Store Access
This one looks for processes touching multiple credential storage locations in a short window.
DeviceFileEvents
| where ActionType in ("FileAccessed", "FileRead")
| where FolderPath has_any (
"Thunderbird",
"Firefox",
"Chrome",
"Opera",
"Foxmail",
"Postbox",
"Mailbird",
"SeaMonkey",
"Waterfox"
)
| where FileName has_any ("profiles.ini", "accounts.ini", "logins.json", "Login Data", "cookies.sqlite")
| summarize
TargetCount = dcount(FolderPath),
Targets = make_set(FolderPath),
FirstSeen = min(Timestamp),
LastSeen = max(Timestamp)
by DeviceName, InitiatingProcessFileName, InitiatingProcessId
| where TargetCount > 3
| where datetime_diff('second', LastSeen, FirstSeen) < 60
Environment Awareness Check
Agent Tesla hit ip-api.com to check if it's in a sandbox. This is a pretty weak signal on its own, but useful for correlation.
DeviceNetworkEvents
| where RemoteUrl has "ip-api.com"
| where InitiatingProcessFolderPath has_any (@"\AppData\", @"\Temp\", @"\Users\Public\")
| project
Timestamp,
DeviceName,
RemoteUrl,
InitiatingProcessFileName,
InitiatingProcessFolderPath,
InitiatingProcessCommandLine
Outbound FTP
FTP from a user workstation is unusual enough that it's worth flagging. This catches connections on port 21.
DeviceNetworkEvents
| where RemotePort == 21
| where ActionType == "ConnectionSuccess"
| where InitiatingProcessFolderPath has @"\Users\"
| project
Timestamp,
DeviceName,
RemoteIP,
RemotePort,
InitiatingProcessFileName,
InitiatingProcessFolderPath,
InitiatingProcessCommandLine
Putting It Together
Any single query might catch legitimate activity. The real signal is when you see multiple hits from the same device in a short timeframe. Startup persistence + credential access + outbound FTP is a pretty solid Agent Tesla signature.
MITRE ATT&CK
| ID | Technique | Observed |
|---|---|---|
| T1566 | Phishing | Likely initial delivery method |
| T1036 | Masquerading | Fake Oracle branding |
| T1547.001 | Startup Folder Persistence | The .lnk drop |
| T1555 | Credentials from Password Stores | All the credential harvesting |
| T1082 | System Information Discovery | The ip-api environment check |
| T1048 | Exfil Over Alternative Protocol | FTP to attacker infrastructure |
Likely initial delivery method
Fake Oracle branding
The .lnk drop
All the credential harvesting
The ip-api environment check
FTP to attacker infrastructure
What I Learned
-
Static analysis has limits. I wasted time looking for an embedded payload that didn't exist. The real action happens at runtime.
-
ProcMon filtering is essential. Unfiltered logs are useless. Knowing which paths and operations to watch for makes a huge difference.
-
"PATH NOT FOUND" is still signal. Failed file access attempts tell you what the malware is looking for, even if it doesn't find anything.
-
Memory analysis matters. The exfil config wasn't on disk anywhere. I only found it by looking at strings in memory.