⚠️ Avertissement : Cet article a été rédigé avec l’assistance d’une IA Les informations techniques sont issues de sources publiques vérifiées (mailing list Arch, BleepingComputer, lenucksi/aur-malware-check). Il est conseillé de croiser avec les sources originales avant toute action sur votre système.
Attaque AUR juin 2026 — 1 579 paquets compromis
Date de l’incident : 9–12 juin 2026
Paquets touchés : 1 579 (liste communautaire, non exhaustive)
Dépôts officiels Arch ([core],[extra],[multilib]) : non affectés
Résumé
Entre le 9 et le 12 juin 2026, l’Arch User Repository (AUR) a été la cible d’une attaque en chaîne d’approvisionnement de grande ampleur. Des acteurs malveillants ont pris le contrôle de centaines de paquets orphelins en usurpant l’identité de mainteneurs légitimes via de la forgerie de commits Git, puis ont injecté du code malveillant dans les PKGBUILD et fichiers .install.
Deux vagues d’attaque
Vague 1 — atomic-lockfile (npm)
L’attaquant a ajouté un appel npm install atomic-lockfile dans les scripts post-installation. Le paquet npm atomic-lockfile@1.4.2 contenait un hook preinstall exécutant un binaire ELF compilé en Rust — un infostealer.
Vague 2 — js-digest (bun)
Une deuxième vague, via les comptes custodiatovar et veramagalhaes, a utilisé bun install js-digest pour livrer une charge utile différente mais similaire.
Capacités du malware
- Vol de credentials : tokens Discord, GitHub PAT, clés SSH, tokens npm/Slack/Teams, cookies navigateur, secrets Vault, credentials Docker
- Exfiltration : upload vers
temp.sh, communication C2 via service Tor onion - Persistance : services systemd (
Restart=always) en mode utilisateur ou root - Rootkit eBPF : si lancé avec
CAP_BPF, masque les processus, fichiers et inodes réseau — invisible pourps,htop,ls
Réponse de l’équipe Arch
L’équipe Arch a réagi rapidement : révocation des commits malveillants, bannissement des comptes attaquants, publication d’une liste de paquets affectés. Le mainteneur légitime arojas a été innocenté — son identité avait été usurpée par forgerie de commit.
Vérifier sa machine
Le script ci-dessous télécharge la liste de référence communautaire
(lenucksi/aur-malware-check),
la croise avec vos paquets AUR installés via pacman -Qm, et affiche
un tableau coloré dans le terminal avec le statut de chaque paquet.
Utilisation
chmod +x aur_report.sh
./aur_report.sh
Codes de sortie : 0 = propre · 2 = paquet(s) infecté(s) détecté(s)
La liste est mise en cache 1 heure dans ~/.cache/aur-malware-check/.
Script
#!/usr/bin/env bash
# =============================================================================
# aur_report.sh — Liste des paquets AUR installés avec statut malware juin 2026
# Attaque atomic-lockfile / js-digest — github.com/lenucksi/aur-malware-check
# =============================================================================
LIST_URL="https://raw.githubusercontent.com/lenucksi/aur-malware-check/master/package_list.txt"
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/aur-malware-check"
LIST_CACHE="$CACHE_DIR/package_list.txt"
# --- Couleurs ----------------------------------------------------------------
RED='\033[1;31m'; GRN='\033[1;32m'; YEL='\033[1;33m'
WHT='\033[1;37m'; DIM='\033[2m'; RST='\033[0m'
# --- Téléchargement liste infectée -------------------------------------------
mkdir -p "$CACHE_DIR"
now=$(date +%s)
mtime=0
[[ -f "$LIST_CACHE" ]] && mtime=$(stat -c %Y "$LIST_CACHE" 2>/dev/null || echo 0)
age=$(( now - mtime ))
if [[ $age -gt 3600 || ! -f "$LIST_CACHE" ]]; then
echo -e "${DIM}[*] Téléchargement de la liste de référence...${RST}"
if curl -fsSL --max-time 15 "$LIST_URL" -o "$LIST_CACHE.tmp"; then
mv "$LIST_CACHE.tmp" "$LIST_CACHE"
else
[[ -f "$LIST_CACHE" ]] || { echo -e "${RED}[✗] Téléchargement échoué, pas de cache.${RST}"; exit 1; }
echo -e "${YEL}[!] Téléchargement échoué — cache local utilisé.${RST}"
fi
fi
# Charger liste infectée dans un tableau associatif (lookup O(1))
declare -A infected_map
while IFS= read -r line; do
[[ -z "$line" || "$line" == \#* ]] && continue
infected_map["$line"]=1
done < "$LIST_CACHE"
total_ref=${#infected_map[@]}
# --- Paquets AUR installés ---------------------------------------------------
mapfile -t aur_pkgs < <(pacman -Qm 2>/dev/null | sort -k1,1)
total_aur=${#aur_pkgs[@]}
if [[ $total_aur -eq 0 ]]; then
echo -e "${YEL}[!] Aucun paquet AUR (foreign) détecté.${RST}"
exit 0
fi
# --- Calcul largeurs colonnes ------------------------------------------------
max_pkg=6 # "Paquet"
max_ver=7 # "Version"
for entry in "${aur_pkgs[@]}"; do
pkg="${entry%% *}"; ver="${entry##* }"
(( ${#pkg} > max_pkg )) && max_pkg=${#pkg}
(( ${#ver} > max_ver )) && max_ver=${#ver}
done
# --- Fonction d'affichage ligne ----------------------------------------------
print_row() {
local pkg="$1" ver="$2" infected="$3"
local pad_pkg pad_ver
pad_pkg=$(( max_pkg - ${#pkg} ))
pad_ver=$(( max_ver - ${#ver} ))
local spaces_pkg; spaces_pkg=$(printf '%*s' "$pad_pkg" '')
local spaces_ver; spaces_ver=$(printf '%*s' "$pad_ver" '')
if [[ "$infected" == "1" ]]; then
echo -e " ${DIM}│${RST} ${RED}${pkg}${RST}${spaces_pkg} ${DIM}│${RST} ${RED}${ver}${RST}${spaces_ver} ${DIM}│${RST} ${RED}⚠ INFECTÉ ${RST} ${DIM}│${RST}"
else
echo -e " ${DIM}│${RST} ${pkg}${spaces_pkg} ${DIM}│${RST} ${DIM}${ver}${RST}${spaces_ver} ${DIM}│${RST} ${GRN}✓ Propre ${RST} ${DIM}│${RST}"
fi
}
sep_pkg=$(printf '─%.0s' $(seq 1 $(( max_pkg + 2 ))))
sep_ver=$(printf '─%.0s' $(seq 1 $(( max_ver + 2 ))))
sep_sta=$(printf '─%.0s' $(seq 1 18))
# --- En-tête -----------------------------------------------------------------
echo
echo -e " ${WHT}AUR Malware Check — Attaque juin 2026 (atomic-lockfile / js-digest)${RST}"
echo -e " ${DIM}Référence : $total_ref paquets infectés | Machine : $(hostname) | $(date '+%Y-%m-%d %H:%M')${RST}"
echo
echo -e " ${DIM}┌${sep_pkg}┬${sep_ver}┬${sep_sta}┐${RST}"
pad_pkg=$(( max_pkg - 6 )); spaces_pkg=$(printf '%*s' "$pad_pkg" '')
pad_ver=$(( max_ver - 7 )); spaces_ver=$(printf '%*s' "$pad_ver" '')
echo -e " ${DIM}│${RST} ${WHT}Paquet${RST}${spaces_pkg} ${DIM}│${RST} ${WHT}Version${RST}${spaces_ver} ${DIM}│${RST} ${WHT}Statut ${RST} ${DIM}│${RST}"
echo -e " ${DIM}├${sep_pkg}┼${sep_ver}┼${sep_sta}┤${RST}"
# --- Lignes ------------------------------------------------------------------
infected_count=0
clean_count=0
infected_list=()
for entry in "${aur_pkgs[@]}"; do
pkg="${entry%% *}"
ver="${entry##* }"
if [[ -n "${infected_map[$pkg]+_}" ]]; then
print_row "$pkg" "$ver" "1"
infected_list+=("$pkg")
(( infected_count++ )) || true
else
print_row "$pkg" "$ver" "0"
(( clean_count++ )) || true
fi
done
echo -e " ${DIM}└${sep_pkg}┴${sep_ver}┴${sep_sta}┘${RST}"
# --- Résumé ------------------------------------------------------------------
echo
echo -e " ${WHT}Résumé${RST} ${DIM}│${RST} Total AUR : ${WHT}${total_aur}${RST} ${DIM}│${RST} Propres : ${GRN}${clean_count}${RST} ${DIM}│${RST} Infectés : $(
[[ $infected_count -gt 0 ]] && echo -e "${RED}${infected_count}${RST}" || echo -e "${GRN}${infected_count}${RST}"
)"
echo
if [[ $infected_count -gt 0 ]]; then
echo -e " ${RED}┌──────────────────────────────────────────────────────────────┐${RST}"
echo -e " ${RED}│ ⚠ ALERTE — ${infected_count} paquet(s) infecté(s) détecté(s) !$(printf '%-*s' $(( 33 - ${#infected_count} )) '')│${RST}"
echo -e " ${RED}└──────────────────────────────────────────────────────────────┘${RST}"
echo
echo -e " ${YEL}Supprimer immédiatement :${RST}"
echo -e " ${WHT}sudo pacman -Rns ${infected_list[*]}${RST}"
echo
echo -e " ${YEL}Puis changer tous vos tokens GitHub, Discord, SSH, npm, Slack...${RST}"
echo -e " ${DIM} → https://github.com/lenucksi/aur-malware-check${RST}"
echo
exit 2
else
echo -e " ${GRN}✓ Aucun paquet infecté détecté parmi vos ${total_aur} paquets AUR.${RST}"
echo
exit 0
fi
Que faire si vous êtes infecté ?
- Ne pas éteindre la machine — le rootkit eBPF disparaît au reboot, mais cela détruit les artefacts forensiques.
- Révoquer immédiatement tous vos secrets : clés SSH, tokens GitHub/GitLab, tokens npm, sessions Discord/Slack, credentials Docker/Podman, secrets Vault/cloud.
- Supprimer les paquets infectés :
sudo pacman -Rns <paquet> - Vérifier la persistance systemd :
systemctl --user list-units --type=service - Chercher les artefacts eBPF :
ls /sys/fs/bpf/hidden_* - Envisager une réinstallation : un rootkit rend le système fondamentalement non fiable.