From d0c2f2480044a974b5ec16fcceff0f3a6dd6a83e Mon Sep 17 00:00:00 2001 From: Zeecka Date: Sun, 28 Dec 2025 10:33:46 +0100 Subject: [PATCH 1/4] WIP --- Dockerfile | 35 +++++++-------- aperisolve/analyzers/binwalk.py | 8 ++-- aperisolve/static/js/aperisolve.js | 72 +++++++++++++++--------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/Dockerfile b/Dockerfile index fe69aa9..1ac3310 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,22 +3,14 @@ FROM python:3.14-slim AS build WORKDIR / # Install build tools and dependencies -RUN apt-get update && apt-get install -y \ - wget \ - default-jre \ - ruby \ - zip \ - 7zip -# Install steganography and forensics tools -RUN apt-get update && apt-get install -y \ - binwalk \ - foremost \ - exiftool \ - steghide \ - binutils \ - outguess \ - pngcheck \ + +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget default-jre ruby \ + bzip2 xz-utils gzip lzip lzma lzop tar unzip p7zip-full squashfs-tools \ + file qpdf cpio arj cabextract sharutils lz4 ccache mtd-utils \ + python3-lxml upx-ucl zlib1g-dev liblzma-dev \ + binwalk foremost exiftool steghide binutils outguess pngcheck \ && gem install zsteg # Install OpenStego @@ -26,17 +18,20 @@ RUN wget https://github.com/syvaidya/openstego/releases/download/openstego-0.8.6 dpkg -i /tmp/openstego.deb && \ rm /tmp/openstego.deb -# Clean up apt cache and remove useless packages -RUN apt-get remove -y wget && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - +# Copy application COPY aperisolve/ /aperisolve/ RUN mkdir -p /data +# Install Python dependencies RUN pip install --no-cache-dir -r /aperisolve/requirements.txt ENV PYTHONUNBUFFERED=1 +# Auto clean after build +RUN apt-get remove -y wget && \ + apt-get autoremove -y && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "--access-logfile", "-", "--error-logfile", "-", "--log-level", "info", "--capture-output", "aperisolve.wsgi:application"] diff --git a/aperisolve/analyzers/binwalk.py b/aperisolve/analyzers/binwalk.py index 32d6fec..823590c 100644 --- a/aperisolve/analyzers/binwalk.py +++ b/aperisolve/analyzers/binwalk.py @@ -3,6 +3,7 @@ import shutil import subprocess from pathlib import Path +from typing import Any from .utils import MAX_PENDING_TIME, update_data @@ -17,7 +18,7 @@ def analyze_binwalk(input_img: Path, output_dir: Path) -> None: stderr = "" # Run binwalk data = subprocess.run( - ["binwalk", "-e", "../" + str(image_name), "--run-as=root"], + ["binwalk", "--matryoshka", "-e", "../" + str(image_name), "--run-as=root"], cwd=output_dir, capture_output=True, text=True, @@ -45,16 +46,17 @@ def analyze_binwalk(input_img: Path, output_dir: Path) -> None: shutil.rmtree(extracted_dir) if len(stderr) > 0: - err = { + err: dict[str, dict[str, Any]] = { "binwalk": { "status": "error", + "output": data.stdout.split("\n") if data else [], "error": stderr, } } update_data(output_dir, err) return None - output_data = { + output_data: dict[str, dict[str, Any]] = { "binwalk": { "status": "ok", "output": data.stdout.split("\n") if data else [], diff --git a/aperisolve/static/js/aperisolve.js b/aperisolve/static/js/aperisolve.js index a093ce7..d7c1e89 100644 --- a/aperisolve/static/js/aperisolve.js +++ b/aperisolve/static/js/aperisolve.js @@ -252,6 +252,38 @@ function parseResult(result) { analyzer.innerHTML += `

${capitalize(tool.replace("_"," "))}

