Malware fight back the tale of agent tesla

~ 9 minute read
Crafted : 3 months ago Updated : 3 months ago
#websec #code-audit #guide #malware #reversing #vulnerability #malwarefightback #rce #botnet #cc #c2 #net

Hello, luvs.


Malware is everywhere. That's why I'd like to share some thoughts on the malware analysis. We start we a brief introduction then we jump into agent tesla malware. We breakdown and deobfuscate both bin and web panel. We wrap it up with a full decrypted bin and an interesting RCE on the web panel. 


Table of contents 



Malware has been around since the beginning of computers and, the anti-virus industry and analysis tools evolved. However, as of today, we can not rely solely on machines, and manual analysis is still required. That's why I believe we need a lot more malware analysts in the world. Their main job is making sense of malware so you and I can be safer while surfing, so before anything else, to any malware analysts reading this out there, I'd like you to thank you for all your hard work guys, you are awesome!

As you may already find out from my previous articles, I prefer to have a case study because, without case studies, it might be just theoretical and maybe boring for some of you. So I randomly choose Agent Tesla as a case study. Its been sold as a service plus crypt and macro document services. It used by some APT, been active recently, and its author even revealed


About Malware Analysis 


I'm used to occasionally analysis malware for practicing the art of reverse engineering. I find real malware more interesting than crack-me style challenges. My methodology might be different from full-time, professional malware analysts, but I believe the process should be very similar. 


Static Analysis VS Dynamic Analysis 

When we want to analysis a new malware, we can use static or dynamic or even a mixture of both techniques to perform an analysis. Depends on complexity, platform, language, and some more factors, we can choose which type of analysis suite our needs best. For those who are not familiar with these, I'll explain them briefly. 


Static Analysis 

We do not run the malware. We try to extract as much information from binary files. For simple to medium complexity malware, static analysis is usually more than enough to make sense of malware capabilities, connections, and maps. These are typically main points while we analyze malware. For large or complex malware, we still can leverage static analysis, but most of the time, getting aid from dynamic analysis makes an analysis process more comfortable and more efficient. There are so many tools available for static analysis, but most notable ones are disassemblers, detectors, and file format parsers. In the static analysis step, we usually extract strings, disassemble, or decompile the code and, finally, analysis the code.

Dynamic analysis 

We run the malware on a safe virtual machine. We usually want to redirect and sniff network packets (most interestingly HTTP and DNS protocols) and analysis the malware process behaviors. (API calls, file drops, registry changes, process injections). Running and configuring malware analysis is out of the scope of this article, but in the case of Windows Malware, flare-VM is more than what we need.

Agent Tesla 

Let's begin our case study by downloading samples and web panel from here

We start with the best online scanners to see if there is any information out there. we usually start with virus total



We can quickly draw a conclusion the file is malware; it seems to steal data and information, and it seems to bypass UAC using an old windows seven exploit. 

Please note that it's not always this straightforward. Malware distributor that has and holds a workaround for bypassing the online and offline sandboxes and anti-viruses. 


Let's dive deeper 


Now we know the malware connects to a C&C and we already even have the IP we can dive into the panel and bin code. 

Determining filetype is our first step. On Unix, you can type file command, or if you like GUI. You can use DIE.


As we can see, the file coded with .NET, and the author used .NET 2.0 to maximize execution compatibility. From the reverser point of view, it makes things a lot easier in most cases. It also indicates it's probably not developed by a professional malware author as professional malware developers usually use lower-level languages such as C developing malware.  Now that we know the file type, we can use its right tools to start our reversing. For .net files, we can use dnSpy; it's free, open-source, professional, and created by a .net reversing master. Amazingly it even supports debugging compiled .NET binaries. 

All we have to do is to drop and drag our bin into this magic tool. Next, right-click on the file name and click on Go To Entry Point. 

Now we can see the code.

You may ask what is this rubbish? Well, it simply means the code is obfuscated.

What we do next? We deobfuscate it, of course again 0xd4d create another awsome tool called de4dot. I can not find the recent binary version, so we have to compile it ourselves. 

Run a visual studio PowerShell command prompt and run. 

PowerShell –ExecutionPolicy Bypass build.ps1 

If you are lazy, tell me i'll give you the compiled one. Now we can run it with -d to check if it can detect the obfuscator used here.

C:\Users\USER\Desktop\de4dot\Release\net45>de4dot.exe -d c:\Users\USER\Desktop\0


de4dot v3.1.41592.3405 Copyright (C) 2011-2015 [email protected]

Latest version and source code:

Detected DeepSea 4.1 (c:\Users\USER\Desktop\0abb52b3e0c08d5e3713747746b019692a05


It seems we are lucky it detects DeepSea, and it also supports deobfuscating it. So all we have to is run de4dot again without -d command. 

now we have cleaned binary, and we can finally dive into the code.

public class GForm0: Form


        // Token: 0x06000001 RID: 1 RVA: 0x000142B8 File Offset: 0x000124B8

        public GForm0()




        // Token: 0x06000002 RID: 2 RVA: 0x000143E8 File Offset: 0x000125E8

        private void GForm0_FormClosing(object sender, FormClosingEventArgs e)


            MethodInfo object_;

            GForm0.Entry(out object_);

            new GForm0.Delegate0(object_.Invoke)(null, null);


        // Token: 0x06000003 RID: 3 RVA: 0x000142C6 File Offset: 0x000124C6

        public static void Entry(out MethodInfo entryPoint)


            entryPoint = Thread.GetDomain().Load(GForm1.Bullguard(GForm0.GetByte())).EntryPoint;




we are interested in the entry point 

public static void Entry(out MethodInfo entryPoint)


 entryPoint = Thread.GetDomain().Load(GForm1.Bullguard(GForm0.GetByte())).EntryPoint;



it calls two functions BullGuard() and GetByte(). 

public static byte[] Bullguard(byte[] strng)


    for (int i = 0; i < strng.Length; i++)


        int num = i % GForm1.mykey.Length;

        strng[i] ^= GForm1.mykey[num];


    return strng;


just a XOR encryption, and here is the encryption key.


public static byte[] mykey = new byte[]


            110, 26, 170, 43, 54, 111, 57, 25, 32, 14, 71,108,
            193, 219, 118, 226, 167, 125, 211, 78, 55, 11, 184,
            6, 204, 60, 61, 24, 210, 160, 171,216,152,93,65, 92,
            236, 202, 49, 44, 212, 91, 30, 203, 84, 237, 64, 233,
            byte.MaxValue, 238, 106, 140, 250, 75, 12, 68, 88,177
            183,153,109,239,74,182,154,137,89,206,104,46, 195,
            130, 2, 162, 229, 98, 242, 186, 172, 66, 67, 161, 41,
            156,36,  205, 147, 18, 148, 52, 244, 73, 48, 218, 5, 194



public static byte[] GetByte()


    return new byte[]


        35, 64, 58, 43, 53, 111, 57, 25,








So it decrypts a long array and runs it. As we can see, dnSpy doesn't give us the full array to avoid OOM. 

So here is what we do. We check the size in IL mode (in our case 74240 bytes), and we dump the file using your preferred hex editor. 


Let's create a simple decryptor now. you can get the source code from here.  now if you run decrypter and check the new file, it seems to be obfuscated code again with another unknown obfuscator. We can deobfuscate this one as well using the same method. 

Finally, we have the full source code we can analyze. For example, here is how we can decrypt its strings. 

using System.IO;

using System.Linq;

using System.Runtime.InteropServices;

using System.Security.Cryptography;

 public static string stringDecrypt(string cipherText, string passPhrase)


      byte[] array = Convert.FromBase64String(cipherText);

      byte[] salt = array.Take(32).ToArray<byte>();

      byte[] rgbIV = array.Skip(32).Take(32).ToArray<byte>();

      byte[] array2 = array.Skip(64).Take(array.Length - 64).ToArray<byte>();

      byte[] bytes = new Rfc2898DeriveBytes(passPhrase, salt, 1000).GetBytes(32);

      string @string;

      using (RijndaelManaged rijndaelManaged = new RijndaelManaged())


        rijndaelManaged.BlockSize = 256;

        rijndaelManaged.Mode = CipherMode.CBC;

        rijndaelManaged.Padding = PaddingMode.ISO10126;

        using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor(bytes, rgbIV))


          using (MemoryStream memoryStream = new MemoryStream(array2))


            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))


              byte[] array3 = new byte[array2.Length];

              int count = cryptoStream.Read(array3, 0, array3.Length);



              @string = Encoding.UTF8.GetString(array3, 0, count);





      return @string;


