45

FACT:一款固件类比分析测试平台

 5 years ago
source link: http://4hou.win/wordpress/?p=22445&%3Butm_source=tuicool&%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

0×01 工具简介

1.FACT 全称 Firmware Analysis and Comparison Tool 是一个拥有WEB端的自动化固件测试平台。

2.旨在自动执行固件安全分析(路由器,物联网,UEFI,网络摄像头,无人驾驶飞机……)

3.工具基于Python-flask框架,采用模块化开发并支持插件接入,因此对于二次开发和优化非常便捷。

4.FACT可以自动化完成固件解包任务并对其进行固件分析包括:

软件识别

(1)使用哪个操作系统?

(2)哪些节目存在?

(3)使用哪些版本?

(4)哪些服务在启动时启动

(5)这些漏洞有哪些?

查找用户凭据

加密材料检测

(1)私人钥匙

(2)证书

(3)CPU架构(需要进行仿真和反汇编)

5.FACT 同样也自动化的实现了固件的类比,可以很方便的对比出来旧版本与新版本固件之间的变动。以找出开发商对新固件在哪里进行了更新,同样也可以识别是否为开发商原始固件。比如:

(1)识别已更改/相同的文件

(2)识别更改的软件版本

0×02 主要功能分析

1.FACT的业务代码主要有三块

Unpacking – 固件解包

Analysis – 固件系统分析

Comparison – 固件类比

2.每一块业务代码又由一下两部分组成:

(1)Scheduler – 任务调度器

(2)Multiple plugins – 插件集

3.每个调度器拥有独立的工作线程

总流程图

VVN7Vzn.jpg!web

固件解包工作流程图

vEvYbyB.jpg!web FACT在识别文件类型的时候会调用”file”命令,并使用自带的一个mime库来标记文件类型。

在确定文件类型后调度器会选择正确的插件进行解包任务。

固件系统分析工作流程图

fyiuIvV.jpg!web

调度器一次只会调用一个插件,当上一个插件任务结束后才会继续调用下一个插件。

插件工作时可以拥有多个线程一起进行。

插件可以调用以及查看前面插件执行后的二进制结果。

固件系统类比工作流程图

2u2iime.jpg!web

固件系统类比任务是与固件分析任务分开的,需要进行类比的固件要先进行固件分析。

需要手工填入需要进行类比的固件UIDS。

类比工作是单线程工作,相对节省系统资源。

0×03 具体代码分析

FACT 的配置文件位于./src/config/main.cfg

# ------ 数据库配置 ------

[data_storage]

firmware_file_storage_directory = /media/data/fact_fw_data

mongo_server = localhost

mongo_port = 27018

main_database = fact_main

intercom_database_prefix = fact_intercom

statistic_database = fact_stats

view_storage = fact_views

# Threshold for extraction of analysis results into a file instead of DB storage

report_threshold = 100000

# 认证信息

db_admin_user = fact_admin

db_admin_pw = 6fJEb5LkV2hRtWq0

db_readonly_user = fact_readonly

db_readonly_pw = RFaoFSr8b6BMSbzt

# 用户管理

user_database  = sqlite:////media/data/fact_auth_data/fact_users.db

password_salt = 5up3r5tr0n6_p455w0rd_5417

# 数据库结构信息

variety_path = bin/variety.js

structural_threshold = 40

[Logging]

logFile=/tmp/fact_main.log

mongoDbLogFile=/tmp/fact_mongo.log

logLevel=WARNING

# ------ 解包插件配置管理 ------

[unpack]

threads = 4

# 如果文件类型在白名单中,将不会被提取

whitelist = audio/mpeg, image/png, image/jpeg, image/gif, application/x-shockwave-flash, video/mp4, video/mpeg, video/quicktime, video/x-msvideo, video/ogg, text/plain

# 递归提取深度

max_depth = 8

# ------ 分析插件配置管理 ------

[default_plugins]

# choose preselected plugins

plugins = cpu_architecture, crypto_material, exploit_mitigations, ip_and_uri_finder, software_components, users_and_passwords

# -- 插件设置项 --

[asc]

threads = 4

[base64_decoder]

string_min_length = 15

# It might be useful to set base64_section_min_length = string_min_length / 3 * 4

base64_section_min_length = 20

[binary_analysis]

threads = 4

[binwalk]

threads = 2

[check_path]

threads = 4

[cpu_architecture]

threads = 2

mime_ignore = application/pdf, application/postscript, application/xml, application/xhtml+xml, application/x-dvi, image/gif, image/jpeg, image/png, text/comma-separated-values, text/css, text/html, text/plain, text/javascript, text/xml, video/mpeg,  video/x-msvideo, application/x-httpd-php, application/msword

[crypto_code]

threads = 2

[crypto_material]

threads = 2

[cwe_checker]

threads = 4

[exploit_mitigations]

threads = 4

[file_hashes]

threads = 2

hashes = md5, sha1, sha256, sha512, ripemd160, whirlpool

[init_systems]

threads = 2

[ip_and_uri_finder]

threads = 2

[malware_scanner]

threads = 4

[manufacturer_detection]

threads = 2

[printable_strings]

threads = 2

min_length = 6

[similar_files]

threads = 4

[software_components]

threads = 2

[string_evaluator]

threads = 2

[software_version_string_finder]

threads = 2

[users_and_passwords]

threads = 4

# ------ Web Interface ------

[database]

results_per_page = 10

number_of_latest_firmwares_to_display = 10

# !!!!=如果你不知道这些是干啥的,就不要瞎改!!!!(作者原话)

