Saturday, January 25, 2014

cuckoo v 1.0 - hardening patch

Some days ago, I found a post talking about cuckoo sandbox going to version 1.0. I was so excited that I decided directly to give it a try.
New fancy web interface (btw don't use the apt-get installation for django but the pip one), and a lot of bug fixes and features.

As I already published some time ago, I tuned a little bit my cuckoo trying to find the best way to evade VM/Sandbox detection techniques (see old posts).
Cuckoo going v1, the patch needed also a v1. I used the patch originally from Alienvault (see alienvault), then modified by Hubert Kromer (see kromer) and I added the last anti-detection mechanism published on my blog to create a patch that works on v1. I think that it should even work on v0.6 but anyway the latest stable is 1.0 so give it a try ! :).

https://github.com/markedoe/cuckoo-sandbox

Pafish:


 waleedassar


Tuesday, January 14, 2014

Malware contribute to global warming

I faced an interesting piece of malware those days. In fact, this is the antivm trick used by the packer that took me some time to figure it out.

It started by a normal day, running malware in sandboxes trying to determine IOCs.
This dropper was detected by 29 AV on VT, and Microsoft named it "Trojan:Win32/Miuref" (MD5: 69ac30eb812d907eda632e870eaa4427).
Usual stuff, the dropper copy a file in %user%\Application Data\tmp and run it (MD5: 7e28e56cfd649cdf3c4382f0f3a0e0e7). This file is also quite well detected by AV vendors and Microsoft also detect it as "Trojan:Win32/Miuref" (should have almost the most functionality).

The interesting part comes here. Running through different sandboxes shows that the process stops at "EnumWindows". At first, I thought that it was standard antivm detecting specific window that I've never heard about when you run the binary in sandboxes. So I traced the binary (VB) and found a more interesting stuff.

Let's start from the beginning. This a VB packer so you need to follow the specific VB process to unpack it. Don't trace the VB VM, it doesn't give you any insight.
I started by putting a breakpoint on "EnumWindows". It is triggered, by surprisingly enough if I go over the call function of "EnumWindows" it runs 50% of my CPU and seems to loop forever. Strange....




By chance, I let it run for more than 10 minutes and pop ! the CPU is lower again and it seems to go to some interesting functions. How could this happen ?
In fact I discovered (maybe it's me and it's well known), that this packer is using the callback function of EnumWindows to trigger the antivm function.

Let's dig deeper in the callback function. One of the parameter of the EnumWindows function is a pointer to the callback. See below:



And if you jump to this address, you will find interesting code.


Standard antidebug code (IsDebuggerPresent, ...), some patching in memory and finally this CPU intensive process.
Standard antidebug stuff:

0016DA4C   64:A1 18000000   MOV EAX,DWORD PTR FS:[18]
0016DA52   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
0016DA55   8078 02 01       CMP BYTE PTR DS:[EAX+2],1  ; FS:30 --> Check being debugged flag
0016DA59   0F84 E4060000    JE 0016E143
0016DA5F   64:A1 30000000   MOV EAX,DWORD PTR FS:[30]
0016DA65   8A40 68          MOV AL,BYTE PTR DS:[EAX+68]
0016DA68   24 70            AND AL,70

0016DA6A   3C 70            CMP AL,70  ; PEB 0x68 --> Check PEB!NtGlobalFlags

Yes, the guys let the packer running in a loop taking a looooong time (10 minutes in my VM but close to 20 minutes on my Cuckoo machines):

0016DADD   90               NOP ; --> Loop to waste time and CPU (ECX = 0D55ABBF)
0016DADE   31C0             XOR EAX,EAX
0016DAE0   31D2             XOR EDX,EDX
0016DAE2   0F31             RDTSC
0016DAE4   90               NOP
0016DAE5   0F6EC8           MOVD MM1,EAX
0016DAE8   0F6EC2           MOVD MM0,EDX
0016DAEB  ^E2 F0            LOOPD SHORT 0016DADD ; --> End of loop to waste time


And yes, if you define manually the timeout of your cuckoo to 20 minutes, you will see the next step, "CreateProcessA". In fact, you don't see more than the new process as cuckoo is loosing connection to the VM after the CreateProcessA and I didn't have time to look at it now. If you have any idea don't hesitate to comment.

The rest is interesting also as the new spawned child from "CreateProcess" is installing an extension in Firefox or Chrome but that could be a subject for an other post.

Happy hunting.


Sunday, October 6, 2013

Cuckoo sandbox hardening (virtualbox)

