IoT 固件识别与提取
IoT 固件识别与提取
moria 可识别固件和 IoT 镜像中嵌入的文件与结构(文件系统、内核、引导加载程序、归档文件、密钥),并在无需 root 权限的情况下解包其发现的大部分内容。它会报告每一项发现的字节偏移、类型和置信度评分,并输出干净的 JSON,使脚本和 LLM 代理能够像人类一样轻松驱动它。
upx -d 的存根。openat + O_NOFOLLOW(无路径遍历或符号链接逃逸),解压缩针对压缩炸弹设有上限。-j),每项发现都带有偏移和置信度。cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
cmake --install build --prefix ~/.local # 或 /usr/local(需要 sudo)
构建需要 cmake、C++20 编译器,以及 zlib、liblzma、lz4 和 zstd 开发库(--extract 使用的解压缩器)。在 Debian/Ubuntu 上:sudo apt install cmake g++ zlib1g-dev liblzma-dev liblz4-dev libzstd-dev。若要在缺少某个库的情况下构建(最小化或仅识别构建),请使用 -DMORIA_OPTIONAL_CODECS=ON 进行配置,缺失的编解码器将被直接禁用。
moria 二进制文件是自包含的:所有签名集在构建时嵌入,因此该二进制文件可在任何地方运行,无需随附任何安装内容(cp build/moria ~/.local/bin 即可,下载的发布版二进制文件可直接运行)。若要使用外部签名而非嵌入签名(例如在不重新构建的情况下测试新的 .toml),请传入 --sigs DIR 或设置 $MORIA_SIGDIR。
默认输出为人类可读格式。传入 -j 可获得 JSON。
moria <file> # 识别:带有偏移、类型和置信度的发现树
moria <dir> # 扫描目录树:类型摘要及值得注意的文件
moria -j <file> # JSON,供工具和代理使用
moria -e <file> # 提取到 <file>.extracted/ (-C DIR 选择输出目录)
moria -c <file> # 将原始字节范围雕刻到 <file>.carved/(不解析)
moria -E <file> # 熵分析:标记未识别/可能加密的区域
moria --list <archive> # 列出 tar/cpio/zip 成员而不提取
moria --broad <path> # 同时加载约 2.5k 个通用文件类型签名
moria --help
-e 将识别出的格式解包到 <file>.extracted/ 下,每个区域一个目录(0x<offset>-<type>/),外加一个将偏移映射到路径的 manifest.json。它会自动递归进入嵌套容器,并逐卷重建 UBI 镜像。防护措施(--depth、--max-files、--max-bytes 以及解压缩比率上限)限制恶意输入;触发防护会停止该分支,但仍返回所有已恢复的内容。
在进程内解包,无需外部工具,无需 sudo:
signatures/ 是手写的核心:固件文件系统、容器、内核和常见格式,每个都带有结构验证。signatures-firmware/ 存放厂商固件容器魔数,默认加载。signatures-generated/ 存放约 2.5k 个通用文件类型魔数,源自 file(1) 的 magic 数据库,仅在 --broad 时加载。要添加格式,请在 signatures/ 中放入一个 .toml。仅当声明层无法表达检查(如 CRC 或跨块指针)时,才需要一个小型 C++ 验证器。
moria 进行结构识别、提取和雕刻。密钥/凭据扫描、SBOM、CVE 和许可证分析是另一个工具(mithril)。
MIT,参见 LICENSE。
部分磁盘格式处理是对其他开源项目中算法的干净重新实现,基于 moria 自己的 I/O 层独立编写(未复制源代码):来自 UPX/UCL 的 UCL/NRV2B 解压缩器和 CTO 逆滤波器(GPL-2.0,仅算法),以及 littlefs 的元数据提交和 CTZ 跳表布局(BSD-3-Clause),以及 SPIFFS 的页/对象布局(MIT)。