.. _cuckoo-module:

#############
Cuckoo module
#############

The Cuckoo module enables you to create YARA rules based on behavioral
information generated by `Cuckoo sandbox <https://cuckoosandbox.org/>`_.
While scanning a PE file with YARA, you can pass additional information about
its behavior to the ``cuckoo`` module and create rules based not only on what
it *contains*, but also on what it *does*.

.. important::
    This module is not built into YARA by default, to learn how to include it
    refer to :ref:`compiling-yara`. Good news for Windows users: this module
    is already included in the official Windows binaries.

Suppose that you're interested in executable files sending a HTTP request to
http://someone.doingevil.com. In previous versions of YARA you had to settle
with:

.. code-block:: yara

    rule evil_doer
    {
        strings:
            $evil_domain = "http://someone.doingevil.com"

        condition:
            $evil_domain
    }


The problem with this rule is that the domain name could be contained in the
file for perfectly valid reasons not related with sending HTTP requests to
http://someone.doingevil.com. Furthermore, the malicious executable could
contain the domain name ciphered or obfuscated, in which case your rule
would be completely useless.

But now with the ``cuckoo`` module you can take the behavior report generated
for the executable file by your Cuckoo sandbox, pass it alongside the
executable file to YARA, and write a rule like this:

.. code-block:: yara

    import "cuckoo"

    rule evil_doer
    {
        condition:
            cuckoo.network.http_request(/http:\/\/someone\.doingevil\.com/)
    }

Of course you can mix your behavior-related conditions with good old
string-based conditions:

.. code-block:: yara

    import "cuckoo"

    rule evil_doer
    {
        strings:
            $some_string = { 01 02 03 04 05 06 }

        condition:
            $some_string and
            cuckoo.network.http_request(/http:\/\/someone\.doingevil\.com/)
    }


But how do we pass the behavior information to the ``cuckoo`` module? Well, in
the case of the command-line tool you must use the ``-x`` option in this way::

    $yara -x cuckoo=behavior_report_file rules_file pe_file


``behavior_report_file`` is the path to a file containing the behavior file
generated by the Cuckoo sandbox in JSON format.

If you are using ``yara-python`` then you must pass the behavior report in the
``modules_data`` argument for the ``match`` method:

.. code-block:: python

    import yara
    rules = yara.compile('./rules_file')
    report_file = open('./behavior_report_file')
    report_data = report_file.read()
    rules.match(pe_file, modules_data={'cuckoo': bytes(report_data)})


Reference
---------

.. default-domain:: c

.. type:: network

    .. function:: http_request(regexp)

        Function returning true if the program sent a HTTP request to a URL
        matching the provided regular expression.

        *Example: cuckoo.network.http_request(/evil\\.com/)*

    .. function:: http_get(regexp)

        Similar to :func:`http_request`, but only takes into account GET
        requests.

    .. function:: http_post(regexp)

        Similar to :func:`http_request`, but only takes into account POST
        requests.
       
    .. function:: http_user_agent(regexp)

        Function returning true if the program sent a HTTP request with a
        user agent matching the provided regular expression.

        *Example: cuckoo.network.http_user_agent(/MSIE 6\\.0/)*   

    .. function:: dns_lookup(regexp)

        Function returning true if the program sent a domain name resolution
        request for a domain matching the provided regular expression.

        *Example: cuckoo.network.dns_lookup(/evil\\.com/)*
        
    .. function:: host(regexp)

        Function returning true if the program contacted an IP address
        matching the provided regular expression.

        *Example: cuckoo.network.host(/192\\.168\\.1\\.1/)*  

      .. function:: tcp(regexp, port)

        Function returning true if the program contacted an IP address
        matching the provided regular expression, over TCP on the provided
        port number.

        *Example: cuckoo.network.tcp(/192\\.168\\.1\\.1/, 443)*  

      .. function:: udp(regexp, port)

        Function returning true if the program contacted an IP address
        matching the provided regular expression, over UDP on the provided
        port number.

        *Example: cuckoo.network.udp(/192\\.168\\.1\\.1/, 53)*  

.. type:: registry

    .. function:: key_access(regexp)

        Function returning true if the program accessed a registry entry
        matching the provided regular expression.

        *Example: cuckoo.registry.key_access(/\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run/)*

.. type:: filesystem

    .. function:: file_access(regexp)

        Function returning true if the program accessed a file matching the
        provided regular expression.

        *Example: cuckoo.filesystem.file_access(/autoexec\\.bat/)*

.. type:: sync

    .. function:: mutex(regexp)

        Function returning true if the program opens or creates a mutex matching
        the provided regular expression.

        *Example: cuckoo.sync.mutex(/EvilMutexName/)*