[ExpertSettings]

block_delay = 2

ssdeep_ignore = 1

communication_timeout = 60

unpack_threshold = 0.8

unpack_throttle_limit = 50

throw_exceptions = false

authentication = false 

由于FACT三块业务功能代码结构类似,这里以Unpack 功能为例,详细的讲解代码逻辑。

Unpack_service 被归置为backend_service 任务通过./start_fact_backend.py启动。

if __name__ == '__main__':'''同理其他的backend_service也是从这里启动

    args, config = program_setup(PROGRAM_NAME, PROGRAM_DESCRIPTION)

    unpacking_service = UnpackingScheduler(config=config, post_unpack=analysis_service.add_task, analysis_workload=analysis_service.get_scheduled_workload)

    intercom = InterComBackEndBinding(config=config, analysis_service=analysis_service, compare_service=compare_service, unpacking_service=unpacking_service)

    work_load_stat = WorkLoadStatistic(config=config)

./src/scheduler/Unpacking.py将负责创建并调度解包任务

 def start_unpack_workers(self):

        logging.debug('Starting {} working threads'.format(int(self.config['unpack']['threads'])))

        for process_index in range(int(self.config['unpack']['threads'])):

            self._start_single_worker(process_index)

    def unpack_worker(self, worker_id):

        unpacker = Unpacker(self.config, worker_id=worker_id) '''这里调用的Unpacker是具体的解包任务执行函数

        while self.stop_condition.value == 0:

            with suppress(Empty):

                fo = self.in_queue.get(timeout=int(self.config['ExpertSettings']['block_delay']))

                extracted_objects = unpacker.unpack(fo)

                logging.debug('[worker {}] unpacking of {} complete: {} files extracted'.format(worker_id, fo.get_uid(), len(extracted_objects)))

                self.post_unpack(fo)

                self.schedule_extracted_files(extracted_objects)

./src./unpacker/unpack.py 负责执行具体的解包任务

class Unpacker(UnpackBase):

    GENERIC_FS_FALLBACK_CANDIDATES = ['SquashFS']

    GENERIC_CARVER_FALLBACK_BLACKLIST = ['generic_carver', 'NOP', 'PaTool']

    VALID_COMPRESSED_FILE_TYPES = ['application/x-shockwave-flash', 'audio/mpeg', 'audio/ogg', 'image/png', 'image/jpeg', 'image/gif', 'video/mp4', 'video/ogg']

    HEADER_OVERHEAD = 256

    def __init__(self, config=None, worker_id=None):

        super().__init__(config=config, worker_id=worker_id)

        self.file_storage_system = FS_Organizer(config=self.config)

    def unpack(self, current_fo):

        '''

        递归提取到的所有对象都将包含在 current_fo 里,并将它们添加进 current_fo.files_included

        '''

        logging.debug('[worker {}] Extracting {}: Depth: {}'.format(self.worker_id, current_fo.get_uid(), current_fo.depth))

        tmp_dir = TemporaryDirectory(prefix='faf_unpack_')

        extracted_files, meta_data = self.extract_files_from_file(current_fo.file_path, tmp_dir.name, current_fo.depth)

        extracted_files, meta_data = self._do_fallback_if_necessary(extracted_files, meta_data, tmp_dir, current_fo)

        extracted_file_objects = self.generate_and_store_file_objects(extracted_files, tmp_dir.name, current_fo)

        extracted_file_objects = self.remove_duplicates(extracted_file_objects, current_fo)

        self.add_included_files_to_object(extracted_file_objects, current_fo)

        self.add_additional_unpacking_meta(current_fo, meta_data)

        self.get_unpack_status(current_fo, extracted_file_objects)

        self.cleanup(tmp_dir)

        return extracted_file_objects

0×04 目录结构分析

FACT_CORE-MASTER/SRC

├─analysis '' 固件分析任务脚本

├─bootstrap

│  └─patches

├─compare ''固件类比任务脚本

├─config ''配置信息

├─helperFunctions '' 辅助任务函数

├─intercom ''数据交互定义

├─mime '' 文件类型的mime资源

├─objects '' 目标类型定义脚本

├─plugins '' 插件集合

│  ├─analysis

│  │  ├─architecture_detection

│  │     ├─code

│  │     ├─test

│  │     │  └─data

│  │     └─view

│  ├─compare

│  │

│  └─unpacking

│     

├─scheduler '' 调度器脚本

├─statistic '' 任务统计

├─storage '' 数据交互存储接口

├─test 

├─unpacker '' 固件解包任务脚本

└─web_interface '' WEB端

   

0×05 安装以及使用

1.FACT的安装非常简洁,参考FACT的github 你可以很方便的安装好一个FACT平台

2. 建议使用清华源进行安装,因为国内源我测试只有清华源可以畅通无阻。。。

3.安装时建议添加 -N 参数 可以一并把nginx安装

4.WEB端原版为全英文,汉化了一下,舒服多了。。。

bIV3Qbf.jpg!web

q6vm2yJ.jpg!web

JrmuMfQ.jpg!web

JBVriyi.jpg!web

0×06 后记

1.平台运行需要一定的硬件配置,资源需求比较大

2.代码结构严谨,逻辑清晰,核心功能工作流程设计非常nice,调度器与插件集的实用为二次开发提供了很大的便利

3.WEB安全性低,不建议作为公开服务运营

4.添加了一个自动化提取固件内部web路径并审计的插件,官方还没有回信

参考资料

1. FACT

2. Flask

3. Firmadyne

4. binwalk

*本文作者:Murkfox,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK