{"uuid": "1d630eae-ffc7-484d-b3d1-76e949dda2c2", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-31431", "type": "seen", "source": "https://gist.github.com/walleralexander/d880563c357deab2c385b6f5f35cc254", "content": "#!/usr/bin/env bash\n# check-copy-fail.sh\n# Nicht-destruktive Pr\u00fcfung auf CVE-2026-31431 (\"Copy Fail\") f\u00fcr Ubuntu. \n# Fragt automatisch die Ubuntu Security API ab und vergleicht Versionen.\n# Kein Exploit, keine \u00c4nderungen am System.\n\nset -u\n\nCVE_ID=\"CVE-2026-31431\"  \nAPI_URL=\"https://ubuntu.com/security/cves/${CVE_ID}.json\"  \n\n# --- Argumente ---------------------------------------------------------------\nVERBOSE=0\nfor arg in \"$@\"; do  \n    case \"$arg\" in  \n        -v|--verbose) VERBOSE=1 ;;\n        -h|--help)\n            cat &lt;/dev/null 2&gt;&amp;1 || MISSING=\"$MISSING $tool\"  \ndone\n[ -n \"$MISSING\" ] &amp;&amp; warn \"Fehlende Tools:$MISSING\"  \n\n# --- 1. Distribution + Release-Codename --------------------------------------\necho \"${B}[1/5] Distribution${N}\"  \nRELEASE_CODENAME=\"\"  \nif [ -r /etc/os-release ]; then\n    . /etc/os-release\n    info \"$PRETTY_NAME\"  \n    RELEASE_CODENAME=\"${UBUNTU_CODENAME:-${VERSION_CODENAME:-}}\"  \n    info \"Codename: ${RELEASE_CODENAME:-unbekannt}\"  \n    [ \"${ID:-}\" != \"ubuntu\" ] &amp;&amp; warn \"Nicht Ubuntu \u2014 Ergebnisse evtl. ungenau.\"  \nelse\n    warn \"/etc/os-release nicht lesbar.\"  \nfi\necho\n\n# --- 2. Kernel-Version + installiertes Paket ---------------------------------\necho \"${B}[2/5] Kernel &amp; Paket${N}\"  \nKVER=$(uname -r)\ninfo \"Laufender Kernel: $KVER\"  \n\nKPKG=\"linux-image-${KVER}\"  \nINSTALLED_VER=\"\"  \nSOURCE_PKG=\"\"  \nif dpkg-query -W -f='${Version}' \"$KPKG\" &gt;/dev/null 2&gt;&amp;1; then  \n    INSTALLED_VER=$(dpkg-query -W -f='${Version}' \"$KPKG\")  \n    SOURCE_PKG=$(dpkg-query -W -f='${source:Package}' \"$KPKG\" 2&gt;/dev/null)  \n\n    # Ubuntu trackt CVEs unter dem unsignierten Kernel-Source-Paket.\n    # 'linux-signed-hwe-6.17' -&gt; 'linux-hwe-6.17' \n    # 'linux-signed'          -&gt; 'linux' \n    # 'linux-signed-aws'      -&gt; 'linux-aws' \n    SOURCE_PKG_TRACK=$(echo \"$SOURCE_PKG\" | sed -E 's/^linux-signed(-|$)/linux\\1/; s/-$//')  \nelse\n    warn \"Kernel-Paket nicht via dpkg auffindbar (Custom-Kernel?).\"  \n    SOURCE_PKG_TRACK=\"\"  \nfi\n\nREBOOT_PENDING=0\nif [ -f /var/run/reboot-required ]; then\n    warn \"Reboot ausstehend \u2014 neuer Kernel erst nach Reboot aktiv!\"  \n    REBOOT_PENDING=1\nfi\necho\n\n# --- 3. Patch-Status via Ubuntu Security API ---------------------------------\necho \"${B}[3/5] Patch-Status (Ubuntu Security API)${N}\"  \nPATCH_STATUS=\"unknown\"  \nKMOD_FIX_STATUS=\"unknown\"   # 'patched' | 'vulnerable' | 'unknown'  \nFIXED_VER=\"\"  \n\nif [ -n \"$RELEASE_CODENAME\" ] &amp;&amp; command -v curl &gt;/dev/null &amp;&amp; command -v python3 &gt;/dev/null; then  \n\n    info \"Frage $API_URL ab...\"  \n    JSON=$(curl -fsSL --max-time 10 \"$API_URL\" 2&gt;/dev/null || echo \"\")  \n\n    if [ -n \"$JSON\" ]; then  \n        # --- 3a: kmod-Mitigation (USN-8226-1) pr\u00fcfen ------------------------\n        # Ubuntu liefert die Mitigation aktuell nur \u00fcber das kmod-Paket,\n        # das algif_aead via modprobe.d blockiert. Das steht in 'notices'. \n        KMOD_FIX_VER=$(printf '%s' \"$JSON\" | REL=\"$RELEASE_CODENAME\" python3 -c '  \nimport json, sys, os\ntry: data = json.load(sys.stdin)\nexcept Exception: sys.exit(0)\nrel = os.environ[\"REL\"]  \nfor n in data.get(\"notices\", []):  \n    rps = n.get(\"release_packages\", {}).get(rel, [])  \n    for p in rps:\n        if p.get(\"name\") == \"kmod\" and p.get(\"is_source\"):  \n            print(p.get(\"version\", \"\")); sys.exit(0)  \n' 2&gt;/dev/null)  \n\n        if [ -n \"$KMOD_FIX_VER\" ]; then  \n            INSTALLED_KMOD=$(dpkg-query -W -f='${Version}' kmod 2&gt;/dev/null || echo \"\")  \n            if [ -n \"$INSTALLED_KMOD\" ]; then  \n                if dpkg --compare-versions \"$INSTALLED_KMOD\" ge \"$KMOD_FIX_VER\"; then  \n                    ok \"kmod-Mitigation ist installiert (USN-8226-1).\"  \n                    KMOD_FIX_STATUS=\"patched\"  \n                else\n                    vuln \"kmod-Mitigation FEHLT \u2014 installiert: $INSTALLED_KMOD, ben\u00f6tigt: $KMOD_FIX_VER\"  \n                    KMOD_FIX_STATUS=\"vulnerable\"  \n                fi\n            else\n                warn \"kmod-Paket nicht gefunden \u2014 Mitigation-Status unklar.\"  \n            fi\n        fi\n\n        # --- 3b: Kernel-Patch pr\u00fcfen ----------------------------------------\n        CANDIDATES=\"$SOURCE_PKG_TRACK\"  \n        case \"$SOURCE_PKG_TRACK\" in  \n            linux-hwe-*|linux-hwe)\n                CANDIDATES=\"$CANDIDATES linux-hwe linux\"  \n                ;;\n            linux-aws*|linux-azure*|linux-gcp*|linux-oracle*)\n                CANDIDATES=\"$CANDIDATES linux\"  \n                ;;\n        esac\n\n        RESULT=\"\"  \n        MATCHED_PKG=\"\"  \n        if [ -n \"$SOURCE_PKG_TRACK\" ]; then  \n            for cand in $CANDIDATES; do\n                R=$(printf '%s' \"$JSON\" | SRC=\"$cand\" REL=\"$RELEASE_CODENAME\" python3 -c '  \nimport json, sys, os\ntry: data = json.load(sys.stdin)\nexcept Exception as e: print(\"ERROR|\"+str(e)); sys.exit(0)  \nsrc = os.environ[\"SRC\"]; rel = os.environ[\"REL\"]  \nfor pkg in data.get(\"packages\", []):  \n    if pkg.get(\"name\") != src: continue  \n    for st in pkg.get(\"statuses\", []):  \n        if st.get(\"release_codename\") == rel:  \n            print(f\"{st.get(\\\"status\\\",\\\"?\\\")}|{st.get(\\\"description\\\",\\\"\\\") or \\\"\\\"}\")  \n            sys.exit(0)\nprint(\"not_found|\")  \n' 2&gt;/dev/null)  \n                S=$(echo \"$R\" | cut -d'|' -f1)  \n                if [ \"$S\" != \"not_found\" ] &amp;&amp; [ \"$S\" != \"ERROR\" ] &amp;&amp; [ -n \"$S\" ]; then  \n                    RESULT=\"$R\"; MATCHED_PKG=\"$cand\"; break  \n                fi\n            done\n        fi\n\n        [ -z \"$RESULT\" ] &amp;&amp; RESULT=\"not_found|\"  \n        STATUS=$(echo \"$RESULT\" | cut -d'|' -f1)  \n        DESCR=$(echo \"$RESULT\" | cut -d'|' -f2-)  \n        [ -n \"$MATCHED_PKG\" ] &amp;&amp; [ \"$MATCHED_PKG\" != \"$SOURCE_PKG_TRACK\" ] &amp;&amp; info \"Kernel-Treffer unter Fallback: $MATCHED_PKG\"  \n\n        case \"$STATUS\" in  \n            released)\n                ok \"Kernel-Patch verf\u00fcgbar.\"  \n                [ -n \"$DESCR\" ] &amp;&amp; info \"Gefixte Kernel-Version: $DESCR\"  \n                FIXED_VER=\"$DESCR\"  \n                if [ -n \"$INSTALLED_VER\" ] &amp;&amp; [ -n \"$FIXED_VER\" ]; then  \n                    if dpkg --compare-versions \"$INSTALLED_VER\" ge \"$FIXED_VER\"; then  \n                        ok \"Kernel installiert ($INSTALLED_VER) &gt;= Fix ($FIXED_VER) \u2192 GEPATCHT\"  \n                        PATCH_STATUS=\"patched\"  \n                    else\n                        vuln \"Kernel installiert ($INSTALLED_VER) &lt; Fix ($FIXED_VER)\"  \n                        PATCH_STATUS=\"vulnerable\"  \n                    fi\n                fi\n                ;;\n            needed|pending|deferred)\n                info \"Kernel-Patch von Ubuntu: noch nicht ver\u00f6ffentlicht.\"  \n                info \"(Status im Tracker: $STATUS)\"  \n                PATCH_STATUS=\"kernel_pending\"  \n                ;;\n            \"not-affected\"|DNE)  \n                ok \"Kernel-Status: $STATUS \u2014 Release/Paket ist nicht betroffen.\"  \n                PATCH_STATUS=\"not_affected\"  \n                ;;\n            ignored)\n                warn \"Kernel-Status: ignored \u2014 siehe Ubuntu-Tracker.\"  \n                ;;\n            ERROR|not_found|\"\")  \n                info \"Kernel-Patch von Ubuntu: noch nicht ver\u00f6ffentlicht.\"  \n                PATCH_STATUS=\"kernel_pending\"  \n                ;;\n            *)\n                warn \"Unbekannter Status: $STATUS\"  \n                ;;\n        esac\n    else\n        warn \"API-Abruf fehlgeschlagen \u2014 Internetverbindung pr\u00fcfen.\"  \n    fi\nelse\n    warn \"API-Check \u00fcbersprungen (fehlende Daten oder Tools).\"  \nfi\necho\n\n# --- 4. algif_aead Modul-Status ----------------------------------------------\necho \"${B}[4/5] algif_aead Modul${N}\"  \nMOD_LOADED=0\nif lsmod 2&gt;/dev/null | grep -q '^algif_aead'; then  \n    MOD_LOADED=1\nfi\n\nBLACKLISTED=0\nif grep -rqsE '^(blacklist[[:space:]]+algif_aead|install[[:space:]]+algif_aead[[:space:]]+/bin/(false|true))' /etc/modprobe.d/ /usr/lib/modprobe.d/ /run/modprobe.d/ 2&gt;/dev/null; then  \n    BLACKLISTED=1\nfi\n\n# Zusammenfassende Bewertung der beiden Checks\nif [ \"$MOD_LOADED\" -eq 0 ] &amp;&amp; [ \"$BLACKLISTED\" -eq 1 ]; then  \n    ok \"Modul ist nicht geladen und blockiert \u2014 Angriffsweg zu.\"  \nelif [ \"$MOD_LOADED\" -eq 1 ] &amp;&amp; [ \"$BLACKLISTED\" -eq 1 ]; then  \n    warn \"Modul ist GELADEN, obwohl blockiert \u2014 wird beim n\u00e4chsten Reboot entladen.\"  \nelif [ \"$MOD_LOADED\" -eq 0 ] &amp;&amp; [ \"$BLACKLISTED\" -eq 0 ]; then  \n    warn \"Modul ist nicht geladen, aber NICHT blockiert \u2014 kann jederzeit nachgeladen werden!\"  \nelse\n    vuln \"Modul ist GELADEN und nicht blockiert \u2014 System angreifbar!\"  \nfi\necho\n\n# --- 5. Gesamtbewertung -------------------------------------------------------\necho \"${B}[5/5] Gesamtbewertung${N}\"  \necho\n\ncase \"$PATCH_STATUS\" in  \n    patched)\n        if [ \"$REBOOT_PENDING\" -eq 1 ]; then  \n            echo \"  ${B}${Y}\u00bb Status: TEILWEISE GESCH\u00dcTZT \u2014 REBOOT N\u00d6TIG${N}\"  \n            echo\n            echo \"  ${B}Aktion:${N} sudo reboot  (sobald m\u00f6glich)\"  \n            if [ \"$VERBOSE\" -eq 1 ]; then  \n                echo\n                echo \"  Der gepatchte Kernel ist installiert, aber noch nicht aktiv.\"  \n                echo \"  Aktuell l\u00e4uft noch der alte Kernel.\"  \n                if [ \"$BLACKLISTED\" -eq 1 ] &amp;&amp; [ \"$MOD_LOADED\" -eq 0 ]; then  \n                    echo \"  ${G}Bis zum Reboot sch\u00fctzt dich die Modul-Blacklist.${N}\"  \n                else\n                    echo \"  ${R}ACHTUNG: Ohne Modul-Blacklist bist du bis zum Reboot verwundbar!${N}\"  \n                fi\n            fi\n        else\n            echo \"  ${B}${G}\u00bb Status: VOLL GESCH\u00dcTZT (Kernel-Patch aktiv)${N}\"  \n            verbose \"\"  \n            verbose \"  Der gepatchte Kernel l\u00e4uft. Keine weitere Aktion n\u00f6tig.\"  \n        fi\n        ;;\n\n    not_affected)\n        echo \"  ${B}${G}\u00bb Status: NICHT BETROFFEN${N}\"  \n        ;;\n\n    kernel_pending)\n        if [ \"$KMOD_FIX_STATUS\" = \"patched\" ] &amp;&amp; [ \"$BLACKLISTED\" -eq 1 ] &amp;&amp; [ \"$MOD_LOADED\" -eq 0 ]; then  \n            echo \"  ${B}${G}\u00bb Status: GESCH\u00dcTZT (durch Mitigation, JETZT)${N}\"  \n            if [ \"$VERBOSE\" -eq 1 ]; then  \n                echo\n                echo \"  ${B}Bist du jetzt sicher?${N} ${G}Ja, ab sofort.${N}\"  \n                echo \"  Der Angriff braucht das Kernel-Modul 'algif_aead'.\"  \n                echo \"  Dieses Modul ist nicht geladen UND kann nicht geladen werden\"  \n                echo \"  (Ubuntu hat es via kmod-Update USN-8226-1 blockiert).\"  \n                echo \"  \u2192 Der Angriffsweg ist ohne Reboot zu.\"  \n                echo\n                if [ \"$REBOOT_PENDING\" -eq 1 ]; then  \n                    echo \"  ${B}Reboot ausstehend \u2014 was bedeutet das?${N}\"  \n                    echo \"  Der Reboot-Hinweis stammt von einem ANDEREN Update,\"  \n                    echo \"  nicht vom Copy-Fail-Schutz. Du solltest trotzdem\"  \n                    echo \"  bei Gelegenheit neu starten, aber es ist kein Notfall.\"  \n                    echo\n                fi\n                echo \"  ${B}Was steht noch aus?${N}\"  \n                echo \"  Ubuntu wird einen echten Kernel-Patch nachliefern.\"  \n                echo \"  Sobald der da ist, einfach 'apt upgrade' + Reboot.\"  \n                echo \"  Bis dahin reicht die jetzige Mitigation aus.\"  \n                echo\n                echo \"  ${B}Hinweis:${N} 'apt upgrade' bringt aktuell KEINEN Kernel-Fix\"  \n                echo \"  f\u00fcr diese CVE \u2014 Ubuntu hat ihn schlicht noch nicht released.\"  \n                echo \"  Du bist trotzdem voll gesch\u00fctzt.\"  \n            fi\n        elif [ \"$BLACKLISTED\" -eq 1 ] &amp;&amp; [ \"$MOD_LOADED\" -eq 0 ]; then  \n            echo \"  ${B}${Y}\u00bb Status: GESCH\u00dcTZT (manuelle Mitigation)${N}\"  \n            if [ \"$VERBOSE\" -eq 1 ]; then  \n                echo\n                echo \"  Modul-Blacklist greift, aber das offizielle kmod-Update\"  \n                echo \"  scheint nicht installiert zu sein. Empfehlung:\"  \n                echo \"    sudo apt update &amp;&amp; sudo apt upgrade\"  \n            fi\n        else\n            echo \"  ${B}${R}\u00bb Status: VERWUNDBAR \u2014 JETZT HANDELN!${N}\"  \n            echo\n            echo \"  ${B}Sofort ausf\u00fchren:${N}\"  \n            echo \"    sudo apt update &amp;&amp; sudo apt upgrade\"  \n            if [ \"$VERBOSE\" -eq 1 ]; then  \n                echo\n                echo \"  ${B}Falls Update nicht m\u00f6glich, manuelle Notfall-Mitigation:${N}\"  \n                echo \"    echo 'install algif_aead /bin/false' | \\\\\"  \n                echo \"      sudo tee /etc/modprobe.d/disable-algif_aead.conf\"  \n                echo \"    sudo rmmod algif_aead 2&gt;/dev/null || true\"  \n            fi\n        fi\n        ;;\n\n    vulnerable)\n        if [ \"$BLACKLISTED\" -eq 1 ] &amp;&amp; [ \"$MOD_LOADED\" -eq 0 ]; then  \n            echo \"  ${B}${Y}\u00bb Status: GESCH\u00dcTZT (Mitigation), aber Patch fehlt${N}\"  \n            echo\n            echo \"  ${B}Aktion:${N} sudo apt update &amp;&amp; sudo apt upgrade &amp;&amp; sudo reboot\"  \n            verbose \"\"  \n            verbose \"  Modul-Blacklist greift, daher kein akutes Risiko.\"  \n            verbose \"  Trotzdem zeitnah patchen.\"  \n        else\n            echo \"  ${B}${R}\u00bb Status: VERWUNDBAR \u2014 JETZT HANDELN!${N}\"  \n            echo\n            echo \"  ${B}Sofort ausf\u00fchren:${N} sudo apt update &amp;&amp; sudo apt upgrade &amp;&amp; sudo reboot\"  \n        fi\n        ;;\n\n    *)\n        echo \"  ${B}${Y}\u00bb Status: UNKLAR \u2014 bitte manuell pr\u00fcfen${N}\"  \n        echo\n        echo \"  $API_URL\"  \n        ;;\nesac\necho\n[ \"$VERBOSE\" -eq 0 ] &amp;&amp; echo \"  (Mehr Details: $0 --verbose)\"  \necho\nexit 0\n", "creation_timestamp": "2026-05-11T08:18:58.000000Z"}