Auteur Sujet: [FireEye]Reversing Malware Command and Control: From Sockets to COM  (Lu 2548 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne igor51

  • Admin
  • Mega Power Members
  • *****
  • Messages: 10419
Reversing Malware Command and Control: From Sockets to COM


 

On a Windows host there is more than one way for a program to
    communicate across the internet.  When reverse engineering a piece
    of malware it is of critical importance to understand what API is
    being used and how it works so that you may gain an understanding of
    the data sent and received as well as command structure and internal
    protocol if applicable.  The choice of networking API also effects
    how you craft your indicators (more on this later). I break Windows
    Malware Command and Control communications into four API categories:
    Sockets, WinInet, URLMon and COM. The primary focus of this article
    is COM, since it is the rarest, least understood and most difficult
    to reverse engineer.


 

Sockets


 

The first group, sockets, is the most widely known as it is
    the same basic networking API found on Unix. It provides a somewhat
    raw session level access to a TCP or UDP session.  It is provided
    primarily by the DLL ws2_32.dll, though it has a storied history.
    Any application using the socket API must manually craft any higher
    level protocol such as HTTP.  A socket object is created with a call
    to the function socket().
    It is during this call where the protocol is specified, TCP or UDP.
    For a TCP client like most malware backdoors, the function     style="color: rgb(0,0,255);">connect() must be called, which
    performs the TCP three-way handshake and paves the way for reading
    and writing of data.  A server program on the other hand will
    typically call bind() and
      listen() to wait for
    connections (although     style="color: rgb(0,0,255);">bind() can also be used client
    side to force a socket to a specific egress port).  The
      functions send()
      and recv() are
    frequently used to transfer data across the wire for TCP connections
    and sendto() and       style="color: rgb(0,0,255);">recvfrom() are traditionally
    used for UDP connections.  From a malware analysis perspective this
    makes things simple, if I need to understand what information a
    piece of malware is expecting in response to its beacon packet I can
    typically look for calls to the
    recv()
function and see how the code that follows inspects
    the data it reads from the wire.  On Windows though, sockets can be
    used interchangeably with most operations as if they were a file
    handle.  For example, a process (like cmd.exe) could be spawned with
    a network socket specified as its standard input and standard output
    and that process would automatically communicate across the network.
    To learn the socket API in-depth I recommend reading the late W.
    Richard Stevens' classic book UNIX Network Programming Volume 1.
    The drawback to using the Socket API is that interacting with any
    higher level protocol such as HTTP must be done so manually.  This
    allows a lot of flexibility in how the malware crafts its requests
    but everything must be laid out explicitly.  Malware authors will
    frequently introduce subtle nuance differences between the way their
    HTTP traffic looks on the wire and the way most web browsers look.
    These small differences make great network signatures!


 

WinInet


 

The WinInet API requires much less work than the socket
    API.  It is a convenience API which simplifies the interaction to
    higher level protocols such as HTTP, FTP and even GOPHER!  To begin
    using the WinInet API to talk to a remote host you first need to
    call InternetOpen()
    followed by     style="color: rgb(0,0,255);">InternetConnect() or     style="color: rgb(0,0,255);">InternetOpenURL().  Once the
    internet has been opened and a connection established, to perform
    and HTTP request you can call the functions     style="color: rgb(0,0,255);">HttpOpenRequest() to make a
    request handle and     style="color: rgb(0,0,255);">HttpSendRequest() to send the
    request.      style="color: rgb(0,0,255);">InternetReadFile() may then be
    called to read any response from the server.   It can also be used
    to read data from an FTP session.  The     style="color: rgb(0,0,255);">InternetWriteFile() function can
    also be used generically in place of any protocol specific function
    where data needs to be sent across the wire.   The HTTP functions
    provide the programmer the ability to configure most of the options
    one would expect in an HTTP request header such as the User-Agent
    string.  Not all of these values have to be specified though, and
    the system default will be used if none is specified.  The malware
    programmer doesn't have as much flexibility to introduce subtle
    anomalies in the request structures though like they can with
    sockets, and left with default settings the malware's HTTP requests
    will look virtually identical to legitimate Internet Explorer
    traffic on the network.


 

URLMon


 

The URL Monikers API provided by the DLL urlmon.dll
    provides yet another API for performing internet communications.  In
    the back end it uses COM but I choose to list this as a separate
    category from the later discussion of COM because using this API is
    an abstraction away from the ugly, obscure-t0-reverse methods of
    direct COM interaction.  The most popular function in the URLMon
    arsenal, from a malware perspective, is the one-punch knockout
    function     style="color: rgb(0,0,255);">URLDownloadToFile(). Rarely in
    the Win32 API does one function do so much work.  You provide this
    function a URL (for any protocol IE understands), a filename and it
    uses COM to force Internet Explorer to download the resource to the
    specified filename.  This is very popular with dropper malware which
    simply needs to download an EXE from a website and launch it.  You
    might also run into the     style="color: rgb(0,0,255);">URLDownloadToCacheFile()
    function which will download a specified URL to the browser cache
    and return the name of the file it downloaded to.      style="color: rgb(0,0,255);">URLOpenStream() and     style="color: rgb(0,0,255);">URLOpenPullStream() can be used
    to download a URL to a buffer in memory, but these functions are
    rarely used in malware.

Controlling Internet Explorer with COM


 

Using COM for malware command and control has a number of
    advantages for the malware author.  From a live response/volatile
    data/memory analysis perspective it obscures the source of malicious
    traffic because all communication with the remote host will be
    performed within an iexplore.exe process instead of the malware
    process.  From a reverse engineering perspective it makes things
    complicated because it is not immediately clear that the malware is
    doing network communications at all when first inspected with static
    analysis.  COM has fallen out of fashion with many of today's
    programmers and is less understood than many other technologies used
    in modern software.  Malware analysts may be particularly unfamiliar
    with the inner workings of COM, depending on the programming
    background in the Win32 world.

Before any COM object can be
    instantiated, the function     style="color: rgb(0,0,255);">CoInitialize() must be called to
    initialize the COM library.  Once this is successfully initialized a
    call can be made to     style="color: rgb(0,0,255);">CoCreateInstance() to create an
    instance of a particular COM object, such as Internet Explorer.  In
    order to understand which object is being instantiated at this point
    you must inspect the first argument to the     style="color: rgb(0,0,255);">CoCreateInstance() function,
    which will be a CLSID value which is a unique identifier for a COM
    object.  Here is the call to     style="color: rgb(0,0,255);">CoCreateInstance() found in a
    malware sample which used COM:


            href="https://www.fireeye.com/content/dam/legacy/ammo/cocreateinstance_screen1.png">        class="alignnone size-full wp-image-1405"
        src="https://www.fireeye.com/content/dam/legacy/ammo/cocreateinstance_screen1.png"
        alt="A Call to CoCreateInstance()" width="269"
  height="72" />

At first glance it's difficult to tell what
    object this function is instantiating because IDA simply shows you
    the data type of the first value instead of any type of meaningful
    interpretation of it.  The first argument in this example code is a
    global variable (a constant actually) that exists at some location
    in the binary that has been given the label "rclsid" by
    IDA Pro.  If you double click on this first argument IDA Pro will
    take you to view the variable as it would look in memory:


            href="https://www.fireeye.com/content/dam/legacy/ammo/rclsid_screen1.png">        class="alignnone size-full wp-image-1406"
        src="https://www.fireeye.com/content/dam/legacy/ammo/rclsid_screen1.png"
        alt="COM CLSID value in memory" width="366"
  height="72" />

This CLSID value is recognized as a data
    structure by IDA and is shown here broken into its components.  The
    Human-readable way to represent this CLSID value is
    "{0002DF01-0000-0000-C000-000000000046}".  It would be
    nice if there were an IDA script to automatically name these values,
    but in the mean time you can look them up manually in the registry.
    By opening regedit and browsing to the key     style="color: rgb(0,0,255);">HKEY_CLASSES_ROOTCLSID you can
    see a rather long list of subkeys, each named with a CLSID value.
    By finding the subkey name which matches the hexadecimal values you
    see in IDA Pro you can identify what the object name is that the
    program is requesting, which is stored in the default value of the
    key.  Here is a screen shot of regedit showing the key for the CLSID
    shown in the example code above:


            href="https://www.fireeye.com/content/dam/legacy/ammo/regedit_screen1.png">        class="alignnone size-full wp-image-1410"
        src="https://www.fireeye.com/content/dam/legacy/ammo/regedit_screen1.png"
        alt="Regedit Screen showing our CLSID being named InternetExplorer(ver 1.0)"
        width="534" height="221" />

So it appears that our
    malware sample is making an instance of the Internet Explorer
    object!  In order to use any functionality from this object the
    malware must make use of the last argument to the     style="color: rgb(0,0,255);">CoCreateInstance() function
    (which was labeled "ppv").  This parameter is a pointer to
    pointer to receive a newly allocated data structure containing all
    the pertinent data for this object, most notably function pointers.
    The list of functions available is documented here:     href="http://msdn.microsoft.com/en-us/library/bb159694.aspx">http://msdn.microsoft.com/en-us/library/bb159694.aspx.
    To see the Internet Explorer object in action from a source code
    level please take a look at this article:   href="http://support.microsoft.com/kb/167658">http://support.microsoft.com/kb/167658.


   

The most important function call to this COM object we need to
    recognize as reverse engineers is the call to the function     style="color: rgb(0,0,255);">Navigate() or     style="color: rgb(0,0,255);">Navigate2().  This is what
    actually accomplishes the HTTP request which may also contain POST
    data or a parametrized GET, and thus transmit data to the remote
    command and control server. The following screen fragment shows the
    call to the Navigate()
    method of the IE COM object as seen from IDA Pro:


            href="https://www.fireeye.com/content/dam/legacy/ammo/navigate_call_in_ida_screen1.png">        class="alignnone size-full wp-image-1412"
        src="https://www.fireeye.com/content/dam/legacy/ammo/navigate_call_in_ida_screen1.png"
        alt="Navigate() call in IDA" width="192" height="61" />


   

In this fragment we see the ppv value being accessed, which is
    what was populated from the call to     style="color: rgb(0,0,255);">CoCreateInstance().  A function
    is being called from within this data structure.

This
    function is at offset 2Ch from the beginning of the ppv data
    structure, and you can tell that the binary is calling this function
    because the call instruction accesses this specific offset from the
    beginning of the structure ("call dword ptr
    [ecx+2Ch]").   There is no clear-cut way to go
    directly from the Microsoft documentation of this COM interface to
    seeing the actually internal offset used by each member function, so
    I made a small test application to simply reference each function.
    I then disassembled my test application and could see the clear
    mapping of offsets to member functions.  The following table is a
    mapping of the commonly used member functions (by malware
    specifically) and their associated offsets as seen in a call
  instruction:


            href="https://www.fireeye.com/content/dam/legacy/ammo/function_table2.png">        class="alignnone size-full wp-image-1417"
        src="https://www.fireeye.com/content/dam/legacy/ammo/function_table2.png"
        alt="" width="189" height="171" />


 

Final Thoughts


 

My goal with this article was to make more malware analysts
    and incident responders aware of the spectrum of communication
    techniques available to malware authors and to make analysts
    recognize and be able to begin reverse engineering the COM technique
    specifically.  There is certainly a need for more tools and
    techniques in this area but it all begins with awareness and
    understanding.  One thing to take away from this is that as a
    malware analyst it is not enough to simply know assembly language.
    You must gain a working knowledge of the APIs and you must be
    rigorous, if not downright tenacious, in your appetite to learn new
    facets of the APIs as you encounter them.  If a malware analyst
    disregards calls such as CoCreateInstance() without deeper
    inspection due to their lack of understanding of it, they
    potentially will miss a critically important component of the
    malware's operation.


Source: Reversing Malware Command and Control: From Sockets to COM

Tags: