对于恶意软件动态恶意软件分析,我使用的是Automated Malware Analysis - Cuckoo Sandbox。现在我想添加新的模块来分析恶意软件。我研究过cuckoo sandbox的开发文档。但目前我无法为恶意软件/样本添加自定义脚本进行静态分析。 Python脚本可用here。
任何人都可以指导我如何在布谷鸟沙箱处理模块中添加更多模块/分析脚本。如果他们是网上的任何文章,请分享。
谢谢
根据文件:
分析包是Cuckoo Sandbox的核心组件。它们包含结构化的Python类,当在客户机中执行时,它们描述了Cuckoo的分析器组件应该如何进行分析。
因此,分析包负责执行处理文件所需的操作。
示例(在Windows客户端)
"C:\\WINDOWS\\system32\\rundll32.exe"
执行dll因此,您编写一个分析包来告诉cuckoo如何打开或执行文件。处理模块,用于处理文件并提取报告信息(报告模块)。
如果你想进行静态分析,你不需要写一个Analisis Package而是Processing Module。如果要添加新的行为分析,则需要实现两者。
这个答案是关于写处理模块的,因为你的问题是关于静态分析。
我使用文档的最新版本。在文档中,我发现许多有用的东西,其他的东西(比如如何在html界面中显示模块报告)我在测试和错误过程中发现了自己并且破解了代码。
要成为处理模块,您的脚本必须满足一些要求。下面,您将看到这些要求是什么以及如何将它们组合在一起以获得处理模块。
分析完成后,Cuckoo将调用modules / processing /目录中的所有可用处理模块。然后将初始化并执行每个模块,并将返回的数据附加到我们称之为global container的数据结构中。这个容器只是一个庞大的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
的含义有不同的看法)。您需要关心的目录是:处理。在那里你将放置你的新模块。
在conf/processing.conf
文件中添加如下所示的seccion:
[simple_module]
enabled = yes
在分析处理模块处理和抽象原始结果并生成global container之后(参考Processing Modules),Cuckoo将其传递给所有可用的报告模块,这将使用它并使其可访问和不同格式的消耗品。
是!!我们需要其他模块才能看到新处理模块的输出。最简单的方法是将结果记录到文件中:
您可以访问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, :(")
您还需要启用此报告模块:
每个模块还应该在文件conf / reporting.conf中有一个专用部分,例如,如果您创建模块模块/ reporting / foobar.py,则必须将以下部分附加到conf / reporting.conf
[simple_report]
enabled = on
现在你运行一个新的分析,你将能够在storage/analyses/<analysis-number>/reports
文件夹中找到一个名为“simple_report.txt”的文件。
嗯......那有点复杂。如果你看看文件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
指向字典全局结果的根。简单的信息是我们的处理模块simple_module添加到这种字典的关键。
这将用我们在Global Conatiner中为该键设置的值替换{{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>
并且...... Hocus Pocus ......
需要注意的是,如果您只想以html格式显示结果,则不必实现报表模块,只需创建相应的模板并使用相应的变量即可。
我为此写了一个不同的答案。为了回答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:脚本将在何处执行,客户端还是主机?
我认为“客户”你的意思是“客人”。
脚本在guest中“执行”,如果你查看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,然后将分析器复制到目标虚拟机,所有这些一起表明sripts在guest虚拟机系统中执行。
实际上有一个函数可以显示它的执行方式:
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
,您可以在那里查看文件,处理它并将信息添加到全局容器中。
我希望这可以帮助您更接近想要实现的目标。