在布谷鸟沙箱中添加模块

Add module inside cuckoo sandbox

对于恶意软件动态恶意软件分析,我正在使用 Automated Malware Analysis - Cuckoo Sandbox. Now I wan to add new modules for analysis on malware. I have studied cuckoo sandbox's development documentation. But currently I am unable to add my custom script for static analysis on malware/samples. Python scripts available here

任何人都可以指导我如何在布谷鸟沙箱处理模块中添加更多模块/分析脚本。如果他们在网上有任何文章,请分享。

谢谢

首先谈谈概念。

根据文档:

The analysis packages are a core component of Cuckoo Sandbox. They consist in structured Python classes which, when executed in the guest machines, describe how Cuckoo’s analyzer component should conduct the analysis.

因此,分析包负责执行处理文件所需的操作

示例(在 windows 位客人上)

  • 需要执行exe文件
  • *.doc 需要用 Microsoft Word 打开。
  • 一个dll需要用"C:\WINDOWS\system32\rundll32.exe"
  • 执行
  • 使用 Internet Explorer 加载 html。
  • 试图用某些版本的 Acrobat 打开 PDF Reader。
  • 等...

因此,您编写了一个 Analisys 包来告诉布谷鸟如何打开或执行文件。处理文件并提取报告信息的处理模块(报告模块)。

如果要执行静态分析,则不需要写Analisis Package but a Processing Module。如果您想添加新的行为分析,您需要实施 both.

这个答案是关于编写处理模块的,因为你的问题是关于静态分析的。

实现布谷鸟的处理模块

我使用的是最新版本的文档。在文档中我发现了很多有用的东西,其他的东西(比如如何在 html 界面中显示模块报告)我在一个 测试错误过程和破解代码。

实施模块

为了成为处理模块,您的脚本必须满足一些要求。下面,你会看到哪些是 这些要求以及如何将它们组合在一起以获得处理模块。

After an analysis is completed, Cuckoo will invoke all the processing modules available in the modules/processing/ directory. Every module will then be initialized and executed and the data returned will be appended in a data structure that we’ll call global container. This container is simply just a big Python dictionary that contains all the abstracted results produced by all the modules sorted by their defined keys.

您的处理模块的结果数据将添加到全局容器中,这样其他模块(例如报告模块)就可以访问该数据 信息。

一个基本的处理模块(我们称之为 simple_module)可能如下所示:

# simple_module.py
from lib.cuckoo.common.abstracts import Processing

class SimpleModule(Processing):     # A class inheriting Processing.

    def run(self):                  # A run() function
        self.key = "simple_info"    # The name that will have the returned data in the global container.
        data = "This is the data returned by simple_module."
        return data                 # A set of data (list, dictionary or string etc.) that will be appended to the global container.
                                    # under the key secified in `self.key`.

将新模块放在哪里。

有几个模块类别,如果你查看 cuckoo 的目录层次结构,你会发现一个名为 modules 的目录和 在一些目录中:

  • 辅助 -- 不言自明
  • 机器 -- 用于处理硬件和虚拟化的模块。
  • processing -- 处理文件的模块(您要添加的)
  • reporting -- 报告处理模块得到的结果所需的模块
  • signatures -- 这对我来说不是很清楚(我可能对 signature 的含义有不同的看法)。

你要关心的目录是:processing。在那里你将放置你的新模块。

启用新模块

conf/processing.conf 文件中添加如下部分:

[simple_module]
enabled = yes

如何查看结果?

After the analysis raw results have been processed and abstracted by the processing modules and the global container is generated (ref. Processing Modules), it is passed over by Cuckoo to all the reporting modules available, which will make some use of it and will make it accessible and consumable in different formats.

是的!!我们需要其他模块才能看到新处理模块的输出。最简单的方法是将结果记录到文件中:

您可以访问 Reporting Modules 文档,您会找到如下示例:

让我们为我们的处理模块实现一个报告,simple_module:

# simple_report.py
import os

from lib.cuckoo.common.abstracts import Report
from lib.cuckoo.common.exceptions import CuckooReportError

class SimpleReport(Report):

    def run(self, results):                         # IMPORTANT!! Here the parameter result will be the Global Container we saw before
        try:
            report = open(os.path.join(self.reports_path, "simple_report.txt"), "w")
            report.write(results["simple_info"])    # We add our information to the Global Container under the key: simple_info
                                                    # now we are querying that info to write it down to a file.
            report.close()
        except (TypeError, IOError) as e:
            raise CuckooReportError("Failed to make a simple report, :(")

您还需要启用此报告模块:

Every module should also have a dedicated section in the file conf/reporting.conf, for example if you create a module module/reporting/foobar.py you will have to append the following section to conf/reporting.conf

[simple_report]
enabled = on

现在你运行一个新的分析,你将能够在storage/analyses/<analysis-number>/reports文件夹中找到一个名为"simple_report.txt"的文件。

那HTML呢,我想在浏览器里看看结果!!

嗯……这有点复杂。如果您查看文件 modules/reporting/reporthtml.py,您会发现 class ReportHtml 在某些时候具有如下代码:

try:
    tpl = env.get_template("report.html")       # Ahhhh, so cuckoo is using a template for this.
    html = tpl.render({"results": results})     # Look, the template receives the Global Container (this dude again!!!, it must be a VIP).
