Accueil / Cybersécurité / Téléphonie / Les utilisateurs Mac visés par une variante du malware Xagent

Les utilisateurs Mac visés par une variante du malware Xagent

Le malware Xagent s’attaque désormais aux utilisateurs Mac pour détourner des mots de passe et des sauvegardes iPhone.

Les pirates responsables de la menace APT28 ont renforcé leur arsenal – la charge utile du malware Xagent peut maintenant cibler des utilisateurs sous macOS dans le but de voler des mots de passe, faire des captures d’écran mais également voler des sauvegardes iPhone stockées sur le Mac. L’année dernière, nous avions publié une étude complète sur ce qui s’est révélé être l’une des plus grandes campagnes de cyber-espionnage, liée à la Russie.

L’échantillon auquel nous nous intéressons aujourd’hui, Bitdefender a pu mettre la main sur ce dernier lors d’un audit client, est lié à la version Mac du composant Xagent de Sofacy / APT28 / Sednit APT. Cette porte dérobée modulaire avec des capacités avancées de cyber-espionnage est probablement installée sur le système via le downloader Komplex.

Une fois installée avec succès, la porte dérobée vérifie si un débogueur est attaché au processus. S’il en détecte un, il s’arrête lui-même pour empêcher l’exécution. Sinon, il attend qu’une connexion Internet soit établie avant de lancer la communication avec les serveurs C&C. Une fois la communication établie, la charge utile démarre les modules.

L’analyse préliminaire montre que la plupart des URL des serveurs C&C prennent l’apparence de noms de domaines Apple. Une fois connecté au C&C, la charge utile envoie un “HelloMessage“, puis génère deux fils de communication s’exécutant en boucles infinies. Le premier utilise des requêtes POST pour envoyer des informations au C&C, tandis que le deuxième surveille les requêtes GET pour des commandes.

Où ces modules d’espionnage macOS s’installent-ils ?

L’analyse révèle la présence de modules capables de sonder les configurations matérielles et logicielles du système, d’obtenir la liste des processus en cours d’exécution, d’exécuter des fichiers supplémentaires, d’obtenir des captures d’écran et de récolter les mots de passe du navigateur. Mais le module le plus important, du point de vue de la collecte d’informations, est celui qui permet aux pirates d’exfiltrer les sauvegardes d’un l’iPhone stockées sur un Mac corrompu.
Tous ces modules sont en attente d’analyse (un document détaillé documentant toutes les fonctionnalités des modules sera disponible sous peu.)

Notre précédente analyse d’échantillons connus pour être liés au groupe APT28 montre un certain nombre de similitudes entre le composant Sofacy / APT28 / Sednit Xagent pour Windows / Linux, et le binaire macOS actuellement étudié par nos équipes. Pour une fois, la présence de modules similaires a été détectée, tels que FileSystem, KeyLogger et RemoteShell, ainsi qu’un module de réseau semblable appelé HttpChanel. D’autres indicateurs montrent que l’échantillon d’aujourd’hui utilise également une adresse URL d’un serveur C&C identique au cheval de Troie OSX Komplex de Sofacy / APT28 / Sednit, moins le TLD (apple – [*******] .net pour Komplex vs apple – [* ******]. Org pour Xagent).

L’expertise forensique du binaire révèle aussi des chaînes binaires identiques dans les clients Komplex et Xagent, comme : Chaîne binaire Komplex: « / Users / kazak / Desktop / Project / komplex » ; Chaîne binaire Xagent Mac: « / Users / kazak / Desktop / Project / XAgentOSX ».

Les équipes Bitdefender concluent donc cette première étape des analyses en supposant que c’est le composant Komplex découvert en septembre dernier qui a été utilisé afin de diffuser le malware Xagent sur macOS. L’enquête est en cours. Une étude complète sera bientôt mise à disposition par l’éditeur de solution de sécurité informatique. De manière générale, les utilisateurs Mac soucieux d’éviter les malwares tels que Xagent devraient toujours éviter les App store alternatifs, et ne se fier qu’au Store officiel et aux développeurs disposant d’une bonne renommée.

