2025年12月31日早朝に検知された攻撃ログ。前回の単純な破壊工作とは異なり、システムの内部情報(カレントディレクトリ等)を奪取し、それをクエリパラメータとして外部へ持ち出そうとする「偵察型RCE」の典型例だったのでメモをしておきます。
検知ログの概要(匿名化済み)
[Wed Dec 31 05:25:08 2025] [security2:error]
[ModSecurity: Warning] [ID "934100"] [Severity: CRITICAL]
[Message: Node.js Injection Attack 1/2]
[Matched Data: process.mainModule.require('child_process').execSync('pwd')]
攻撃ペイロードの構造解析
今回の攻撃者は、Next.jsのサーバーアクションや特定のSSR(サーバサイドレンダリング)の脆弱性を想定した、非常にテクニカルなコードを注入しています。
JavaScript実行環境への介入
var res = process.mainModule.require('child_process').execSync('pwd').toString().trim();
process.mainModuleを経由して、サンドボックス化されている可能性のある環境からchild_process(OS操作モジュール)を強制的に呼び出しています。execSync('pwd')を実行することで、「現在、サーバのどのディレクトリでプログラムが動いているか」という、次なる攻撃(設定ファイルの奪取など)のための足がかりとなる情報を取得しようとしています。
Next.jsの内部挙動を悪用した情報の持ち出し
throw Object.assign(new Error('NEXT_REDIRECT'), {
digest: `NEXT_REDIRECT;push;/login?a=${res};307;`
});
ここが非常に巧妙だと思った点。Next.jsがリダイレクトを処理する際の内部エラー NEXT_REDIRECT を意図的に投げ(throw)、そのエラーオブジェクトの中に、先ほど取得したディレクトリ情報(${res})を埋め込んでいます。
- これにより、攻撃者のブラウザ(あるいはボット)は、
/login?a=/home/www-data/...というURLに強制的に飛ばされます。 - 攻撃者は自分のサーバのアクセスログを見るだけで、ターゲットサーバの内部パスを手に入れることができる仕組みです。
防御側の対応と結果
- 検知: ModSecurity CRSの
934100(Node.js Injection)が、child_processやexecSyncといった危険な関数呼び出しを完全にパターンマッチング。 - 阻止: 前回同様、アプリケーション層に到達する前に403遮断(設定により404応答)。
- 分析: 攻撃者はRedmine(Ruby on Rails)に対し、あえてNode.js/Next.js用の高度なペイロードを投げています。これは「何で動いているか分からないが、とりあえず流行りの脆弱性コードを全部試す」という、 スキャンから自動攻撃までシームレスに移行するボット*の挙動です。
技術的考察:2025年を締めくくった「贈り物」
このログが示しているのは、攻撃側がいかに「多様な環境」を想定した多角的な攻撃を自動化しているかという事実です。
しかし、設置したModSecurityは、相手がRubyを狙おうがNode.jsを狙おうが、「外部から実行コードが注入される」という本質的な異常を逃しませんでした。