Thursday, September 11, 2014

Looking Glasses with Bacon

This is my first post on the VRT blog and I would like to introduce myself. I am Mariano Graziano, an Italian third-year Ph.D. student at the Software and Systems Security Group at Institut Eurecom in Sophia-Antipolis (France) under the supervision of professor Davide Balzarotti. My research interests are memory forensics and automated malware analysis and currently I am an intern at Cisco in the Talos Security Intelligence and Research Group under the guidance of Alain Zidouemba for the next three months. This post is not about my current project at Cisco but is about my DEF CON talk.

At DEF CON 22 last month, I presented with my former colleague Luca Bruno an offensive research about Looking Glass software security. At the time we contacted all the Autonomous Systems (ASes) involved, as well as all the maintainers of the affected open-source Looking Glass software, but unfortunately, responsible disclosure is not the panacea and as result either some issues have not been addressed by the software maintainers or the AS local sysadmins did not update their Looking Glass instances.

In this post I give a brief overview about the research, then I introduce the vulnerabilities and web misconfigurations we uncovered, and finally I show how the Talos Security Intelligence and Research Group covered  all the CVEs with Snort rules, so that users can protect their backbone infrastructure.

Overview

Let's start by defining what a looking-glass is. A looking-glass is a web-application that provides a restricted set of operations on AS routers and is commonly written in Perl or PHP. This web application is directly connected to the routers (via telnet or SSH), the commands go from the web form to the router console and the answer is printed back. The attack vector is obviously from the web, in this threat model we have two kind of problems: web misconfigurations and common web vulnerabilities in the web interface. Web misconfigurations might lead an attacker to the backbone router credentials with a simple Google Dork while a severe vulnerability might lead to a command injection from the web form to the router console. During our research we have found both issues and six CVE numbers have been assigned by the MITRE affecting 45 ASes all over the world.

For a detailed analysis please have a look at either the WOOT 2014 paper or our DEF CON 22 slides.

Vulnerabilities

We have found six vulnerabilities on four open-source Looking Glass software (MRLG4PHP, Cougar LG, Cistron LG and MRLG). Two CVEs (CVE-2014-3927 and CVE-2014-3926) are common web vulnerabilities, three are simply web misconfigurations (CVE-2014-3928, CVE-2014-3929 and CVE-2014-3930) and the last one is a memory corruption in a third-party binary shipped in a Looking Glass installation package. Below you can find the list of these issues:

  • CVE-2014-3927: Remote command injection in router's console via "argument" parameter
  • CVE-2014-3926: XSS in <title> via "addr" parameter
  • CVE-2014-3928: Unsafe configuration file path/ACL
  • CVE-2014-3929: Unsafe SSH keypairs path in default config
  • CVE-2014-3930: Unsafe configuration file path/ACL
  • CVE-2014-3931: Remote memory corruption in fastping (SUID binary)

The Snort way

Talos wrote six Snort rules to address all the above issues. The rules for the web misconfigurations prevent the attacker to retrieve the configuration file or list the configuration directories (have a look at sid:31709, sid:31708 and sid:31727 for all the details). The memory corruption bug referenced by CVE-2014-3931 should be avoided by sid:31767, only the default ICMP Echo Reply payloads are allowed. The web vulnerabilities are addressed by sid:31741 and sid:31766, these rules provide the missing input sanitization and should avoid basic exploitation attempts.


We recommend that all Snort users running the affected Looking Glass software deploy the mentioned rules.
Add to Technorati Favorites Digg! This

Tuesday, September 9, 2014

Microsoft Update Tuesday September 2014: another generally light month but with a significant IE bulletin



This month’s Microsoft Update Tuesday is pretty light save for the Internet Explorer bulletin. While there’s only a total of 4 bulletins, they cover a total of 42 CVEs. The IE bulletin, as is usual, has the most updates for bugs and is rated critical. It covers a total of 37 CVEs. The other three bulletins are rated as important and provide updates for the remaining five vulnerabilities.