`; + // Parse text output + if (typeof result[tool]["output"] === "string") { + analyzer.innerHTML += `
${escapeHtml(
+        result[tool]["output"]
+      )}
`; + } else if (Array.isArray(result[tool]["output"])) { + if (result[tool]["output"].length > 0) { + var texarea_content = `
`; + texarea_content += ``; + texarea_content += ``; + texarea_content += `
`; + analyzer.innerHTML += texarea_content; + } + } else if (typeof result[tool]["output"] === "object") { + var table_content = `
`; + table_content += ``; + for (const key in result[tool]["output"]) { + table_content += ``; + table_content += ``; + } + table_content += `
${escapeHtml(key)}${escapeHtml( + result[tool]["output"][key] + )}
`; + table_content += ``; + analyzer.innerHTML += table_content; + } + + // Parse images, downloads, ... if (result[tool]["status"] === "ok") { if ("images" in result[tool]) { // Parse image output @@ -286,48 +318,16 @@ function parseResult(result) { } } - // Parse text output - - - if (typeof result[tool]["output"] === "string") { - analyzer.innerHTML += `
${escapeHtml(
-          result[tool]["output"]
-        )}
`; - } else if (Array.isArray(result[tool]["output"])) { - if (result[tool]["output"].length > 0) { - var texarea_content = `
`; - texarea_content += ``; - texarea_content += ``; - texarea_content += `
`; - analyzer.innerHTML += texarea_content; - } - } else if (typeof result[tool]["output"] === "object") { - var table_content = `
`; - table_content += ``; - for (const key in result[tool]["output"]) { - table_content += ``; - table_content += ``; - } - table_content += `
${escapeHtml(key)}${escapeHtml( - result[tool]["output"][key] - )}
`; - table_content += ``; - analyzer.innerHTML += table_content; - } else { - // analyzer.innerHTML += `
${result[tool]["output"]}
`; - } - if ("download" in result[tool]) { // Parse download link analyzer.innerHTML += `
Download file`; } - } else if (result[tool]["status"] === "error") { + } + + // Parse errors + if (result[tool]["status"] === "error") { showDanger(result[tool]["error"]); } } From 64f13f53c395c8235c9c00a7993c33fd35e77b6c Mon Sep 17 00:00:00 2001 From: Zeecka Date: Tue, 30 Dec 2025 17:06:08 +0100 Subject: [PATCH 2/4] Fix Dockerfile --- Dockerfile | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1ac3310..1c0ce92 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,14 +3,22 @@ FROM python:3.14-slim AS build WORKDIR / # Install build tools and dependencies +RUN apt-get update && apt-get install -y \ + wget \ + default-jdk \ + ruby \ + zip \ + 7zip - -RUN apt-get update && apt-get install -y --no-install-recommends \ - wget default-jre ruby \ - bzip2 xz-utils gzip lzip lzma lzop tar unzip p7zip-full squashfs-tools \ - file qpdf cpio arj cabextract sharutils lz4 ccache mtd-utils \ - python3-lxml upx-ucl zlib1g-dev liblzma-dev \ - binwalk foremost exiftool steghide binutils outguess pngcheck \ +# Install steganography and forensics tools +RUN apt-get update && apt-get install -y \ + binwalk \ + foremost \ + exiftool \ + steghide \ + binutils \ + outguess \ + pngcheck \ && gem install zsteg # Install OpenStego From 474ad6208588f1cf54300f2f30331cd7464763a5 Mon Sep 17 00:00:00 2001 From: Zeecka Date: Tue, 30 Dec 2025 17:08:34 +0100 Subject: [PATCH 3/4] fix error showing binwalk --- aperisolve/analyzers/binwalk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aperisolve/analyzers/binwalk.py b/aperisolve/analyzers/binwalk.py index 823590c..950d14a 100644 --- a/aperisolve/analyzers/binwalk.py +++ b/aperisolve/analyzers/binwalk.py @@ -45,7 +45,7 @@ def analyze_binwalk(input_img: Path, output_dir: Path) -> None: if extracted_dir.exists(): shutil.rmtree(extracted_dir) - if len(stderr) > 0: + if len(stderr) > 0 and not zip_exist: err: dict[str, dict[str, Any]] = { "binwalk": { "status": "error", From 12382fee6ab9e4fcfc707f4622d1233f150ae4fd Mon Sep 17 00:00:00 2001 From: Zeecka Date: Tue, 30 Dec 2025 17:10:14 +0100 Subject: [PATCH 4/4] add comments --- aperisolve/analyzers/binwalk.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aperisolve/analyzers/binwalk.py b/aperisolve/analyzers/binwalk.py index 950d14a..6c05b9a 100644 --- a/aperisolve/analyzers/binwalk.py +++ b/aperisolve/analyzers/binwalk.py @@ -45,6 +45,8 @@ def analyze_binwalk(input_img: Path, output_dir: Path) -> None: if extracted_dir.exists(): shutil.rmtree(extracted_dir) + # Only report error if stderr exists AND extraction failed. + # If zip_exist is True, binwalk worked (despite warnings), so we proceed. if len(stderr) > 0 and not zip_exist: err: dict[str, dict[str, Any]] = { "binwalk": {