except Exception as e:
    raise CuckooReportError("Failed to generate HTML report: %s" % e)

try:
    with codecs.open(os.path.join(self.reports_path, "report.html"), "w", encoding="utf-8") as report:
        report.write(html)
except (TypeError, IOError) as e:
    raise CuckooReportError("Failed to write HTML report: %s" % e)

模板在 web/templates/analysis 中,您可以在那里找到 report.html。阅读该文件,您会注意到两个重要的代码块:

选项卡代码:

<ul class="nav nav-tabs">
    <li class="active"><a href="#overview" data-toggle="tab">Quick Overview</a></li>
    <li><a href="#static" data-toggle="tab">Static Analysis</a></li>
    {% if analysis.behavior.processes %}<li><a href="#behavior" data-toggle="tab" id="graph_hook">Behavioral Analysis</a></li>{% endif %}
    <li><a href="#network" data-toggle="tab">Network Analysis</a></li>
    <li><a href="#dropped" data-toggle="tab">Dropped Files</a></li>
    {% if analysis.procmemory %}<li><a href="#procmemory" data-toggle="tab">Process Memory</a></li>{% endif %}
    {% if analysis.memory %}<li><a href="#memory" data-toggle="tab">Memory Analysis</a></li>{% endif %}
    <li><a href="#admin" data-toggle="tab">Admin</a></li>
</ul>

和内容代码(为简洁起见省略了一些代码):

<div class="tab-content">
    <div class="tab-pane fade in active" id="overview">
        {% include "analysis/overview/index.html" %}
    </div>
    <div class="tab-pane fade" id="static">
        {% include "analysis/static/index.html" %}
    </div>
    {% if analysis.behavior.processes %}
    <div class="tab-pane fade" id="behavior">
        {% include "analysis/behavior/index.html" %}
    </div>
    {% endif %}
    ...
    ...
</div>

好的,很明显,我们需要添加我们的模板,让我们继续:

1- 创建文件,web/templates/analysis/simple_module/index.html

 {{analysis.simple_info}}

在上面的行中,analysis 指向字典 Global Results 的根目录。简单信息是我们的流程模块添加到此类字典的关键字,simple_module.

这会将 {{analysis.simple_info}} 替换为我们在 Global Conatiner 中为该键设置的值。另见 The Django template language: for Python programmers.

2- 更新 web/templates/analysis/report.html 以包含您的模板

添加行

<li class="active"><a href="#simple_module" data-toggle="tab">Simple Module</a></li>

到选项卡部分。以及内容部分的以下行:

<div class="tab-pane fade" id="simple_module">
    {% include "analysis/simple_module/index.html" %}
</div>

还有... Hocus Pocus ...

需要注意的是,如果您只想以html格式显示结果,则不必实现报表模块,只需创建相应的模板并使用相应的变量即可。

我为此写了一个不同的答案。为了回答 Nika 的问题(he/she 在问题上创建了赏金)。

我应该如何扩展涉及编辑分析包的动态分析功能?

为了回答您的主要问题,我将首先回答您作为评论发布的问题:

Nika:我应该添加还是修改现有的 "exe" 包?

你应该添加另一个模块,你可以在提交时指定分析包。

#analizer.py

...
# If no analysis package was specified at submission, we try to select
# one automatically.
        if not self.config.package:
            log.debug("No analysis package specified, trying to detect "
                      "it automagically.")
...

Nika:脚本将在哪里执行,客户端还是主机?

我认为 "client" 你的意思是 "guest"。

脚本在来宾中 "performed",如果您查看 agent.py 的代码,您会看到类似这样的内容:

from SimpleXMLRPCServer import SimpleXMLRPCServer

还有:

def add_analyzer(self, data):
        """Add analyzer.
        @param data: analyzer data.
        @return: operation status.
        """
        data = data.data

        if not self._initialize():
            return False

        try:
            zip_data = StringIO()
            zip_data.write(data)

            with ZipFile(zip_data, "r") as archive:
                archive.extractall(ANALYZER_FOLDER)
        finally:
            zip_data.close()

        self.analyzer_path = os.path.join(ANALYZER_FOLDER, "analyzer.py")

        return True

这两个代码片段表明:首先,代理使用 RCP,其次,分析器被复制到目标虚拟机,所有这些都表明脚本是在来宾系统中执行的。

事实上有一个函数显示了它是如何执行的:

def execute(self):
        """Execute analysis.
        @return: analyzer PID.
        """
        global ERROR_MESSAGE
        global CURRENT_STATUS

        if not self.analyzer_path or not os.path.exists(self.analyzer_path):
            return False

        try:
            proc = subprocess.Popen([sys.executable, self.analyzer_path],
                                    cwd=os.path.dirname(self.analyzer_path))
            self.analyzer_pid = proc.pid
        except OSError as e:
            ERROR_MESSAGE = str(e)
            return False

如果在来宾上执行,我可以在哪里存储收集的信息以进一步提取到报告中?

参见我的其他回答,信息总是由 处理模块 收集并添加到 全局容器 。然后从那里您可以使用 报告模块 .

访问它

您的分析包应该使用一些工具来获得您想要的结果或信息。然后在处理模块中你有成员 self.dropped_path 你可以在那里查看文件,处理它并将信息添加到全局容器中。

我希望这能帮助您更接近想要实现的目标。