MS14-052 is the IE bulletin and is rated critical. It covers a total of 37 CVEs. Of these 37 CVEs, 36 are remote code execution vulnerabilities, the other one is an information disclosure vulnerability (CVE-2013-7331). This last vulnerability is publicly known and under active exploitation. This vulnerability allows attackers to use Microsoft’s XMLDOM ActiveX object to gain information on local drive and network settings. The attack can be used to detect if files or folders are present on the machine due to different error messages being returned depending on if the files or folder exist or not. An attacker can similarly figure out internal IP addresses using this vulnerability. The remaining 36 vulnerabilities are mostly the result of use-after-free vulnerabilities.

The three remaining bulletins are all rated as important:

Bulletin MS14-053 deals with a single CVE (CVE-2014-4072) in .NET. The vulnerability results in a Denial of Service. This is due to a hash collision that can be exploited by an attacker, which will result in resource exhaustion.

CVE-2014-4074 is fixed by bulletin MS14-054, it deals with a vulnerability in the Windows Task Scheduler that could allow a logged on user to schedule a task that would run code at the system level.

The final bulletin is MS14-055 and fixes three vulnerabilities in Lync. Two of the vulnerabilities, CVE-2014-4068 and CVE-2014-4071, could result in Denial of Services. An attacker could create a legitimate meeting and then modify the SIP information, which would result in a DoS on the Lync server. The third vulnerability that is covered by this bulletin is CVE-2014-4070 and can result in information disclosure due to a Cross Site Scripting (XSS) vulnerability on the server.

To address these issues, Talos has the following SIDs:  29821-29822, 30110-30113, 31782-31797, 31799-31802, 31811-31812
Add to Technorati Favorites Digg! This

Thursday, September 4, 2014

Malware Using the Registry to Store a Zeus Configuration File

This blog was co-authored by Andrea Allievi. 

A few weeks ago I came across a sample that was reading from and writing a significant amount of data to the registry. Initially, it was thought that the file may be a binary, but after some analysis it was determined that the file is a configuration file for Zeus. Within this blog post we take a look at our analysis of the data I/O in the registry.

Initial Stages of Infection

The scope of this paper is the analysis of the registry write. This section is a brief overview of what happens when the malware is executed.


  1. Unpacks
  2. Creates a copy of itself in the tmp directory
  3. Injects itself into explorer.exe
  4. Starts a thread that executes the injected code

The code injected into Explorer.exe becomes the focus of our analysis. To get started, an infinite loop was added to the entry point of the injected code and Ollydebug was used to attached to Explorer.exe. Debugging injected code in this manner was previously covered here.

Analysis

Registry Key NamesAfter attaching the debugger and prior to continuing execution, a breakpoint is set on Advapi32.RegSetValueExW() before the large data write is made. This breakpoint is tripped multiple times by multiple threads within Explorer.exe. Most of the time the threads are related to the injected ZBot code.

It turns out that the same thread is used consistently for writing to this registry key.  Several sub-keys are created to store data that the application uses at a later time.The names of the sub-keys are created using an index value that is combined with other data to appear random. For instance, the key “2f0e9h99” was created by combining a hash of the User SID with the index value 0x9A. Throughout this paper, the registry key will be referenced by either name or index. 

A Series of Registry Writes


This section establishes a pattern to the registry activity that can be used to help figure out what the malware is accomplishing with the registry I/O. The registry activity centers around writing to the following key:
  • HKUSERS\<sid>\Software\Microsoft\Ujquuvs.

The “ujquuvs” is dynamically generated by the application and will change between executions.


zbot-regdata-prior to initial large data write.png
Ujquuvs Registry Key Prior to 

Prior to the first registry write of interest the Ujquuvs sub-key contains the values shown in the above graphic. Throughout this section we’ll see that new value names are generated and data is cycled between the keys. 

One of the first chunks written to the registry value 2f0e9h99 is a binary string that is 475 bytes in length. The following graphic shows the call to the Windows Advapi32.RegSetValueExW() procedure made by the malware.


zbot-regset-1db-screen1.png
RegSetValueExW() Stack


