Fwanalyzer
a tool to analyze filesystem images for security
Install / Use
/learn @cruise-automation/FwanalyzerREADME
FwAnalyzer (Firmware Analyzer)
FwAnalyzer is a tool to analyze (ext2/3/4), FAT/VFat, SquashFS, UBIFS filesystem images, cpio archives, and directory content using a set of configurable rules. FwAnalyzer relies on e2tools for ext filesystems, mtools for FAT filesystems, squashfs-tools for SquashFS filesystems, and ubi_reader for UBIFS filesystems. cpio for cpio archives. SELinux/Capability support for ext2/3/4 images requires a patched version of e2tools. SELinux/Capability support for SquashFS images requires a patched version of squashfs-tools.

Overview
The main idea of FwAnalyzer is to provide a tool for rapid analysis of filesystem images as part of a firmware security Q&A check suite. FwAnalyzer takes a configuration file that defines various rules for files and directories and runs the configured checks against a given filesystem image. The output of FwAnalyzer is a report, which contains the list of files that violate any of the rules specified in the configuration. The report further contains meta information about the filesystem image and, if configured, information extracted from files within the analyzed filesystem. The report is formatted using JSON so it can be easily integrated as a step in a larger analysis.
Example report:
{
"fs_type": "extfs",
"image_digest": "9d5fd9acc98421b46976f283175cc438cf549bb0607a1bca6e881d3e7f323794",
"image_name": "test/test.img",
"current_file_tree_path": "test/oldtree.json.new",
"old_file_tree_path": "test/oldtree.json",
"data": {
"Version": "1.2.3",
"date1 file": "Mon Oct 1 16:13:05 EDT 2018\n"
},
"informational": {
"/bin": [
"CheckFileTree: new file: 40755 1001:1001 1024 0 SeLinux label: -"
],
},
"offenders": {
"/bin/elf_arm32": [
"script(check_file_elf_stripped.sh) returned=elf_arm32 is not stripped"
],
"/file1": [
"File not allowed"
],
"/file2": [
"File is WorldWriteable, not allowed",
"File Uid not allowed, Uid = 123"
],
}
}
Building and Development
Follow the steps described in Building to install all requirements and build FwAnalyzer.
Using FwAnalyzer
Command line options
-cfg: string, path to the config file-cfgpath: string, path to config file and included files (can be repeated)-in: string, filesystem image file or path to directory-out: string, output report to file or stdout using '-'-extra: string, overwrite directory to read extra data from (e.g. filetree, filecmp)-ee: exit with error if offenders are present-invertMatch: invert regex matches (for testing)
Example:
fwanalyzer -cfg system_fwa.toml -in system.img -out system_check_output.json
Example for using custom scripts stored in the scripts/ directory:
PATH=$PATH:./scripts fwanalyzer -cfg system_fwa.toml -in system.img -out system_check_output.json
The devices/ folder contains helper scripts for unpacking and dealing with specific device types and firmware package formats such as Android. It also includes general configuration files that can be included in target specific FwAnalyzer configurations.
check.py in the devices/ folder provides a universal script to effectively use FwAnalyzer, see devices/Readme.md for details. This likely is how most people will invoke FwAnalyzer.
The scripts/ folder contains helper scripts that can be called from FwAnalyzer for file content analysis and data extraction. Most interesting should be our checksec wrapper check_sec.sh, see the Checksec Wrapper Readme.
Config Options
Global Config
The global config is used to define some general parameters.
The FsType (filesystem type) field selects the backend that is used to access
the files in the image. The supported options for FsType are:
dirfs: to read files from a directory on the host running fwanalyzer, supports Capabilities (supported FsTypeOptions are: N/A)extfs: to read ext2/3/4 filesystem images (supported FsTypeOptions are:selinuxandcapabilities)squashfs: to read SquashFS filesystem images (supported FsTypeOptions are:securityinfo)ubifs: to read UBIFS filesystem images (supported FsTypeOptions are: N/A)vfatfs: to read VFat filesystem images (supported FsTypeOptions are: N/A)cpiofs: to read cpio archives (supported FsTypeOptions are:fixdirs)
The FsTypeOptions allow tuning of the FsType driver.
securityinfo: will enable selinux and capability support for SquashFS imagescapabilities: will enable capability support when reading ext filesystem imagesselinux: will enable selinux support when reading ext filesystem imagesfixdirs: will attempt to work around a cpio issue where a file exists in a directory while there is no entry for the directory itself
The DigestImage option will generate a SHA-256 digest of the filesystem image
that was analyzed, the digest will be included in the output.
Example:
[GlobalConfig]
FsType = "extfs"
FsTypeOptions = "selinux"
DigestImage = true
Example Output:
"fs_type": "extfs",
"image_digest": "9d5fd9acc98421b46976f283175cc438cf549bb0607a1bca6e881d3e7f323794",
"image_name": "test/test.img",
Include
The Include statement is used to include other FwAnalyzer configuration files
into the configuration containing the statement. The include statement can
appear in any part of the configuration.
The -cfgpath parameter sets the search path for include files.
Example:
[Include."fw_base.toml"]
Global File Checks
The GlobalFileChecks are more general checks that are applied to the entire filesystem.
Suid: bool, (optional) if enabled the analysis will fail if any file has the sticky bit set (default: false)SuidAllowedList: string array, (optional) allows Suid files (by full path) for the Suid checkWorldWrite: bool, (optional) if enabled the analysis will fail if any file can be written to by any user (default: false)SELinuxLabel: string, (optional) if enabled the analysis will fail if a file does NOT have an SeLinux labelUids: int array, (optional) specifies every allowed UID in the system, every file needs to be owned by a Uid specified in this listGids: int array, (optional) specifies every allowed GID in the system, every file needs to be owned by a Gid specified in this listBadFiles: string array, (optional) specifies a list of unwanted files, allows wildcards such as?,*, and**(no file in this list should exist)BadFilesInformationalOnly: bool, (optional) the result of the BadFile check will be Informational only (default: false)FlagCapabilityInformationalOnly: bool, (optional) flag files for having a Capability set as Informational (default: false)
Example:
[GlobalFileChecks]
Suid = true
SuidAllowedList = ["/bin/sudo"]
SELinuxLabel = false
WorldWrite = true
Uids = [0,1001,1002]
Gids = [0,1001,1002]
BadFiles = ["/file99", "/file1", "*.h"]
Example Output:
"offenders": {
"/bin/su": [ "File is SUID, not allowed" ],
"/file1": [ "File Uid not allowed, Uid = 123" ],
"/world": [ "File is WorldWriteable, not allowed" ],
}
Link Handling
With links we refer to soft links. Links can point to files on a different filesystem, therefore, we handle them in a special way. Link handling requires a patched version of e2tools:
- e2tools with link support
FileStatCheck will handle links like you would expect it. However if
AllowEmpty is false and the file is a link then the check fails.
All other checks and dataextract will fail if the file is a link. Those checks need to be pointed to the actual file (the file the link points to).
File Stat Check
The FileStatCheck can be used to model the metadata for a specific file or
directory. Any variation of the configuration will be reported as an offender.
AllowEmpty: bool, (optional) defines that the file can have zero size will cause error if file is link (default: false)Uid: int, (optional) specifies the UID of the file, not specifying a UID or specifying -1 will skip the checkGid: int, (optional) specifies the GID of the file, not specifying a GID or specifying -1 will skip the checkMode: string, (optional) specifies the UN*X file mode/permissions in octal, not specifying a mode will skip the checkSELinuxLabel: string, (optional) the SELinux label of the file (will skip the check if not set)LinkTarget: string, (optional) the target of a symlink, not specifying a link target will skip the check. This is currently supported fordirfs,squashfs,cpiofs,ubifs, andextfsfilesystems.Capability: string array, (optional) list of capabilities (e.g. cap_net_admin+p).Desc: string, (optional) is a descriptive string that will be attached to the report if there is a failed checkInformationalOnly: bool, (optional) the result of the check will be Informational only (default: false)
Example:
[FileStatCheck."/etc/passwd"]
AllowEmpty = false
Uid = 0
Gid = 0
Mode = "0644"
Desc =