Example usage :

static void Main(string[] args)


       / //sleep
      string output = stringDecrypt("AJ37pG578YxdRIjz1OCGA9tkRR2qprtdRcPtqZVgbTTlGVoz8OdZDUx8JIMUS1EIf7Qx6nEH7ZBZjdxEAaAGABYre37y7Mj8WFufV1POU2YLjeVOYFEilFUl+rhKS+fr", "a3eID1gvyDBh");


Please note some of these crypto functions aren't available in .net core, so you have to use the visual studio on windows. From now, it's just understandable code, and you have to spend time to read it, so if you like to continue, I already uploaded cleaned files here. 


Based on the dynamic analysis result and our static analysis, we have now some good grasp on this malware binary side. 


Analyzing web panel


Now we can move on analyzing agent tesla web panel to hunt some 0days. Again depends on the programming language used by the web panel; we have to use different tools and techniques to speed up the analysis process. In our cases, Agent Tesla uses PHP, which means we can use any editor and XDebug. There is only one issue panel code is also obfuscated using ionCube.So we can't install it this ionCube is commercial software and the best software for obfuscating PHP, so I'm not pointing you directly to how but how to decrypt its files. But you can get decrypted files from here. 


after decryption, we can decrypt client-server communications easily. 


f (isset($_POST["p"])) {

    require "config.php";

    require "mysqli.db.php";

    require "tripledes-class.php";

    $array = parse_ini_string_m(Decrypt($_POST["p"], "E+MTWs/(En()a3456d3h99sdf9sjdgA&%/+vkm&FGNBDSFs5(TRS%cxv"));

    $type = $array["type"];

    $pcname = $array["pcname"];

    $data = $array["logdata"];

    $screenshot = "";

    if (isset($array["screen"])) {

        $screenshot = $array["screen"];





I prefer to run a version of the web panel locally. After decryption The installation is straight forward; all you have to do is to set up MySQL. 


Now we can run it locally. We can easily fuzz or test it. 


5 minutes to 0day RCE 


after analyzing user input for five minutes, I found this. server_processing.php

Here is the interesting part:

// DB table to use

$table = $_GET['table'];

// Table's primary key

$primaryKey = $_GET['primary'];


   $where = base64_decode($_GET['where']); // #1 injection


   $where = "";


$idArray = unserialize(urldecode($_GET['clmns'])); // #2 deserializiation issue. 

echo json_encode(

   SSP::complex( $_GET, $sql_details, $table, $primaryKey, $idArray, NULL, $where)



We have two issues here — first, one controlling where Claus query and second unserializing user input and second. So I searched a bit, and I saw this vulnerability already discovered by other researchers and nicely exploited. As far as I'm aware, the malware author never releases a patch for this vulnerability, so these issues are still unpatched. 

Here is the result of running RCE exploit in our local environment. 


Agent Tesla RCE by prsecurity.
[*] Probing...
[*] Your IP:
[+] uid=501(user) gid=20(staff) groups=20(staff),701(,12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(,398(,399(,400(


We make rules


Now we can control every single tesla C&C panels around the globe, and We also deobfuscate the original binary we can call so we can create a proper signature. Here is just an example

rule agentTesla_functions





        description="Detect agent tesla by KEY"


        $key1={6E 1A AA 2B} // Key 

        $key2={36 6F 39 19} // Key

        $key3= {20 0E 47 6C 81} //Key


        3 of them


please note Key, even though static, is easily replaceable by malware authors, so it's better to signature parts of code that makes it costly for the author to replace. 



Things are not always this straightforward, and you may have to spend a lot more time, usually reversing native files will take more time, but also, there are excellent tools available for native reversing. Now it's your turn I invite all of you to try to analyze an existing C2 malware binary, and it's web panel and create a Yara rule. 


Tweet your results with #MalwareFightBack. Also, send me a link to your analysis so I can share it with others here. 


till then, luvs.

Assist me:
Buy Me a Coffee at