在Cuckoo沙箱中添加模块

7
针对恶意软件的动态分析,我正在使用自动化恶意软件分析 - Cuckoo Sandbox。现在我想添加新的模块来分析恶意软件。我已经研究了Cuckoo Sandbox的开发文档。但目前我无法为恶意软件/样本添加自定义静态分析脚本。可用的Python脚本在这里
请问有人能指导我如何在Cuckoo Sandbox处理模块中添加更多模块/分析脚本吗?如果网络上有任何文章,请分享。
谢谢

请注意,不要只是参考官方文档,因为任何关注所描述问题的人都很可能已经搜索过它们,但没有找到答案 :)。 - nicks
所以你需要添加分析包吗?请指出文档缺失的具体内容或您遇到困难的地方。 - Serafim Suhenky
  1. 我应该添加还是修改现有的“exe”包?
  2. 脚本将在客户端或主机上执行?如果它将在主机上执行,我如何完全访问客户系统以执行我的逻辑?如果在客户端上执行,我在哪里可以存储收集到的信息以便进一步提取到报告中?
- nicks
要求我们推荐或寻找书籍、工具、软件库、教程或其他外部资源的问题,不适用于Stack Overflow。相反,请描述问题以及已经采取的解决方案。 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须在问题本身中包含所需的行为、特定的问题或错误以及重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建一个最小、完整和可验证的示例。 - SherylHohman
2个回答

5

首先让我们谈谈概念。

根据文档:

分析包是Cuckoo Sandbox的核心组件之一。它们由结构化的Python类组成,当在客户机上执行时,描述了Cuckoo的分析器组件应该如何进行分析

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

示例(在Windows客户机上)

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

因此,您编写一个分析包来告诉cuckoo如何打开或执行文件。一个处理模块用于处理文件并提取报告信息(报告模块)。

如果您想执行静态分析,您不需要编写分析包而是处理模块。如果您想添加新的行为分析,您需要同时实现两者
本答案是关于编写处理模块的,因为您的问题是关于静态分析的。

实现cuckoo的处理模块

我使用最新版本的文档。在文档中,我发现很多信息是有用的,其他东西(比如如何在HTML界面中显示模块报告)我通过试验和修改代码自己发现了。

实现模块

为了成为一个处理模块,您的脚本必须满足一些要求。下面,您将看到这些要求以及如何将它们组合起来以获取一个处理模块。
完成分析后,Cuckoo将调用modules/processing/目录中可用的所有处理模块。然后每个模块将被初始化和执行,并且返回的数据将被添加到我们称之为全局容器的数据结构中。 该容器只是一个包含所有模块按其定义键排序产生的抽象结果的大型Python字典。
您的处理模块的结果数据将被添加到全局容器中,这样其他模块(例如报告模块)可以访问该信息。
一个基本的处理模块(我们称其为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的目录和一些子目录:

  • 辅助 -- 自我解释
  • 机械 -- 用于处理硬件和虚拟化的模块。
  • 处理 -- 用于处理文件(您想要添加的文件)的模块
  • 报告 -- 处理模块所获得结果所需的模块
  • 签名 -- 我不确定(我可能对signature的含义有不同的理解)。

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

启用新模块

conf/processing.conf文件添加以下类似的部分:

[simple_module]
enabled = yes

如何查看结果?

在分析原始结果经过处理模块并生成全局容器(参见处理模块)后,Cuckoo会将其传递给所有可用的报告模块,这些模块将对其进行一些处理,并以不同的格式使其可访问和可消费。

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

您可以查看报告模块文档,其中会有以下示例:

让我们为我们的处理模块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, :(")

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

每个模块都应该在文件conf/reporting.conf中有一个专门的部分,例如如果您创建了一个名为module/reporting/foobar.py的模块,则必须将以下部分添加到conf/reporting.conf中

[simple_report]
enabled = on

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

Output to the report to the file

关于HTML,我想在浏览器中看到结果!!

嗯...这有点复杂。如果您查看文件modules/reporting/reporthtml.py,您会发现一个名为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 info是由我们的process模块simple_module添加到该字典中的键。
这将用Global Container中设置的值替换{{analysis.simple_info}}。还请参见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>

而且...变戏法...

enter image description here

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

我需要的是“分析包”,而你甚至没有在教程中添加它。很抱歉,但你的帖子完全无关。 - nicks
@NikaGamkrelidze 我不这么认为。如果你查看Cuckoo内的文件,你会在文件夹“modules/processing/”中找到文件,例如:static.py、analysisinfo.py、network.py、memory.py等。处理模块是执行分析的模块。OP想要对OLE文件进行静态分析,因此教程是正确的。要分析一个文件,你必须对它进行处理。 - Raydel Miranda
静态分析 - 是的,但我在那个问题上创建了赏金并指定了我的问题。 - nicks
抱歉,我不知道是谁在这个问题上设置了悬赏,这是你一开始看不到的。我会简要地将你的问题添加到我的答案中。 - Raydel Miranda
我在想,如何扩展涉及编辑“分析”包的动态分析功能。 - nicks
太棒了:)。感谢你解决问题,伙计:)。 - Muhammad Abdullah

2
我为此写了一个不同的答案。为了回答Nika的问题(他/她在问题上创建了悬赏),我将先回答您在评论中发布的问题:
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: 脚本将在客户端或主机上执行?

我想你指的是“访客”而不是“客户端”。

脚本是在访客中“执行”的,如果您查看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中的文件,对其进行处理并将信息添加到全局容器中。
希望这能帮助您更接近您想要实现的目标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接