fkie-cad / FACT_docker

Dockerfile for building the FACT container
GNU General Public License v3.0
21 stars 10 forks source link

PDF Report results in Internal Server Error #27

Closed frakman1 closed 1 year ago

frakman1 commented 1 year ago

Using docker-compose with version 4.0.1 of FACT. Running on Ubuntu 20.04.2 docker version: 20.10.7 docker-compose version: 1.29.2

I analysed some firmware and clicked on the Generate PDF report button that resulted in an error.

Error trace:

[2022-10-04 06:59:39][app][ERROR]: Exception on /pdf-download/65e91cded702aed752bdecde9797cbdba50aba8b2c63dba9fdb62d5e79da6827_55250944 [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 2077, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1525, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.8/dist-packages/flask_restx/api.py", line 672, in error_router
    return original_handler(e)
  File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/opt/FACT_core/src/./web_interface/security/decorator.py", line 11, in decorated_view
    return fn(*args, **kwargs)
  File "/opt/FACT_core/src/./web_interface/components/io_routes.py", line 130, in download_pdf_report
    with TemporaryDirectory(dir=self._config['data-storage']['docker-mount-base-dir']) as folder:
  File "/usr/lib/python3.8/tempfile.py", line 919, in __init__
    self.name = mkdtemp(suffix, prefix, dir)
  File "/usr/lib/python3.8/tempfile.py", line 497, in mkdtemp
    _os.mkdir(file, 0o700)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/fact-docker-mount-base-dir/tmpdvzw3stc'

Steps to create FACT:

git clone https://github.com/fkie-cad/FACT_docker
cd FACT_docker/
export FACT_DOCKER_VERSION=4.0.1
make
docker images
docker tag 2d1475e71d58  fkie-cad/fact-core-scripts:4.0.1
docker tag 3b05a4ab75a6  fkie-cad/fact-core-frontend:4.0.1
docker tag b018af4cd9c4  fkie-cad/fact-core-backend:4.0.1
docker tag 574ca72d5703  fkie-cad/fact-core-common:4.0.1
./start.py pull
mkdir fact-data
./start.py compose-env --firmware-file-storage-dir /home/user/git/fact/FACT_docker/fact-data
eval $(./start.py compose-env --firmware-file-storage-dir  /home/user/git/fact/FACT_docker/fact-data)
export FACT_DOCKER_POSTGRES_PASSWORD=mypassword
docker-compose up -d database
./start.py initialize-db --network fact_docker_fact-network
docker-compose up
frakman1 commented 1 year ago

Thank you for the update. I just tested it.

I updated the docker-compose.yml file and re-ran the steps above starting from ./start.py because I was in a new shell and lost my environment variables. When I did all that, FACT runs but it seems I lost all my previous analysis and it starts with a fresh installation. I thought the fact-data folder I specified above would get re-used.

Is the docker-compose up-d database supposed to be a one-time operation? What is the correct way to restart FACT without losing history?

jstucke commented 1 year ago

Normally you shouldn't lose the contents of your database. Since FACT 4.0 switched from MongoDB to PostgreSQL and FACT_docker now uses a database in a separate docker container, you would lose your database contents if you switch the container (e.g. by downloading a newer version of the image). But theoretically the old database container should still be there (since it shouldn't be automatically removed). Do you see other instances of the DB container if you run docker container ls -a? It should be possible to export the DB contents and import it in the new container.

I thought the fact-data folder I specified above would get re-used.

This folder is used for something different than the DB: The fact-data folder contains the actual files from the firmware and the DB contains analysis, comparison results and metadata (and some more stuff like cached binary search results). In the old version (pre 4.0) there was another folder with the actual DB contents.

Maybe we need to find a way to mount the DB's contents like before if this happens regularly. It should also be possible with PostgreSQL.

frakman1 commented 1 year ago

No, I don't see any other database containers.

