81 lines
2.9 KiB
Python
81 lines
2.9 KiB
Python
"""Asynchronous worker for analyzing image submissions."""
|
|
|
|
import threading
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from .analyzers.binwalk import analyze_binwalk
|
|
from .analyzers.decomposer import analyze_decomposer
|
|
from .analyzers.exiftool import analyze_exiftool
|
|
from .analyzers.foremost import analyze_foremost
|
|
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 .analyzers.image_resize import analyze_image_resize
|
|
from .app import app, db
|
|
from .config import RESULT_FOLDER
|
|
from .models import Image, Submission
|
|
|
|
|
|
def analyze_image(submission_hash: str) -> None:
|
|
"""Analyze an image submission in separate threads."""
|
|
with app.app_context():
|
|
submission: Submission = Submission.query.get(submission_hash) # type: ignore
|
|
image = Image.query.get_or_404(submission.image_hash) # type: ignore
|
|
|
|
if not submission or not image: # No submission found
|
|
return
|
|
|
|
submission.status = "running" # type: ignore
|
|
db.session.commit()
|
|
|
|
try:
|
|
img_path: Path = Path(image.file)
|
|
result_path: Path = RESULT_FOLDER / str(image.hash) / str(submission.hash)
|
|
result_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
threads: list[threading.Thread] = []
|
|
|
|
def run_analyzer(analyzer_func: Any, *args: Any) -> None:
|
|
"""Run an analyzer function in a separate thread."""
|
|
try:
|
|
analyzer_func(*args)
|
|
except Exception as e:
|
|
print(f"Error in {analyzer_func.__name__}: {e}")
|
|
|
|
analyzers = [
|
|
(analyze_binwalk, img_path, result_path),
|
|
(analyze_decomposer, img_path, result_path),
|
|
(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),
|
|
(analyze_image_resize, img_path, result_path),
|
|
]
|
|
|
|
# Deep analysis only
|
|
if submission.deep_analysis:
|
|
analyzers.extend(
|
|
[
|
|
(analyze_outguess, img_path, result_path),
|
|
]
|
|
)
|
|
|
|
for analyzer in analyzers:
|
|
thread = threading.Thread(target=run_analyzer, args=analyzer)
|
|
threads.append(thread)
|
|
thread.start()
|
|
|
|
for thread in threads:
|
|
thread.join()
|
|
|
|
submission.status = "completed"
|
|
except Exception:
|
|
submission.status = "error"
|
|
finally:
|
|
db.session.commit()
|