Node Package Managerのインデックスにある悪意のあるパッケージは、目に見えないUnicode文字を使って悪意のあるコードを隠し、Google Calendarのリンクを使ってコマンド・アンド・コントロールの場所のURLをホストしている。
os-info-checker-es6と名付けられたこのパッケージは、情報ユーティリティとして表示され、今月初めから1,000回以上ダウンロードされています。
コード・セキュリティ評価会社であるVeracodeの研究者は、このパッケージの最初のバージョンが3月19日にNode Package Manager(NPM)インデックスに追加され、ホストからオペレーティング・システム情報を収集するだけの良性のものであることを発見した。
作者は数日後、プラットフォーム固有のバイナリと難読化されたインストール・スクリプトを含むように修正を加えた。
5月7日には、このパッケージの新バージョンが公開され、最終的なペイロードを配信する「洗練されたC2(コマンド・アンド・コントロール)メカニズム」のコードが含まれていた。
本稿執筆時点でnpmで利用可能な「os-info-checker-es6」の最新バージョンはv1.0.8で、悪意のあるものだとVeracodeは警告している。
さらにこのパッケージは、skip-tot、vue-dev-serverr、vue-dummyy、‘vue-bit’の4つの他のNPMパッケージの依存関係としてリストされており、これらはすべてアクセシビリティと開発者プラットフォームのエンジニアリングツールを装っている。
これらのパッケージが脅威行為者によってどのように宣伝されているかは不明です。
Unicodeステガノグラフィ
悪意のあるバージョンでは、攻撃者は’|’文字列のように見えるものにデータを埋め込んでいます。しかし、縦棒の後には、バリエーション・セレクタ補足範囲(U+E0100からU+E01EF)の目に見えないUnicode文字が長く続いています。
こ れ ら の Unicode キ ャ ラ ク タ は通常修飾子であ り 、 通常は 「複雑な用字系で特定のグ リ フ バ リ エーシ ョ ン を提供す る ために」 用い ら れます。こ の場合、 こ のキ ャ ラ ク タ の役割は、 テ キ ス ト ベース の ス テ ガ ノ グ ラ フ ィ (他のデー タ の中に情報を隠す) を容易にす る こ と です。
Veracodeは文字列を解読し、難読化を解除して、最終的なペイロードをホストする場所に到達するためにGoogleカレンダーのショートリンクに依存する洗練されたC2メカニズム用のペイロードを発見した。
研究者は、グーグルカレンダーのリンクを取得した後、リクエストに対するHTTP 200 OKレスポンスを受信するまで、一連のリダイレクトがチェックされると説明している。
そして、イベントのHTMLページからdata-base-title属性をスクレイピングし、最終的なペイロードを指すbase64エンコードされたURLを保持する。
ymogvjと呼ばれる関数を使用して、URLはマルウェアのペイロードを取得するためにデコードされる。研究者によると、このリクエストは、レスポンス・ボディにbaseエンコードされたstage-2のマルウェアのペイロードを期待し、HTTPヘッダに初期化ベクターとシークレット・キー(最終的なペイロードの暗号化の可能性を示すもの)が含まれている可能性が高いという。
Veracodeはまた、ペイロードがeval()を使用して実行されることも発見しました。このスクリプトには、システムの一時ディレクトリに簡単な永続化メカニズムが含まれており、複数のインスタンスが同時に実行されるのを防いでいる。
分析時点では、研究者は最終的なペイロードを取得できなかったため、このキャンペーンは保留中であるか、まだ初期段階である可能性が示唆された。
Veracodeが発見をNPMに報告したにもかかわらず、不審なパッケージはまだプラットフォーム上に存在している。
.ia_ad { background-color:#width: 95%; max-width: 800px; margin: 15px auto; border-radius: 8px; border:1px solid #d6ddee; display: flex; align-items: stretch; padding: 0; overflow: hidden; }:0; overflow: hidden; } .ia_lef { flex: 1; max-width: 200px; height: auto; display: flex; align-items: stretch; } .ia_lef a { display: flex; width: 100%; height: 100%; } .ia_lef a img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px 0 0 8px; margin: 0; display: block; } .ia_rig { flex: 2; padding:display: flex; flex-direction: column; justify-content: center; } .ia_rig h2 { font-size: 17px !important; font-weight: 700; color:#line-height: 1.4; font-family:margin: 0 0 14px 0; } .ia_rig p { font-weight: bold; font-size: 14px; margin: 0 0 clamp(6px, 2vw, 14px) 0; } .ia_button { background-color:#border:1px solid #3b59aa; color: black; text-align: center; text-decoration: none; border-radius: 8px; display: inline-block; font-size: 16px; font-weight: bold; cursor: pointer; padding:10px 20px; width: fit-content; } .ia_button a { text-decoration: none; color: inherit; display: block; } @media (max-width: 600px) { .ia_ad { flex-direction: column; align-items: center; text-align: center; } .ia_lef { max-width: 100%; } .ia_lef a img { border-radius: 8px 8px 0 0; } .ia_rig { padding:15px; width: 100%; } .ia_button { width: 100%; } .
Comments