This post is also available in: English (英語)

概要

本稿は、Visual Studio Code の Node.js デバッグ機能を使って、GootLoader マルウェアが使う分析回避技術について解説します。GootLoader JavaScript ファイルが使う回避技術は、マルウェア分析を試みるサンドボックスにとって、厄介な問題になりがちです。

サンドボックスはコンピューティング リソースが限られているので、バイナリーの数が多すぎると分析がむずかしいことがあります。多くのマルウェアがこの制限につけ込んで、悪質な動作の発動を遅らせることによって分析を回避しています。この手法は一般に「スリープ」と呼ばれています。

GootLoader はバックドア兼ローダー マルウェアで、オペレーターらはこれを偽のフォーラム投稿を通じて活発に配布しています。GootLoader の感染プロセスはある JavaScript ファイルから始まります。

パロアルトネットワークスのお客様は、Advanced WildFire を含むクラウド配信型セキュリティサービスを備えた次世代ファイアウォールCortex XDR により、これらの脅威に対してより強力に保護されています。侵害の懸念があり弊社にインシデントレスポンスに関するご相談をなさりたい場合は、こちらのフォームからご連絡いただくか、infojapan@paloaltonetworks.comまでメールにてご連絡いただくか、下記の電話番号までお問い合わせください(ご相談は弊社製品のお客様には限定されません)。

関連する Unit 42 のトピック GootLoader, Evasion, Memory Detection

背景

2014 年に最初に報告された Gootkit は、時間の経過とともに多くの変化を遂げてきました。2020 年、少なくとも 1 つのソースが Gootkit Loader という JavaScript ベースのマルウェアを特定しました。このマルウェアのオペレーターは、偽のフォーラム投稿を通じてこれを配布していました。このキャンペーンの背後にいるグループは同じ配布戦術を取り続けており、2024 年の現在も見た目がほぼ同じ偽のフォーラム投稿を使っています。

多くのセキュリティ ベンダーは、これらの JavaScript ファイルを指すさい、Gootkit Loader を GootLoader と短縮しています。オリジナルの Gootkit マルウェアは Windows 実行ファイルでしたが、GootLoader は JavaScript ベースのマルウェアで、ランサムウェアを含むほかの種類のマルウェアを配信することができます。

2024 年 1 月以来、私たちはいくつかの GootLoader サンプルを調査してきました。感染チェーンを以下の図 1 に示します。

感染チェーン: 偽のフォーラム ページ > ZIP ダウンロードへのリンク > ダウンロードされた ZIP アーカイブ > 被害者が ZIP に含まれる JS ファイルをダブルクリック > GootLoader インストール、スケジュール タスクを通じて永続化 > GootLoader の Web ベース C2 トラフィック
図 1. 私たちが観察した GootLoader 感染のフローチャート (2024年3月)

「サンドボックス」というのは悪意のあるバイナリーの識別に広く採用されている方法で、コントロールされた環境内でバイナリーの動作を分析します。このサンドボックスによる分析で問題となるのが、限られたコンピューティング リソースで大量のバイナリーを扱う場合です。

多くのマルウェアはこの問題につけ込み、サンドボックス内で悪質な動作の発動を意図的に遅らせることで真意を隠します。こうした遅延の動作は、一般にマルウェアのスリープと言われています。

よく使われる JavaScript マルウェアのスリープ手法

マルウェアをスリープさせるのに一番よく使われるのが、単純に Wscript.sleep() または setTimeout() メソッドを呼び出す方法です。ただし、サンドボックスの多くはこれらのメソッドを容易に検出できます。以降のセクションでは、GootLoader が検出回避に使う、あまり言及されてきたことのない方法の 1 つを分析します。

コードにステップ イン

このセクションでは、Visual Studio Code の Node.js デバッグ機能を利用して Windows ホスト上の次の GootLoader ファイルを分析します。

  • SHA256 ハッシュ: c853d91501111a873a027bd3b9b4dab9dd940e89fcfec51efbb6f0db0ba6687b
  • ファイル サイズ: 860,920 バイト
  • ファイル名: what cards are legal in goat format 35435.js
  • VirusTotal に最初に提出された日: 2024 年 1 月 9 日

GootLoader ファイルのデバッグには、Node.js JavaScript ランタイムVisual Studio Code をインストールした Windows ホストを使います。この環境であれば Visual Studio Code エディターの Node.js デバッグを使ってコードをステップ実行できます。

この環境は、マルウェアのフロー制御や実行ロジックへの理解を深める効果的なアプローチを提供してくます。通常であれば、Windows Script Host (wscript.exe) が Windows 環境でスタンドアロンの JavaScript ファイルを実行しますが、Node.js と Visual Studio Code を使うと、JavaScript ファイルの実行をステップ実行し、コードにブレークポイントを設定し、イミディエイトウィンドウを使って式を評価できます。このアプローチには大きな利点がありますが、特定の JavaScript 関数は Node.js でサポートされていないことがあります。

難読化技術として、GootLoader の作者は正当な JavaScript ライブラリー コードの中に GootLoader コードの行を混ぜ込みます。デバッグ プロセス全体を通じ、私たちは特定ループの範囲内でスタックしているように見えるコード実行を観察しました。以下の図 2 は、そうしたループの 1 つを示したコード スニペットです。

2024 年 3 月 13 日水曜日に発生した Gootloader 感染のプロセス。偽のフォーラム ページから始まり、ZIP ダウンロード リンクに誘導し、JavaScript ファイルを含む ZIP アーカイブをダウンロードし、インストールし、永続的なスケジュール タスク作成へと進み、最終的に Web ベースのコマンド & コントロール (C2) トラフィックが発生する。
図 2. GootLoader のサンプルをコード実行させたところ。Visual Studio Code で Node.js デバッグを使ってファイルを分析するとループ内でスタックしているように見える