*Analyse fournie par Tiberius Axinte, Responsable Technique chez BitdefenderLabs

Étiquetté :

Nos partenaires




Actualités du mois

avril 2026
L M M J V S D
 12345
6789101112
13141516171819
20212223242526
27282930  

Articles en UNE

Actus zataz



Réseaux sociaux


Liste des sujets


<!-- Cyber'Émission ZATAZ — badge volant (déplaçable) + réduire/fermer -->
<div class="zataz-yt-float" id="zatazYtFloat" role="region" aria-label="Cyber'Émission ZATAZ">
  <div class="zataz-yt-float__bar" id="zatazYtBar">
    <span class="zataz-yt-float__title">Cyber'Émission ZATAZ</span>

    <div class="zataz-yt-float__actions">
      <button type="button" class="zataz-yt-float__btn" id="zatazYtMin" aria-label="Réduire">—</button>
      <button type="button" class="zataz-yt-float__btn zataz-yt-float__btn--close" id="zatazYtClose" aria-label="Fermer">×</button>
    </div>
  </div>

  <a class="zataz-yt-badge" href="https://www.youtube.com/@ZATAZCOM" target="_blank" rel="noopener noreferrer"
     aria-label="Regarder Cyber'Émission ZATAZ sur YouTube (nouvel onglet)">
    <span class="zataz-yt-badge__thumb" aria-hidden="true">
      <span class="zataz-yt-badge__play" aria-hidden="true"></span>
    </span>
  </a>
</div>

<style>
  .zataz-yt-float{
    position:fixed;
    right:18px;
    bottom:18px;
    z-index:99999;
    width:320px;
    max-width:calc(100vw - 36px);
    border-radius:14px;
    overflow:hidden;
    background:linear-gradient(135deg,#111827,#0b1220 55%,#111827);
    border:1px solid rgba(255,255,255,.12);
    box-shadow:0 14px 40px rgba(0,0,0,.35);
    transform:translateZ(0);
    user-select:none;
    touch-action:none; /* drag mobile */
  }

  /* Barre de drag + boutons */
  .zataz-yt-float__bar{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    padding:10px 10px 10px 12px;
    font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;
    color:#fff;
    background:rgba(0,0,0,.18);
    border-bottom:1px solid rgba(255,255,255,.10);
    cursor:grab;
  }
  .zataz-yt-float__bar:active{ cursor:grabbing; }
  .zataz-yt-float__title{
    font-weight:800;
    letter-spacing:.2px;
    font-size:15px;
    line-height:1;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
  }
  .zataz-yt-float__actions{ display:flex; gap:8px; }
  .zataz-yt-float__btn{
    appearance:none;
    border:1px solid rgba(255,255,255,.18);
    background:rgba(0,0,0,.28);
    color:#fff;
    width:32px;
    height:28px;
    border-radius:10px;
    font-weight:900;
    line-height:1;
    cursor:pointer;
    display:grid;
    place-items:center;
  }
  .zataz-yt-float__btn:hover{ background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.28); }
  .zataz-yt-float__btn--close:hover{ background:rgba(239,68,68,.22); border-color:rgba(239,68,68,.45); }

  /* Contenu (votre vignette) */
  .zataz-yt-badge{
    display:block;
    text-decoration:none;
    color:#fff;
  }
  .zataz-yt-badge__thumb{
    display:block;
    height:180px;
    background:#0f172a url("https://i.ytimg.com/vi/HUo8dnD6Swk/hqdefault.jpg") center/cover no-repeat;
    position:relative;
  }
  .zataz-yt-badge__play{
    position:absolute;
    left:50%;
    top:50%;
    width:54px;
    height:54px;
    margin:-27px 0 0 -27px;
    border-radius:999px;
    background:rgba(0,0,0,.55);
    border:1px solid rgba(255,255,255,.25);
    box-shadow:0 10px 22px rgba(0,0,0,.35);
  }
  .zataz-yt-badge__play:before{
    content:"";
    position:absolute;
    left:22px;
    top:16px;
    width:0;height:0;
    border-top:11px solid transparent;
    border-bottom:11px solid transparent;
    border-left:16px solid #fff;
  }

  .zataz-yt-float:hover{
    box-shadow:0 18px 55px rgba(0,0,0,.45);
    border-color:rgba(255,255,255,.18);
  }
  .zataz-yt-badge:active{ transform:scale(.99); }

  /* Etat réduit */
  .zataz-yt-float.is-min .zataz-yt-badge{ display:none; }
  .zataz-yt-float.is-min{ width:260px; }

  /* Mobile : plus compact */
  @media (max-width:480px){
    .zataz-yt-float{ width:280px; right:12px; bottom:12px; }
    .zataz-yt-badge__thumb{ height:158px; }
    .zataz-yt-float.is-min{ width:220px; }
  }
