From 5c0776d144fb6948e7115ed08b881363df239009 Mon Sep 17 00:00:00 2001 From: Memphis Marshall Date: Tue, 22 Jul 2025 23:36:31 +0800 Subject: [PATCH 1/4] Resolved problems listed in #86 --- aperisolve/analyzers/steghide.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/aperisolve/analyzers/steghide.py b/aperisolve/analyzers/steghide.py index 58a5f48..1f50f7a 100644 --- a/aperisolve/analyzers/steghide.py +++ b/aperisolve/analyzers/steghide.py @@ -61,9 +61,9 @@ def analyze_steghide( "steghide", "extract", "-sf", - "../" + str(image_name), + "../../" + str(image_name), "-xf", - str(embedded_filename), + str(embedded_file.name), ] if password: cmd_ext += ["-p", password] @@ -72,13 +72,19 @@ def analyze_steghide( data = subprocess.run( cmd_ext, - cwd=output_dir, + cwd=extracted_dir, capture_output=True, text=True, check=False, timeout=MAX_PENDING_TIME, ) - stderr += data.stderr + # Filter out lines that indicate success + stdout = [] + for line in data.stderr.split("\n"): + if line.startswith("wrote extracted data to \""): + stdout.append(line) + elif line: + stderr += line + "\n" # Zip extracted files zip_data = subprocess.run( @@ -94,7 +100,7 @@ def analyze_steghide( if len(stderr) > 0: err = { - "binwalk": { + "steghide": { "status": "error", "error": stderr, } @@ -110,7 +116,7 @@ def analyze_steghide( { "steghide": { "status": "ok", - "output": data.stdout.split("\n") if data else [], + "output": stdout, "download": f"/download/{output_dir.name}/steghide", } }, From 0c661651a6ef1b76f57fbd0661f3daed2471101d Mon Sep 17 00:00:00 2001 From: 0xlildoudou <67382584+0xlildoudou@users.noreply.github.com> Date: Tue, 4 Nov 2025 14:52:28 +0000 Subject: [PATCH 2/4] add pngcheck --- README.md | 3 ++- aperisolve/analyzers/pngcheck.py | 40 ++++++++++++++++++++++++++++++ aperisolve/static/js/aperisolve.js | 1 + aperisolve/workers.py | 2 ++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 aperisolve/analyzers/pngcheck.py diff --git a/README.md b/README.md index f56b173..ced6f7b 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ The platform allow you to: - **Visualise `binwalk` informations** - **Download `binwalk` files** such as zip in png headers - **Download `foremost` files** such as zip in png headers +- **Visualise `pngcheck` output** - **Visualise `strings` output** ## Installation @@ -93,7 +94,7 @@ GitHub CI will alert in case of failure. ## Roadmap -- [ ] PngCheck +- [x] PngCheck - [ ] Zsteg extract / --all --> **Download `zsteg` files** such as mp3 encoded on LSB - [ ] Test on mobile - [ ] i18n diff --git a/aperisolve/analyzers/pngcheck.py b/aperisolve/analyzers/pngcheck.py new file mode 100644 index 0000000..835f968 --- /dev/null +++ b/aperisolve/analyzers/pngcheck.py @@ -0,0 +1,40 @@ +"""Pngcheck Analyzer for Image Submissions.""" + +import subprocess +from pathlib import Path + +from .utils import MAX_PENDING_TIME, update_data + + +def analyze_pngcheck(input_img: Path, output_dir: Path) -> None: + """Analyze an image submission using strings.""" + + try: + data = subprocess.run( + ["pngcheck", "-v",input_img], + capture_output=True, + text=True, + check=False, + timeout=MAX_PENDING_TIME, + ) + # Error based on https://github.com/pnggroup/pngcheck/issues/59 + # if data.stderr: + # update_data( + # output_dir, {"pngcheck": {"status": "error", "error": data.stderr}} + # ) + # return + + data_strings = data.stdout.split("\n") if data else [] + data_strings = [s for s in data_strings if s] + + update_data( + output_dir, + { + "pngcheck": { + "status": "ok", + "output": data_strings, + } + }, + ) + except Exception as e: + update_data(output_dir, {"pngcheck": {"status": "error", "error": str(e)}}) diff --git a/aperisolve/static/js/aperisolve.js b/aperisolve/static/js/aperisolve.js index a951ebf..3127aa6 100644 --- a/aperisolve/static/js/aperisolve.js +++ b/aperisolve/static/js/aperisolve.js @@ -4,6 +4,7 @@ const TOOL_ORDER = [ "binwalk", "foremost", "outguess", + "pngcheck", "steghide", "zsteg", "strings", diff --git a/aperisolve/workers.py b/aperisolve/workers.py index d595654..963bb1e 100644 --- a/aperisolve/workers.py +++ b/aperisolve/workers.py @@ -12,6 +12,7 @@ from .analyzers.outguess import analyze_outguess from .analyzers.steghide import analyze_steghide from .analyzers.strings import analyze_strings from .analyzers.zsteg import analyze_zsteg +from .analyzers.pngcheck import analyze_pngcheck from .app import app, db from .config import RESULT_FOLDER from .models import Image, Submission @@ -49,6 +50,7 @@ def analyze_image(submission_hash: str) -> None: (analyze_exiftool, img_path, result_path), (analyze_foremost, img_path, result_path), (analyze_strings, img_path, result_path), + (analyze_pngcheck, img_path, result_path), (analyze_steghide, img_path, result_path, submission.password), (analyze_zsteg, img_path, result_path), ] From 3cabd8c75285dd49fdba76b034e16aa32fe04c51 Mon Sep 17 00:00:00 2001 From: Zeecka Date: Fri, 7 Nov 2025 18:24:11 +0100 Subject: [PATCH 3/4] Lint --- aperisolve/analyzers/pngcheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aperisolve/analyzers/pngcheck.py b/aperisolve/analyzers/pngcheck.py index 835f968..fa32faf 100644 --- a/aperisolve/analyzers/pngcheck.py +++ b/aperisolve/analyzers/pngcheck.py @@ -11,7 +11,7 @@ def analyze_pngcheck(input_img: Path, output_dir: Path) -> None: try: data = subprocess.run( - ["pngcheck", "-v",input_img], + ["pngcheck", "-v", input_img], capture_output=True, text=True, check=False, From b00e1b45c71438f580f55b773a1cce198deeaf3b Mon Sep 17 00:00:00 2001 From: Zeecka Date: Fri, 7 Nov 2025 18:29:19 +0100 Subject: [PATCH 4/4] Lint (black) --- aperisolve/analyzers/steghide.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aperisolve/analyzers/steghide.py b/aperisolve/analyzers/steghide.py index 1f50f7a..8a12ce9 100644 --- a/aperisolve/analyzers/steghide.py +++ b/aperisolve/analyzers/steghide.py @@ -81,7 +81,7 @@ def analyze_steghide( # Filter out lines that indicate success stdout = [] for line in data.stderr.split("\n"): - if line.startswith("wrote extracted data to \""): + if line.startswith('wrote extracted data to "'): stdout.append(line) elif line: stderr += line + "\n"