これらのループをもっとよく知るため、図 2 のループの周囲のコードを詳しく見てみましょう。以下の図 3 は元のコードから注目したい部分のみを示しています。

これはダーク テーマの IDE でコード スニペットを表示しているコンピューター画面のスクリーンショットです。このコードには、紫、青、オレンジなどさまざまな色で表示された関数や変数が含まれています。
図 3. 図 2 のコードのループ

図 3 を見ると、このコード内の while 関数は無限ループに陥っています。というのも、変数 jobcv には一貫して「1」が割り当てられているからです。さらに、変数 oftenfs はカウンターとして機能していますが、これは 「8242」という値で初期化されています。

このループ内で重要となる行は rangez=(horseq7[oftenfs](oftenfs)); の行です。この行の実行が成功するかどうかは、実際の関数を指している関数の配列 horseq7 に依存しています。このループはカウンター oftenfs2597242 という値に達するまで続きます。ここに達した時点で、関数の配列 horsqe7sleepy という関数を参照します。

このせいでこのコードはループ内でスタックしているように見えていました。なぜなら私たちの分析環境では、このカウンター oftenfs2597242 という値に達するのに 10 分を超える時間がかかっていたからです。

次に、私たちは sleepy 関数にステップインしました。sleepy 関数の内部からは、前にも見た関数の配列名が確認されました (図 4)。この関数の配列 horseq7 には、indicated6 という名前の関数が割り当てられています (図 4)。

この IDE のコードのスクリーンショットには奇妙な変数名を持つ「sleepy」という名前の関数が表示されています。3802 行目には、電球の絵文字つきでコード行 (horseq(5210044); = indicate6;') が強調表示されています。
図 4. sleepy 関数内からは関数の配列 horseq7 が見つかる

さらなる遅延を経て、コードの実行が indicated6 関数内に着地します。今度は lclft4 関数が関数の配列 horseq7 に割り当てられます (図 5)。

これはシンタックスハイライト機能が有効になったテキスト エディター内でコンピューター コードを表示したスクリーンショットです。3 つのパラメーターを持つ「indicate6」という名前の関数と、変数に値を割り当てている数行のコードが強調表示されています。
図 5. indicate6 関数の内部

ふたたび遅延が続いた後、コードの実行は図 6 に示した course83 関数に至ります。この関数 course83 が実際に悪意のあるコードの実行が開始される場所です。

図 6. course83 関数の内部

ここで course83 関数をデバッグすると、ようやく GootLoader の悪意のある機能を開始する JavaScript コードがあらわれ、難読化が解除されます。以下の図 7 は、難読化を解除された悪意のある GootLoader コードの一部を示したものです。

この図はプログラミング言語で書かれた多数のスクリプト行を含むコード エディターの画面です。このコード スニペットには、コンピューター システム内のタスク管理に関連する関数や条件節、変数などが含まれています。画面の背景色は黒で、テキストがわかりやすいように青、黄、白で強調表示されています。
図 7. 悪意のある GootLoader コードのスニペット (難読化解除済み)

GootLoader の開発者は時間のかかる while ループと関数の配列を使うことで悪意のあるコードの発動を意図的に遅らせています。こうしてスリープ期間を設けて GootLoader の悪質性を難読化しておくことで、この手法は効果的に回避技術を実現しています。

カウンターの値とそれらに割り当てられた関数の一覧を、GootLoader JavaScript コードから呼び出された順序で表 1 にまとめました。

カウンターの値 関数名
2597242 sleepy
5210044 indicate6
6001779 lclft4
6690534 course83

表 1. GootLoader サンプルから抽出したカウンターの値とそれに割り当てられた関数

結論

GootLoader の使う回避手法を分析し、そこから得た知見を活用すれば、悪意のあるソフトウェアを検出・分析して効果的対策を開発する能力を高められます。継続的な協力と知識共有を通じ、私たちは団結してサイバー犯罪者に一歩先んじ、デジタル システムとネットワークを守ることができます。

パロアルトネットワークスのお客さまは、以下の製品を通じて、GootLoader とそれに類する脅威からより強力に保護されています。

侵害の懸念があり弊社にインシデントレスポンスに関するご相談をなさりたい場合は、こちらのフォームからご連絡いただくか、infojapan@paloaltonetworks.com までメールにてご連絡いただくか、下記の電話番号までお問い合わせください (ご相談は弊社製品のお客さまには限定されません)。

  • 北米フリーダイヤル: 866.486.4842 (866.4.UNIT42)
  • EMEA: +31.20.299.3130
  • APAC: +65.6983.8730
  • 日本: (+81) 50-1790-0200

パロアルトネットワークスは、これらの調査結果を Cyber Threat Alliance (CTA: サイバー脅威アライアンス) のメンバーと共有しました。CTA のメンバーはこのインテリジェンスを使って、お客さまに保護を迅速に提供し、悪意のあるサイバー攻撃者を体系的に阻害できます。詳細は Cyber Threat Alliance にてご確認ください。

IoC (侵害指標)

GootLoader JavaScript ファイルの SHA256 ハッシュ

  • b939ec9447140804710f0ce2a7d33ec89f758ff8e7caab6ee38fe2446e3ac988
  • c853d91501111a873a027bd3b9b4dab9dd940e89fcfec51efbb6f0db0ba6687b
Enlarged Image