## https://sploitus.com/exploit?id=E476ED22-8DC0-58CC-A1BC-415DA7A57BBE
# CVE-2026-31431 / GHSA-2274-3hgr-wxv6 โ algif_aead Remediator
**Severity:** High (CVSS 7.8 โ `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`)
## Background
[CVE-2026-31431](https://github.com/advisories/GHSA-2274-3hgr-wxv6) is a local privilege escalation vulnerability in the Linux kernel's `algif_aead` module (AF_ALG AEAD crypto socket interface). A low-privileged local user can exploit incorrect in-place buffer operations to gain full root access. All AKS node pools running Linux kernels prior to the upstream patch are potentially affected.
The `algif_aead` module is not required for normal Kubernetes or AKS workloads. Blacklisting it eliminates the attack surface entirely.
---
## What this DaemonSet does
One pod runs on every Linux node. On start-up and then every 60 seconds each pod:
1. **Writes** `/etc/modprobe.d/modprobe-CIS.conf` on the host with:
```
install algif_aead /bin/false
blacklist algif_aead
```
This prevents the module from loading on reboot or via `modprobe`.
2. **Checks** `/proc/modules` (the live host kernel module list โ shared with all containers) for `algif_aead`.
3. **Labels** the Kubernetes node with the result so you can query across the cluster:
| Label value | Meaning |
|---|---|
| `mitigated` | Module not loaded; blacklist config applied |
| `module-loaded` | Module is currently loaded โ investigate immediately |
---
## Files
| File | Purpose |
|---|---|
| `rbac.yaml` | Namespace, ServiceAccount, ClusterRole (`get`/`patch` nodes), ClusterRoleBinding |
| `configmap.yaml` | Shell remediation script mounted into every pod |
| `daemonset.yaml` | DaemonSet definition โ one pod per Linux node |
---
## Prerequisites
- `kubectl` configured against the target AKS cluster
- Cluster-admin permissions (required to create a ClusterRole and a privileged namespace)
---
## Deploy
Apply the manifests in order:
```sh
kubectl apply -f rbac.yaml
kubectl apply -f configmap.yaml
kubectl apply -f daemonset.yaml
```
Wait for the rollout to complete on all nodes:
```sh
kubectl -n security-remediation rollout status daemonset/cve-2026-31431-remediator
```
---
## Verify
### Check node remediation status at a glance
```sh
kubectl get nodes -L vulnerability.aks.io/CVE-2026-31431
```
Expected output on a clean cluster:
```
NAME STATUS ROLES AGE VERSION CVE-2026-31431
aks-nodepool1-xxxxx-vmss000000 Ready 4d v1.33.7 mitigated
aks-nodepool1-xxxxx-vmss000001 Ready 4d v1.33.7 mitigated
```
### Check logs on a specific pod
```sh
# List pods and their assigned nodes
kubectl -n security-remediation get pods -o wide
# Tail a specific pod's logs
kubectl -n security-remediation logs -f
```
Expected log output:
```
2026-05-01T01:33:36Z [INFO ] CVE-2026-31431 remediator starting on node: aks-nodepool1-...
2026-05-01T01:33:36Z [INFO ] Blacklist config written โ /host/etc/modprobe.d/modprobe-CIS.conf
2026-05-01T01:33:36Z [INFO ] Node aks-nodepool1-...: 'algif_aead' is NOT loaded โ blacklist config applied, node is mitigated.
2026-05-01T01:33:36Z [INFO ] Labeled node aks-nodepool1-...: vulnerability.aks.io/CVE-2026-31431=mitigated
2026-05-01T01:33:36Z [INFO ] Entering monitoring loop (interval: 60s)
```
### Verify the modprobe config was written to the host
```sh
kubectl -n security-remediation exec -- cat /host/etc/modprobe.d/modprobe-CIS.conf
```
Expected content:
```
# CIS hardening โ mitigate CVE-2026-31431 (GHSA-2274-3hgr-wxv6)
# Prevents algif_aead (AF_ALG AEAD) LPE from being loaded or exploited.
install algif_aead /bin/false
blacklist algif_aead
```
### Alert: module-loaded nodes
If a node shows `module-loaded`, the kernel module is currently active and the node may already be compromised. Cordon and drain the node immediately for forensic analysis:
```sh
# Find affected nodes
kubectl get nodes -l vulnerability.aks.io/CVE-2026-31431=module-loaded
# Cordon and drain for investigation
kubectl cordon
kubectl drain --ignore-daemonsets --delete-emptydir-data
```
---
## Uninstall
> **Note:** Removing the DaemonSet does **not** remove the `/etc/modprobe.d/modprobe-CIS.conf` file from host nodes. That file is intentionally left in place as a persistent kernel hardening measure.
### Remove Kubernetes resources
```sh
kubectl delete -f daemonset.yaml
kubectl delete -f configmap.yaml
kubectl delete -f rbac.yaml
```
This deletes the DaemonSet, all its pods, the ConfigMap, the ServiceAccount, the ClusterRole, the ClusterRoleBinding, and the namespace.
### Remove node labels (optional)
```sh
kubectl label nodes --all vulnerability.aks.io/CVE-2026-31431-
```
### Remove the modprobe config from nodes (not recommended)
Only do this if you have an alternative mitigation (patched kernel). Run on each node or via a privileged pod:
```sh
rm -f /etc/modprobe.d/modprobe-CIS.conf
```
---
## Security notes
- The pod runs as **root** (`runAsUser: 0`) โ required to write to `/etc/modprobe.d/` on the host.
- All Linux capabilities are **dropped** (`capabilities.drop: ["ALL"]`). No kernel capabilities are needed.
- The main container runs with **`readOnlyRootFilesystem: true`**. Only the mounted `hostPath` and `emptyDir` volumes are writable.
- Only `/etc/modprobe.d/` is bind-mounted from the host โ not `/etc`, `/proc`, or any broader path.
- The `curl` binary and its shared libraries are staged by the init container into an `emptyDir` (`/tools`) so the main container can call the Kubernetes API without needing write access to rootfs.
- The service account has the minimum RBAC permissions needed: `get` and `patch` on `nodes` only.