zbot-bin-regdata-screen1.png
First Registry Write to 2f0e9h99

The above graphic displays the binary string data that was written to the registry. Although 475 bytes is a significant chunk of data written to the registry it is not what caused an alarm. The registry write I am looking for is greater than 3000 bytes. 

zbot-bin-regdata-screen2.png
Second Registry Write to 2f0e9h99
Another 475 byte write occurs, but the data is different than the first write. It is worth noting that although the data is different the first four bytes appear to be the same “5D BB 95 50” pattern. This may be a header used to distinguish the data.

The next call to RegSetDataExW will write 3800 bytes to the registry.  The binary data was replaced with alphanumeric data (possibly base64). Another assumption can be made. The original binary data is encoded and then stored back to the registry.

zbot-alpha-regdata-screen1.png
Alphanumeric Data Written to 2f0e9h99
This is one of the large data writes that was flagged by the sandbox. Continuing on we see several more data writes all of which are variations of the above. The data cycles between binary strings and alphanumeric strings, and the string lengths vary. One of the largest data writes was an 7200 byte alphanumeric string. 

Registry Reads

Along with the registry writes there are usually corresponding registry reads. The data located in 2f0e9h99 is pulled into a buffer and manipulated by the application.

Once the data is read, decoded from alphanumeric encoding to a long list of 475 byte chunks of binary data. These chunks of data contain a hash to identify specific chunks within the list. Whenever a new chunk of data is received the data contained in 2f0e9h99 is decoded and the hash value of the received chunk of data is compared against each chunk that exists already within the registry. If these hash values match, then the that registry data chunk is replaced with the incoming data. Otherwise the data is appended to the bottom of the list.

Once the  input queue is empty the calls to read or write to the registry stop. The thread has not been killed, but it is (most likely) suspended until some event occurs.

The next section combines these findings with further analysis to track down the source of the registry writes.

ZBotThread_1 Procedure


Walking through the executable with a debugger led us to the source of the registry writes. A thread is created and starts executing the code at address 0x41F579. From here on out this code is going to be referred to as ZBotThread_1(). This procedure is the backbone for all activity related to this registry key.

screenshot_WSA_code.png
Network Socket Loop


After  several instructions for initializing various data structures, ZBotThread_1() initializes a network socket to communicate with a remote server.  Once traffic is received the IP address is verified against an IP blacklist of network address ranges that exists within a data structure used throughout the application. These IP Address ranges appear to be owned by various AV vendors (indicated here). Here is the list of blacklisted address ranges with the corresponding netmasks:
  • 64.88.164.160      255.255.255.224
  • 64.233.160.0 255.255.224.0
  • 65.52.0.0 255.252.0.0
  • 66.148.64.0 255.255.192.0
  • 84.74.14.0 255.255.255.0
  • 91.103.64.0 255.255.252.0
  • 91.200.104.0 255.255.255.0
  • 91.212.143.0 255.255.255.0
  • 91.212.136.0 255.255.255.0
  • 116.222.85.0 255.255.252.0
  • 128.130.0.0 255.254.0.0
  • 131.107.0.0 255.255.0.0
  • 150.26.0.0 255.255.255.0
  • 193.71.68.0 255.255.255.0
  • 193.175.86.0 255.255.255.0
  • 194.94.127.0 255.255.255.0
  • 195.74.76.0 255.255.255.0
  • 195.164.0.0  255.255.0.0
  • 195.168.53.48 255.255.0.0
  • 195.169.125.0 255.255.255.0
  • 204.8.152.0 255.255.248.0
  • 207.46.130.0 255.255.0.0
  • 208.118.60.0 255.255.240.0
  • 212.5.80.0 255.255.255.192
  • 212.67.88.64 255.255.224.0
Once the IP address is verified the payload is decrypted and the data is initialized into the following data structure (sub_41F9C6):

ZBOT_SOCKET_DATA structure


Throughout this post we will refer to this as ZBOT_SOCKET_DATA. Each datagram payload contains this data structure. The lpDataBuff points to a buffer that contains the data that will eventually be written to the registry. 

