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_processexecSync といった危険な関数呼び出しを完全にパターンマッチング。
  • 阻止: 前回同様、アプリケーション層に到達する前に403遮断(設定により404応答)。
  • 分析: 攻撃者はRedmine(Ruby on Rails)に対し、あえてNode.js/Next.js用の高度なペイロードを投げています。これは「何で動いているか分からないが、とりあえず流行りの脆弱性コードを全部試す」という、 スキャンから自動攻撃までシームレスに移行するボット*の挙動です。

技術的考察:2025年を締めくくった「贈り物」

このログが示しているのは、攻撃側がいかに「多様な環境」を想定した多角的な攻撃を自動化しているかという事実です。

しかし、設置したModSecurityは、相手がRubyを狙おうがNode.jsを狙おうが、「外部から実行コードが注入される」という本質的な異常を逃しませんでした。