When analyzing malware, it is always interesting to have a sandbox environment to speed up dynamic analysis. You can always use public (or private) system on the internet (like malwr.com or threatexpert.com) but you miss the complete control of the system (live internet callbacks) and more important you give the sample to the "cloud".
This is the reason why I wanted to test cuckoo sandbox as this is python based and opensource (http://www.cuckoosandbox.org/).

After some time following the (good) official guide, I finished with a fully working virtualbox based sandbox environment.
After firing some sample that I never had time to really analyze, I have to say that I was a little bit disappointed, a lot of sample didn't run at all. I was suspecting that the anti-vm included in actual malware were detecting the virtualbox (or the cuckoo processes?).

There are some articles on how to harden cuckoo running on virtualbox so I started with alienvault blog post (http://www.alienvault.com/open-threat-exchange/blog/hardening-cuckoo-sandbox-against-vm-aware-malware) but it is a bit outdated. I finally found a more recent post (version 0.6) (http://kromer.pl/malware-analysis/installing-and-hardening-latest-cuckoo-sandbox-on-gentoo-linux/). As I'm on  debian or ubuntu I had to modify a bit but this was a good start.

I used the netlog branch, patched the cuckoomon dll (btw if you are on ubuntu change the Makefile (CC parameter) on line 2 with: CC = i586-mingw32msvc-gcc).
After sending the famous "pafish.exe" to my Virtualbox sandbox I was surprised to see that it detects the virtual machine through a registry key "VideoBiosVersion":

Ok, so we could simply add a hook for this registry key but it makes me feel that pafish is not exhaustive in regards to virtualbox detection. To try to have a full list of virtualbox detection I refer to the research of WALIEDASSAR (@waleedassar) that published 9 methods to detect Virtualbox (http://pastebin.com/RU6A2UuB).
To compile it "out of the box" on ubuntu use this code (I modified it a bit to better view the possible detected method in the running VM). I also removed method 9 as this is related to "Shared folder" and I don't have any on the sandbox VM:

//http://waleedassar.blogspot.com - (@waleedassar)
#include <windows.h>


void ToLower(unsigned char* Pstr)
{
char* P=(char*)Pstr;
unsigned long length=strlen(P);
for(unsigned long i=0;i<length;i++) P[i]=tolower(P[i]);
return;
}

int main(int argc, char* argv[])
{
//method 1
HKEY HK=0;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\ACPI\\DSDT\\VBOX__",0,KEY_READ,&HK)==ERROR_SUCCESS)
{
        printf("VirtualBox detected Method 1\n");
system("pause");
ExitProcess(1);
}

//method 2 -- requires Guest Additions to be installed.
HANDLE hF1=CreateFile("\\\\.\\VBoxMiniRdrDN",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,0,OPEN_EXISTING,0,0);
if(hF1!=INVALID_HANDLE_VALUE)
{
                printf("VirtualBox detected Method 2\n");
                system("pause");
ExitProcess(2);
}


//method 3 -- requires Guest Additions to be installed
HMODULE hM1=LoadLibrary("VBoxHook.dll");
if(hM1)
{
                printf("VirtualBox detected Method 3\n");
                system("pause");
ExitProcess(3);
}

//method 4 -- requires Guest Additions to be installed
HK=0;
if( (ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Oracle\\VirtualBox Guest Additions",0,KEY_READ,&HK)) && HK)
{

printf("VirtualBox detected Method 4\n");
                system("pause");
RegCloseKey(HK);
ExitProcess(4);
}

//method 5
HK=0;
char* subkey="SYSTEM\\CurrentControlSet\\Enum\\IDE";
if( (ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,KEY_READ,&HK)) && HK )
{
unsigned long n_subkeys=0;
unsigned long max_subkey_length=0;
if(ERROR_SUCCESS==RegQueryInfoKey(HK,0,0,0,&n_subkeys,&max_subkey_length,0,0,0,0,0,0))
{
if(n_subkeys)  //Usually n_subkeys are 2
{
     char* pNewKey=(char*)LocalAlloc(LMEM_ZEROINIT,max_subkey_length+1);
 for(unsigned long i=0;i<n_subkeys;i++)  //Usually n_subkeys are 2
 {
     memset(pNewKey,0,max_subkey_length+1);
     HKEY HKK=0;
                          if(ERROR_SUCCESS==RegEnumKey(HK,i,pNewKey,max_subkey_length+1))
 {
  if((RegOpenKeyEx(HK,pNewKey,0,KEY_READ,&HKK)==ERROR_SUCCESS)  && HKK)
  {
    unsigned long nn=0;
    unsigned long maxlen=0;
    RegQueryInfoKey(HKK,0,0,0,&nn,&maxlen,0,0,0,0,0,0);
                                     char* pNewNewKey=(char*)LocalAlloc(LMEM_ZEROINIT,maxlen+1);
if(RegEnumKey(HKK,0,pNewNewKey,maxlen+1)==ERROR_SUCCESS)
{
      HKEY HKKK=0;
          if(RegOpenKeyEx(HKK,pNewNewKey,0,KEY_READ,&HKKK)==ERROR_SUCCESS)
  {
       unsigned long size=0xFFF;
       unsigned char ValName[0x1000]={0};
                   if(RegQueryValueEx(HKKK,"FriendlyName",0,0,ValName,&size)==ERROR_SUCCESS)
{
        ToLower(ValName);
        if(strstr((char*)ValName,"vbox"))
{
               printf("VirtualBox detected Method 5\n");
               system("pause");

       ExitProcess(5);
}
}
RegCloseKey(HKKK);
  }
}
LocalFree(pNewNewKey);
RegCloseKey(HKK);
  }
 }
 }
 LocalFree(pNewKey);
}
}
RegCloseKey(HK);
}

//method 6
HK=0;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System",0,KEY_READ,&HK)==ERROR_SUCCESS)
{
unsigned long type=0;
unsigned long size=0x100;
char* systembiosversion=(char*)LocalAlloc(LMEM_ZEROINIT,size+10);
if(ERROR_SUCCESS==RegQueryValueEx(HK,"SystemBiosVersion",0,&type,(unsigned char*)systembiosversion,&size))
{
 ToLower((unsigned char*)systembiosversion);
 if(type==REG_SZ||type==REG_MULTI_SZ)
 {
 if(strstr(systembiosversion,"vbox"))
 {
       printf("VirtualBox detected Method 6 v1\n");
               system("pause");

ExitProcess(6);
 }
 }
}
LocalFree(systembiosversion);

type=0;
size=0x200;
char* videobiosversion=(char*)LocalAlloc(LMEM_ZEROINIT,size+10);
if(ERROR_SUCCESS==RegQueryValueEx(HK,"VideoBiosVersion",0,&type,(unsigned char*)videobiosversion,&size))
{
if(type==REG_MULTI_SZ)
{
char* video=videobiosversion;
while(*(unsigned char*)video)
{
ToLower((unsigned char*)video);
if(strstr(video,"oracle")||strstr(video,"virtualbox") )
{
       printf("VirtualBox detected Method 6 v2: %s\n",video);
               system("pause");

ExitProcess(6);
}
video=&video[strlen(video)+1];
}
}
}
LocalFree(videobiosversion);
RegCloseKey(HK);
}
//method 7 - requires guest additions to be installed.
HANDLE hxx=CreateFile("\\\\.\\pipe\\VBoxTrayIPC",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
if(hxx!=INVALID_HANDLE_VALUE)
{
               printf("VirtualBox detected Method 7\n");
               system("pause");

CloseHandle(hxx);
ExitProcess(7);
}
        //method 8 - requires guest additions installed
        HWND hY1=FindWindow("VBoxTrayToolWndClass",0);
HWND hY2=FindWindow(0,"VBoxTrayToolWnd");
if(hY1 || hY2)
{
printf("VirtualBox detected Method 8\n");
                system("pause");

ExitProcess(8);
}

printf("Nothing detected\n");
system("pause");

}

To compile it use this:
i586-mingw32msvc-gcc -Wall -std=c99 -s -O2 -lws2_32 -lshlwapi -o waleedassar_detectvbox.exe waleedassar_detectvbox.c


You should have a running .exe to send to the sandbox:

VM detected with method 1.
When you look at the code you can see that method 1 is looking at a registry key under HKEY_LOCAL_MACHINE\HARDWARE\ACPI\DSDT with the name VBOX__:

so let's add a hook for this detection. Open "hook_reg.c" add this lines under the hook of "RegOpenKeyExA" (I added also some possible detection):

    else if (strstr(lpSubKey, "VBOX") != NULL) {
        ret = 1;
        LOQ("s", "Hardening", "Faked RegOpenKeyExA return");
    }
    else if (strstr(lpSubKey, "vbox") != NULL) {
        ret = 1;
        LOQ("s", "Hardening", "Faked RegOpenKeyExA return");
    }
    else if (strstr(lpSubKey, "oracle") != NULL) {
        ret = 1;
        LOQ("s", "Hardening", "Faked RegOpenKeyExA return");
    }
    else if (strstr(lpSubKey, "virtualbox") != NULL) {
        ret = 1;
        LOQ("s", "Hardening", "Faked RegOpenKeyExA return");
    }

Let's do the same with the "VideoBiosVersion" that we saw earlier with "pafish.exe". Add this under the hook of "RegQueryValueExA" and "RegQueryValueExW":

    else if (strstr(lpValueName, "VideoBiosVersion") != NULL) {
        ret = ERROR_SUCCESS;
        LOQ("s", "Hardening", "Faked RegQueryValueExA return");
    }

Compile the cuckoomon dll again and you should have an hardened sandbox that will give you "hopefully" more interesting results:



Feel free to comment. Happy sandboxing !