In addition, the dataBuffHeader[0x2C]  contains the first 44 bytes of the decrypted received data. These bytes contain critical information about the entire data chunk.

After a few checks to verify the integrity of the data, ZBotThread_1 calls AnalyseSockDataAndUpdateZBot (sub_43D305). This function will take the 20 byte hash of the data contained within the data chunk header (first 44 bytes) and compares it against a list of other hashes. This list of hashes is built out of previously received datagrams.  If the hash is part of the list then the data is dropped. Otherwise, the hash is appended to the end of the list. 

 Next, AnalyseAndFinalizeSockData (sub_41D006) is called to begin the process of adding the data to the registry. Once inside the function, the data type (dataBuffHeader+0x3) is checked. There are several different data types, but the one that is relevant for the purposes of this blog post is type 0x6. This signifies the end of the data stream and the malware can proceed to save the data to registry key 2f0e9h99


The type 0x6 code branch calls VerifyFinalSckDataAndWriteToReg (sub_436889). This function strips the 0x2C length header from the socket data before verifying the integrity using RSA1.


Finally, if the data integrity is good, the WriteSckDataToReg function is called.



Writing Socket Data to the Registry

The previously received socket data has already been written to registry key 2f0e9h99. At this point, the socket data needs to be merged with the data contained within the registry key. Before this can occur, the data is currently alphanumerically encoded (see the registry write section above). The decoded data is a series of 0x1D0 hex byte chunks. Each chunk is a ZBOT_SOCKET_DATA structure.

encoded data structure.png
Alphanumeric Encoded Data in Memory
The hash of the socket data is compared against the hash of each chunk contained within the list of chunks. If the hashes match, then that registry data chunk is replaced with the network socket data. Otherwise the network socket data is appended to the end of the list.

Once the update is completed the registry data is (once again) alphanumerically encoded and written back to the 2f0e9h99 registry key.
It’s worth noting that our sample dropper can encode the original data in several different ways: Base64, and 3 customized XOR algorithms (see function at VA 0x4339DE for all the details). 

Summary

Using the registry as a way to store and update a configuration is a clever idea. The multiple writes and reads that come with constructing the file with a registry key will raise alarms. It’s what originally grabbed our interest.

This blog post covers a small percentage of the functionality of this malware sample. Some of the functionality that we uncovered denote a high level of sophistication by the author. We strongly encourage others to download a copy and crack open their debuggers.

Sample MD5 Hashes:
     Dropper: 15136D615297C16D1FED67F2A8C11C37
     Injected Code: B4A00F4C6F025C0BC12DE890A2C1742E

Add to Technorati Favorites Digg! This

Wednesday, August 20, 2014

Discovering Dynamically Loaded API in Visual Basic Binaries

Performing analysis on a Visual Basic (VB) script, or when Visual Basic is paired with the .NET Framework, becomes an exercise of source code analysis. Unfortunately when Visual Basic is compiled to a Windows Portable Executable (PE) file it can become a nightmare for many malware analysts and reverse engineers.

Why is it used by malware?

Visual Basic binaries have a reputation for making an analysts job difficult due to the many aspects of its compilation that differ from standard C/C++ binaries. To analyze a VB PE binary it helps to be familiar with the VB scripting syntax and semantics since their constructs will appear throughout the binary's disassembly. VB binaries have their own API interpreted by Microsoft's VB virtual machine (VB 6.0 uses msvbvm60.dll). Many of the APIs are wrappers for more commonly used Win32 APIs leveraged from other system DLLs.

Reverse engineering VB binaries will often involve reverse engineering VB internals for various VB APIs, a task dreaded by many. The entry point of a VB program diverts from the typical C/C++ or even Borland Delphi binary. There is no mainCRTStartup or WinMainCRTStartup function that initializes the C runtime and calls the developer defined main or WinMain function. Instead the Entry Point (EP) looks like this:

     004014A4 start:
     004014A4                 push    offset dword_40159C
     004014A9                 call    ThunRTMain
     004014A9 ; -----------------------------------------------------------------
     004014AE                 dw 0
     004014B0                 dd 0
     004014B4                 dd 30h, 40h, 0
     004014C0                 dd 0E8235672h, 403451C6h, 0AAF1D6B9h, 88BB31A6h, 0
                              ...

