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 scriptfirmwalker.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 databasepath
: The path to the extracted firmware image directoryoutput_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
, upgradespip
, 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.