This commit is contained in:
Zeecka
2025-12-28 10:33:46 +01:00
parent 35bb0a5aea
commit d0c2f24800
3 changed files with 56 additions and 59 deletions
+15 -20
View File
@@ -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"]
+5 -3
View File
@@ -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 [],
+36 -36
View File
@@ -252,6 +252,38 @@ function parseResult(result) {
analyzer.innerHTML += `<h2>${capitalize(tool.replace("_"," "))}</h2>`;
// Parse text output
if (typeof result[tool]["output"] === "string") {
analyzer.innerHTML += `<pre>${escapeHtml(
result[tool]["output"]
)}</pre>`;
} else if (Array.isArray(result[tool]["output"])) {
if (result[tool]["output"].length > 0) {
var texarea_content = `<div class="textarea-container">`;
texarea_content += `<textarea class="form-control w-100 mb-2" rows="8" readonly>`;
for (const line of result[tool]["output"]) {
texarea_content += escapeHtml(`${line}\n`);
}
texarea_content += `</textarea>`;
texarea_content += `<i class="fas fa-copy copy-icon"></i>`;
texarea_content += `</div>`;
analyzer.innerHTML += texarea_content;
}
} else if (typeof result[tool]["output"] === "object") {
var table_content = `<div class="table-container">`;
table_content += `<table>`;
for (const key in result[tool]["output"]) {
table_content += `<tr><td>${escapeHtml(key)}</td>`;
table_content += `<td>${escapeHtml(
result[tool]["output"][key]
)}</td></tr>`;
}
table_content += `</table>`;
table_content += `</table>`;
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 += `<pre>${escapeHtml(
result[tool]["output"]
)}</pre>`;
} else if (Array.isArray(result[tool]["output"])) {
if (result[tool]["output"].length > 0) {
var texarea_content = `<div class="textarea-container">`;
texarea_content += `<textarea class="form-control w-100 mb-2" rows="8" readonly>`;
for (const line of result[tool]["output"]) {
texarea_content += escapeHtml(`${line}\n`);
}
texarea_content += `</textarea>`;
texarea_content += `<i class="fas fa-copy copy-icon"></i>`;
texarea_content += `</div>`;
analyzer.innerHTML += texarea_content;
}
} else if (typeof result[tool]["output"] === "object") {
var table_content = `<div class="table-container">`;
table_content += `<table>`;
for (const key in result[tool]["output"]) {
table_content += `<tr><td>${escapeHtml(key)}</td>`;
table_content += `<td>${escapeHtml(
result[tool]["output"][key]
)}</td></tr>`;
}
table_content += `</table>`;
table_content += `</table>`;
analyzer.innerHTML += table_content;
} else {
// analyzer.innerHTML += `<pre>${result[tool]["output"]}</pre>`;
}
if ("download" in result[tool]) {
// Parse download link
analyzer.innerHTML += `<br/><a href="${escapeHtml(
result[tool]["download"]
)}" target="_blank" class="btn btn-primary mt-2"><i class="fa fa-download"></i> Download file</a>`;
}
} else if (result[tool]["status"] === "error") {
}
// Parse errors
if (result[tool]["status"] === "error") {
showDanger(result[tool]["error"]);
}
}