$ docker container ls -a
CONTAINER ID   IMAGE                               COMMAND                  CREATED             STATUS             PORTS                                               NAMES
7d429567122c   fkie-cad/fact-core-frontend:4.0.1   "/usr/local/bin/entr…"   About an hour ago   Up About an hour   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp           fact_docker-fact-frontend-1
c107ccae74f2   fkie-cad/fact-core-backend:4.0.1    "/usr/local/bin/entr…"   About an hour ago   Up About an hour                                                       fact_docker-fact-backend-1
52574f66feea   postgres                            "docker-entrypoint.s…"   About an hour ago   Up About an hour   5432/tcp                                            fact_docker-database-1
52c205a8b010   redis                               "docker-entrypoint.s…"   About an hour ago   Up About an hour   6379/tcp                                            fact_docker-redis-1
22227f15e563   fkiecad/radare-web-gui:latest       "python3 src/serve.py"   20 hours ago        Up 20 hours                                                            radare_app_1
34e62c69975b   radare_server                       "/docker-entrypoint.…"   20 hours ago        Up 20 hours        80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   radare_server_1

Also, do I need to run all this every time?

docker-compose up -d database
./start.py initialize-db --network fact_docker_fact-network
docker-compose up

I think the initialize-db is what broke it.

Normally, I just run docker-compose up and docker-compose down in other docker projects. Is that also true for FACT?

jstucke commented 1 year ago

"initialize-db" executes the init_postgres.py script from FACT and this script should not affect your data (I just tested it on my local FACT installation). But it should not be necessary to run this more than once. The docker-compose up -d database should run the db container in the background (but it should probably also work to just use docker-compose up to start all containers at once).

I'm still not sure what may have erased your database, but I think a newly created database container is the most probable cause (if the DB container is replaced, the DB contents are also replaced). I think it would be best to use a common docker volume for the database as described here so that the database contents are not lost if the container is replaced.

frakman1 commented 1 year ago

I think it would be best to use a common docker volume for the database as described here so that the database contents are not lost if the container is replaced.

I think this would be an excellent addition.

jstucke commented 1 year ago

Did you get a chance to test out if the error still occurs when you try to generate a PDF report?

jstucke commented 1 year ago

I added a volume in #30 but was unable to try it out yet if it works as expected

frakman1 commented 1 year ago

I'm running a new full analysis of the firmware now. It takes several hours so I'll report back when it's done.

FYI, it would be nice if there was a 'full' Analysis Preset pull-down option (or just a Select All, Select None option) when selecting the plugins to run in the Upload Firmware page. Then I can uncheck the ones I don't want intead of manually checking all but one or two right now.

frakman1 commented 1 year ago

Yes, the PDF report feature is now working after applying #28 Thank you for your support.

jstucke commented 1 year ago

FYI, it would be nice if there was a 'full' Analysis Preset pull-down option

You can add custom presets easily be adding new entries in the main.cfg file under section [default-plugins] (the config file in the FACT_docker folder should get mounted into the FACT docker container)

frakman1 commented 1 year ago

It happened again. (Firmware database lost). I think I know why now after reading your explanation. docker-compose down stops and removes containers. What I should have used is docker-compose start and stop

frakman1 commented 1 year ago

FYI, it would be nice if there was a 'full' Analysis Preset pull-down option

You can add custom presets easily be adding new entries in the main.cfg file under section [default-plugins] (the config file in the FACT_docker folder should get mounted into the FACT docker container)

This is excellent news! Thank you. I got it to work:

image

For reference, I added the following in main.cfg

full = unpacker, file_type, crypto_hints, binwalk, users_and_passwords, printable_strings, malware_scanner, software_components, ip_and_uri_finder, crypto_material, qemu_exec, file_system_metadata, input_vectors, interesting_uris, string_evaluator, source_code_analysis, exploit_mitigations, device_tree, cpu_architecture, elf_analysis, file_hashes, cve_lookup, init_systems, kernel_config, hardware_analysis, cwe_checker, known_vulnerabilities, tlsh, hashlookup, information_leaks

I got the list of plugins from the fact_docker-fact-frontend-1 docker container within the /opt/FACT_core/src/plugins/analysis directory.

frakman1 commented 1 year ago

I noticed that after doing a docker-compose stop (or even down) that the radare containers stay up.

$ docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED      STATUS      PORTS                                               NAMES
22227f15e563   fkiecad/radare-web-gui:latest   "python3 src/serve.py"   2 days ago   Up 2 days                                                       radare_app_1
34e62c69975b   radare_server                   "/docker-entrypoint.…"   2 days ago   Up 2 days   80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   radare_server_1

I am guessing that one of the intermediate containers start it but does not shut it down afterwards. Perhaps worth looking into.

maringuu commented 1 year ago

I noticed that after doing a docker-compose stop (or even down) that the radare containers stay up.

Created #32 to track this.