</style>

<script>
(() => {
  const box = document.getElementById('zatazYtFloat');
  const bar = document.getElementById('zatazYtBar');
  const btnMin = document.getElementById('zatazYtMin');
  const btnClose = document.getElementById('zatazYtClose');

  if (!box || !bar || !btnMin || !btnClose) return;

  // Réduire / restaurer
  btnMin.addEventListener('click', (e) => {
    e.stopPropagation();
    box.classList.toggle('is-min');
    btnMin.textContent = box.classList.contains('is-min') ? '▢' : '—';
    btnMin.setAttribute('aria-label', box.classList.contains('is-min') ? 'Restaurer' : 'Réduire');
  });

  // Fermer
  btnClose.addEventListener('click', (e) => {
    e.stopPropagation();
    box.remove();
  });

  // Drag (souris + tactile) via Pointer Events
  let dragging = false;
  let startX = 0, startY = 0;
  let startLeft = 0, startTop = 0;

  // Position initiale: on convertit right/bottom en left/top pour le drag
  const init = () => {
    const r = box.getBoundingClientRect();
    box.style.left = r.left + 'px';
    box.style.top  = r.top  + 'px';
    box.style.right = 'auto';
    box.style.bottom = 'auto';
  };
  init();

  const clamp = (v, min, max) => Math.min(Math.max(v, min), max);

  bar.addEventListener('pointerdown', (e) => {
    // pas de drag quand on clique sur les boutons
    if (e.target === btnMin || e.target === btnClose) return;

    dragging = true;
    bar.setPointerCapture(e.pointerId);

    const r = box.getBoundingClientRect();
    startX = e.clientX;
    startY = e.clientY;
    startLeft = r.left;
    startTop = r.top;

    e.preventDefault();
  });

  bar.addEventListener('pointermove', (e) => {
    if (!dragging) return;

    const dx = e.clientX - startX;
    const dy = e.clientY - startY;

    const r = box.getBoundingClientRect();
    const w = r.width;
    const h = r.height;

    const maxLeft = window.innerWidth - w - 8;
    const maxTop  = window.innerHeight - h - 8;

    box.style.left = clamp(startLeft + dx, 8, maxLeft) + 'px';
    box.style.top  = clamp(startTop + dy, 8, maxTop) + 'px';
  });

  const endDrag = () => { dragging = false; };
  bar.addEventListener('pointerup', endDrag);
  bar.addEventListener('pointercancel', endDrag);

  // Re-clamp au resize
  window.addEventListener('resize', () => {
    const r = box.getBoundingClientRect();
    const maxLeft = window.innerWidth - r.width - 8;
    const maxTop  = window.innerHeight - r.height - 8;
    box.style.left = clamp(r.left, 8, maxLeft) + 'px';
    box.style.top  = clamp(r.top, 8, maxTop) + 'px';
  });
})();
</script>