Skip to main content

Firmwalker

Overview

The Firmwalker is based on the open-source bash script by craigz28. It is responsible for analyzing the firmware and includes a Flask API and client-side scripts to facilitate remote requests for firmware analysis.

Primary Components

The primary components of Firmwalker are located in the /jobs directory:

  • firmwalker.py: A client-side script that interacts with the Flask API to request firmware analysis.
  • firmwalker_service.py: A Flask web service that exposes an API for remote requests to analyze firmware images using Firmwalker.
  • firmwalker_analysis.py: A Python script that performs the actual analysis of the firmware by invoking the bash script firmwalker.sh to process extracted firmware data, that was previously extracted.

Individual Components

1. firmwalker.py (Client-side Script)

This script acts as the entry point for sending requests to the Firmwalker service. It is responsible for:

  • Sending an HTTP request to the Firmwalker service (Flask API)
  • Passing the necessary parameters (image_id, path, output_path) to the service
  • Handling the response from the service and printing the results

The script accepts three arguments:

  • image_id: The unique identifier for the firmware image from the database
  • path: The path to the extracted firmware image directory
  • output_path: The output location for the analysis results

The script constructs a POST request to the /post endpoint of the Flask service firmwalker_service.py running at http://firmwalker:5004/post. The request body includes a JSON payload with the keys image_id, path and output_path.

Upon receiving a response from the Flask API:

  • If successful (status code 200), the script prints the JSON response from the API, which includes the result of the firmware analysis
  • If an error occurs, it prints the error message

2. firmwalker_service.py (Flask API Server)

This is the Flask web service that acts as a middleman between the client firmwalker.py and the analysis process firmwalker_analysis.py. The Flask service listens for POST requests on the /post endpoint. The request body should contain a JSON payload with the three parameters mentioned above.

The service then verifies that the required parameters image_id, path, output_path are present in the request. It also checks if the specified firmware extraction directory (extracted) exists in the provided path and if not, prints Please extract the firmware first with binwalk!.

If the extraction directory is present and valid, the Flask service calls firmwalker_analysis.py to perform the actual analysis, passing the path arguments to this script. This is done using the subprocess.run() function, which executes the firmwalker_analysis.py script as a subprocess.

After the analysis is completed, the service returns a JSON response:

  • If successful, it includes a success message along with the path to the saved output file
  • If any error occurs, it returns an error message and logs the issue

The service logs important events, such as incoming requests, successful analyses and errors to a log file (firmwalker.log) to help with the auditing and debugging.

3. firmwalker_analysis.py (Firmware Analysis Script)

This script is a wrapper around the firmwalker.sh script and is responsible for the actual analysis of the firmware image. It processes the extracted firmware files and generates analysis results.

The script takes one argument: the path to the extracted firmware directory firmwalker_extracted_path.

firmwalker_analysis.py calls the firmwalker.sh Bash script to process the extracted firmware. The firmwalker.sh script analyzes the contents of the extracted directory (e.g., checking for passwords, configuration files, etc.).

After running firmwalker.sh, the script processes its output, extracting key sections like: passwd, shadow, conf files, bin files, etc. These sections can be added or removed. To see which sections are available, please refer to the firmwalker output taken from the script's GitHub repository.

A section is what comes after the 37 # characters, for example:

passwd
*id_rsa*
*.conf
emails

The results are saved in separate text files for each section as well as a file for the complete output.

The output file and results are stored in the firmwalker_results directory.

Firmwalker and Docker

The Firmwalker module is integrated into the project's Docker environment.

Dockerfile

The Dockerfile_firmwalker is used to ensure the proper installation and configuration of Firmwalker within the Docker container. The Dockerfile:

  • Uses python:3.11 as the base image
  • Updates the package lists and installs bash for script execution
  • Creates a Python virtual environment in /app/venv, upgrades pip, and installs necessary dependencies
  • Sets up the environment variable PATH to include the virtual environment
  • Sets the working directory to /app where all the needed files are copied to in the container
  • Gives executable permissions to the firmwalker.sh script
  • Specifies that the container should run python3 /app/firmwalker_service.py when started, initializing the Firmwalker API Service

Docker Compose

The newly made container is added to the docker-compose.yaml file found in the cloned project under firmware_vault/docker_compose_dir/docker-compose.yaml. This is done by adding the following as a service:

  firmwalker:
container_name: firmwalker
build:
context: ../jobs
dockerfile: Dockerfile_firmwalker
volumes:
- executor:/tasks
- scraper_downloads:/amos_project/downloads/
environment:
- DB_CONTAINER=${DATABASE_DB_CONTAINER}
- MYSQL_USER=${DATABASE_USER}
- MYSQL_PASSWORD=${DATABASE_PASSWORD}
- DB_SCHEMA=${DATABASE_SCHEMA}
- DB_PORT=${DATABASE_PORT}
networks:
- firmware_network
ports:
- "5004:5004"
restart: unless-stopped

This specifies:

  • The name of the service and container
  • The build context and Dockerfile to use
  • The volumes to persist data and share it between containers
  • The environment variables to set
  • The network to join
  • The port to map from inside the container to the host machine

Copying the Client-Side Script

The client-side script firmwalker.py is copied to the executor container by adding the following line to the Dockerfile_executor file found under /jobs:

COPY firmwalker.py /working_dir

This ensures that the client-side script is available in the executor container and can be used to send requests to the Firmwalker service.