mirror of
https://github.com/VirusTotal/yara.git
synced 2026-10-12 02:10:00 +00:00
`https://www.cuckoosandbox.org` has a cert error. But `http://cuckoosandbox.org` works just fine.
186 lines
5.2 KiB
ReStructuredText
186 lines
5.2 KiB
ReStructuredText
.. _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/)*
|
|
|
|
|
|
|
|
|
|
|
|
|