The call to ThunRTMain is just wrapper to call VB API (msvbvm60!ThunRTMain). The only argument to ThunRTMain is the address of an object. This structure is documented in several places online and Reginald Wong developed an IDA Pro IDC script (https://www.hex-rays.com/products/ida/support/freefiles/vb.idc) to parse the structure and label its members within the IDB. This will aid in understanding the objects used within the binary and their corresponding methods.

At this point it becomes an exercise of understanding the VB program based on the VB APIs used (there are some caveats, e.g. calls to Zombie_AddRef). Generally, VB programmers will have access to all the functionality they need through msvbvm60.dll, however, it is is possible to dynamically load API not available within the VB API through the DllFunctionCall function. The name implies the function will call the supplied function within a DLL, but this is not true.

How does it work?

DllFunctionCall takes in a structure that defines the wanted library and exported function, loads the library specified into memory, locates the address of the function provided, and returns the address. To know this we have to dive into the VB engine. Opening msvbvm60.dll in IDA Pro and navigating to the disassembly for DllFunctionCall we are met with a fairly small function (See figure DllFunctionCall graph). Within the first code block we see a call to sub_7342A127 with arg_0 as its first argument. At this point, all we know is DllFunctionCall has one argument that should provide (at a minimum) the library and export name. Based on what we currently know we can define our structure:

    typedef struct _DllFunctionCallStruct {
        void * lpLibraryOrExportName;
        void * lpExportOrLibraryName;
    } DllFunctionCallStruct;


IDA Pro Graph View of msvbvm60!DllFunctionCall
msvbvm60!DllFunctionCall 

Going to the Structures window I created the structure, changed DllFunctionCall and sub_7342A127 function headers to reflect that arg_0 is typed as a DllFunctionCallStruct * and rename arg_0 in both functions to "struct". By examining sub_7342A127 we see this is where all the work happens (See sub_7342A127 function graph).

IDA Pro Graph View of msvbvm60!sub_7342A127
msvbvm60!sub_7342A127

Analyzing the disassembly within sub_7342A127 we see our DllFunctionCallStruct structure assigned to ESI (first red box in figure sub_7342A127 part 1 below) and our assumptions of its composition is incorrect. The second red box highlights a new, unknown, member within our DllFunctionCallStruct structure. A new structure member is accessed at offset 0x0C (12) and saved into EDI (or &DllFunctionCallStruct + 0x0C).

IDA Pro Text View of msvbvm60!sub_7342A127 Part 1
msvbvm60!sub_7342A127 part 1

The new member is accessed at 0x7342A14A (first red box in figure sub_7342A127 part 2 below), however, it is accessed via an offset and a dereference. This tells us the new member at offset 0x0C is a pointer to a value, most likely a structure, with its own members (e.g. a member at offset 4). The call to LoadLibraryA (second red box in figure sub_7342A127 part 2 below) helps to fill in some of the assumptions we have made so far concerning DllFunctionCallStruct.

IDA Pro Text View of msvbvm60!sub_7342A127 Part 1
msvbvm60!sub_7342A127 part 2

The first member of DllFunctionCallStruct (&DllFunctionCallStruct + 0) must be a pointer to a character array containing the library name to be loaded (e.g. "kernel32.dll), thus the second member is a pointer to the string representing the exported function (e.g. “CreateFileA”). Finally, EDI is used to save the return value of LoadLibraryA (third red box in figure sub_7342A127 part 2 above), corroborating our suspicion that EDI is a structure. Below we create a new structure DynamicaHandles and rewrite DllFunctionCallStruct:
            typedef struct _DynamicHandles {
    0x00        
    0x04    HANDLE hModule;
    0x08    
            } DynamicHandles;

            typedef struct _DllFunctionCallStruct {
    0x00        LPCSTR lpDllName;
    0x04        LPTSTR lpExportName;
    0x0C        DynamicHandles sHandleData_unk;
    0x10
            } DllFunctionCallStruct;

Continuing our analysis we confirm DllFunctionCallStruct + 4 is a pointer to the exported function name. However, we also see that DllFunctionCallStruct contains a byte at offset 0x0A (10) that is used for the comparison at 7342A16C. Examining both possible branches it becomes clear that this byte is significant for the function to determine if GetProcAddress is being called with the exported function's string representation or the export function's ordinal. After GetProcAddress is called arg_8 is used to save the value (arg_8 will be renamed to fnAddress) and its value is saved into the DynamicHandles structure at offset 8.

IDA Pro Text View of msvbvm60!sub_7342A127 Part 3
msvbvm60!sub_7342A127 part 3

Piecing this together DllFunctionCall argument is the structure defined below:
            typedef struct _DynamicHandles {
    0x00        DWORD dwUnknown;
    0x04        HANDLE hModule;
    0x08        VOID * fnAddress
    0x0C
            } DynamicHandles;

            typedef struct _DllFunctionCallStruct {
    0x00        LPCSTR lpDllName;
    0x04        LPTSTR lpExportName;
    0x08
    0x09
                // 4 bytes means it is a LPTSTR *
                // 2 bytes means it is a WORD (the export's Ordinal) 
    0x0A        char sizeOfExportName;    
    0x0B
    0x0C        DynamicHandles sHandleData;
    0x10
            } DllFunctionCallStruct;

Putting it all Together

Great, we understand enough of the structure passed into DllFunctionCall, but how does this benefit us? It will aid us in locating dynamically loaded API functions in a VB binary. Most VB binaries making use of DllFunctionCall will have wrapper functions that follow this format:
          mov     eax, dword_ZZZZZZZZ
          or      eax, eax
          jz      short loc_XXXXXXXX
          jmp     eax
    loc_XXXXXX:
          push    YYYYYYYYh
          mov     eax, offset DllFunctionCall
          call    eax ; DllFunctionCall
          jmp     eax
 
The memory address 0xYYYYYYYY represents the address of the DllFunctionCallStruct. This structure is usually saved as a global variable. The sHandleData field within the DllFunctionCallStruct points to another global variable in memory. The fnAddress field within the DynamicHandles structure is accessed directly via the offset dword_ZZZZZZZZ. If the exported function has not been loaded into memory yet then DllFunctionCall will be invoked, thereby populating the value stored at dword_ZZZZZZZZ, and any sequential calls will directly call the exported function.

In malware, dozens or even hundreds of these wrapper functions can be found. Going through each reference to DllFunctionCall, applying the DllFunctionCallStruct and DynamicHandles structures, labelling the structure and direct address to the fnAddress field, and defining/renaming the function is a lot of work. To get around this cumbersome task I've created a IDA Python script that will perform these monotonous tasks and print out a listing of all the dynamically loaded API used by the binary.

As an example, a VB compiled binary may contain the below undefined section of code (see figure Undefined Code below). Note that IDA Pro was unable to make a function out of this set of instructions, didn’t interpret “push 4038D8h” as an offset within the binary, and didn’t recognize the ASCII string or offset to it starting at virtual address 0x004038CC.

IDA Pro Text View of undefined DllFunctionCall wrapper
Undefined Code

After the IDA Python script runs, the disassembly is cleaned up, a function is defined, the structures are applied, offsets are labeled, strings are defined, and appropriate names are given to the function and global variables. This will be applied to all DllFunctionCall wrapper functions generated by the compiler.

IDA Pro Text View of Defined DllFunctionCall wrapper and structures after running IDA Python Script
Defined Code

The script is freely available and comes "as is," depending on your situation it may need to be altered. For example if the VB binary you are analyzing obfuscates the strings associated with library name or export name then the strings will need to be de-obfuscated first.

Download IDA Python Script: vb_DllFunctionCall.tar.gz
Add to Technorati Favorites Digg! This