Lucene search
K

📄 Ubuntu 25.10 Containerd Insecure Directory Permissions

🗓️ 09 Mar 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 160 Views

POC tool detects CVE-2024-25621 in containerd by auditing /var/lib/containerd permissions.

Related
Code
=============================================================================================================================================
    | # Title     : Ubuntu 25.10 Containerd Insecure Directory Permissions Vulnerability                                                        |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits)                                                            |
    | # Vendor    : https://ubuntu.com/                                                                                                         |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/214598/ & CVE-2024-25621, CVE-2025-64329
    
    [+] Summary    : This Proof of Concept (PoC) demonstrates and detects CVE-2024-25621, a security vulnerability in containerd caused by insecure permissions on critical runtime and data directories. 
                     Affected versions may expose container metadata and runtime artifacts due to directories being readable or writable by non-privileged users.
                     The scanner checks the installed containerd version against known vulnerable ranges and audits permissions on sensitive directories such as /var/lib/containerd and /run/containerd/*. 
    				 When verbose mode is enabled, it safely tests read/write access without performing destructive actions, with optional dry-run support.
                     If vulnerable conditions are detected, the tool highlights potential impacts including unauthorized access, information disclosure, and possible privilege escalation, 
    				 and provides clear remediation guidance such as upgrading containerd and correcting directory permissions.
    
    [+] Usage : 
    
    chmod +x poc_cve_2024_25621.py
    
    ./poc_cve_2024_25621.py --verbose
    
    ./poc_cve_2024_25621.py --dry-run
    
    
    [+] POC : 
    
    #!/usr/bin/env python3
    
    import os
    import stat
    import sys
    import subprocess
    import argparse
    import re
    from datetime import datetime
    
    class ContainerdPoC:
        def __init__(self, verbose=False, dry_run=False):
            self.verbose = verbose
            self.dry_run = dry_run
            self.vulnerable_dirs = [
                "/var/lib/containerd",
                "/run/containerd/io.containerd.grpc.v1.cri",
                "/run/containerd/io.containerd.sandbox.controller.v1.shim"
            ]
            self.vulnerable_versions = {
                "1.7.0": "1.7.28",
                "2.0.0": "2.0.6",
                "2.1.0": "2.1.4",
                "2.2.0": "2.2.0"
            }
            self.test_files = []
    
        def log(self, message, level="INFO"):
            ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            print(f"[{ts}] [{level}] {message}")
    
        def check_permissions(self, path):
            try:
                if not os.path.exists(path):
                    return None, "Directory does not exist"
    
                st = os.stat(path)
                perms = stat.S_IMODE(st.st_mode)
                perm_str = oct(perms)[-3:]
    
                group_write = bool(perms & stat.S_IWGRP)
                other_write = bool(perms & stat.S_IWOTH)
                group_read = bool(perms & stat.S_IRGRP)
                other_read = bool(perms & stat.S_IROTH)
    
                vulnerable = group_write or other_write
    
                return {
                    "path": path,
                    "permissions": perm_str,
                    "group_write": group_write,
                    "other_write": other_write,
                    "group_read": group_read,
                    "other_read": other_read,
                    "vulnerable": vulnerable,
                    "uid": st.st_uid,
                    "gid": st.st_gid
                }
            except Exception as e:
                return None, str(e)
    
        def check_containerd_version(self):
            try:
                r = subprocess.run(
                    ["containerd", "--version"],
                    capture_output=True,
                    text=True,
                    timeout=5
                )
                if r.returncode == 0:
                    m = re.search(r'v(\d+\.\d+\.\d+)', r.stdout)
                    if m:
                        return m.group(1), r.stdout.strip()
                return None, "Cannot determine version"
            except FileNotFoundError:
                return None, "containerd not found"
            except Exception as e:
                return None, str(e)
    
        def test_directory_access(self, directory):
            tests = []
    
            try:
                os.listdir(directory)
                tests.append(("LIST", "SUCCESS", "Directory readable"))
            except PermissionError:
                tests.append(("LIST", "FAILED", "Permission denied"))
            except Exception as e:
                tests.append(("LIST", "ERROR", str(e)))
    
            if self.dry_run:
                tests.append(("WRITE", "SKIPPED", "Dry-run enabled"))
                return tests
    
            test_file = os.path.join(
                directory, f".test_cve_2024_25621_{os.getpid()}"
            )
    
            try:
                with open(test_file, "w") as f:
                    f.write("PoC Test\n")
    
                self.test_files.append(test_file)
                tests.append(("WRITE", "SUCCESS", "File created"))
    
                with open(test_file, "r") as f:
                    f.read()
                tests.append(("READ", "SUCCESS", "File read"))
    
            except PermissionError:
                tests.append(("WRITE", "FAILED", "Permission denied"))
            except Exception as e:
                tests.append(("WRITE", "ERROR", str(e)))
    
            return tests
    
        def compare_versions(self, v1, v2):
            def normalize(v):
                v = re.sub(r'[-_].*$', '', v)
                return [int(x) for x in v.split('.')]
    
            a = normalize(v1)
            b = normalize(v2)
            return (a > b) - (a < b)
    
        def cleanup(self):
            for f in self.test_files:
                try:
                    if os.path.exists(f):
                        os.remove(f)
                except:
                    pass
    
        def run_scan(self):
            print("=" * 60)
            print("Containerd CVE-2024-25621 Vulnerability Scanner By indoushka")
            print("=" * 60)
    
            print("\n[1] Checking containerd version...")
            version, info = self.check_containerd_version()
            if version:
                print(f"  Version: {version}")
                vulnerable = False
                for min_v, max_v in self.vulnerable_versions.items():
                    if self.compare_versions(min_v, version) <= 0 and \
                       self.compare_versions(version, max_v) <= 0:
                        vulnerable = True
                        print(f"    VULNERABLE ({min_v} → {max_v})")
                        break
                if not vulnerable:
                    print(" Version appears patched")
            else:
                print(f"  {info}")
    
            print("\n[2] Checking directory permissions...")
            found = []
            for d in self.vulnerable_dirs:
                r, e = self.check_permissions(d)
                if r:
                    print(f"\n  {d}")
                    print(f"  Perms: {r['permissions']} | Vulnerable: {r['vulnerable']}")
                    if r["vulnerable"]:
                        found.append(d)
                    if self.verbose:
                        for t in self.test_directory_access(d):
                            print(f"    {t[0]}: {t[1]} - {t[2]}")
                else:
                    print(f"\n  {d} - {e}")
    
            print("\n" + "=" * 60)
            if found:
                print(" SYSTEM IS VULNERABLE")
                for d in found:
                    print(f"  - {d}")
            else:
                print(" SYSTEM APPEARS SECURE")
            print("=" * 60)
    
    
    def main():
        p = argparse.ArgumentParser()
        p.add_argument("-v", "--verbose", action="store_true")
        p.add_argument("-d", "--dry-run", action="store_true")
        args = p.parse_args()
    
        poc = ContainerdPoC(args.verbose, args.dry_run)
        try:
            poc.run_scan()
        finally:
            poc.cleanup()
    
    
    if __name__ == "__main__":
        main()
    
    		
    Greetings to :============================================================
    jericho * Larry W. Cashdollar * r00t * Malvuln (John Page aka hyp3rlinx)*|
    ==========================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

09 Mar 2026 00:00Current
5.8Medium risk
Vulners AI Score5.8
CVSS 3.17.3 - 7.8
CVSS 46.9
EPSS0.00148
SSVC
160