タグ: ログ調査

壁をどう補強するか──ログと決断、そして未来への備え

はじめに

Linuxサーバーを運用していると、セキュリティ対策について考える機会が少なくありません。

  • ファイアウォールを設定する
  • アクセス制御を行う
  • WAFを導入する
  • OSやソフトウェアを更新する
  • 必要に応じて設定を見直す。

こうした作業を続けていると、一つの疑問に行き着きます。

次に、何をすればよいのでしょうか。

防御を強化しようと思えば、できることはいくらでもあります。壁を高くすることも、厚くすることも、別の材料を追加することもできます。

しかし、すべてを実施するには時間も手間もかかります。設定を増やせば、その分だけ管理する対象も増えていきます。だからこそ、必要になるのは判断です。

何を守るべきなのか。現在の防御には何が足りないのか。そして、次に何をするべきなのか。

今回は、サーバーのログを手がかりに、セキュリティ対策における決断と未来への備えについて考えてみます。

壁の補強には、判断が必要です

前回の記事では、セキュリティを「壁を作り、手入れを続けること」として考えました。

壁一枚でも、そこにあることで防げるものがあります。壁が万能ではないからといって、その価値がなくなるわけではありません。

しかし、壁を作り、維持しているだけで十分なのかといえば、そうとも限りません。

時間が経過すれば、周囲の環境が変わります。以前は問題にならなかった経路から侵入を試みる者が現れることもあれば、利用するソフトウェアが変わり、新たな対策が必要になることもあります。

そのとき、壁を補強する必要があるのかを考えなければなりません。

例えば、ファイアウォールで許可する通信を見直す。SSHの接続元を制限する。ModSecurityのルールセットを更新する。認証ログに現れる不審な試行を調査する。

どれも防御を維持するための選択肢です。

しかし、ある場所で問題が発生したからといって、すべての壁を一律に高くすればよいわけではありません。必要なのは、どこが弱く、何を補強すれば、守りたいものをより確実に守れるのかを見極めることです。

防御を増やすことよりも、何を補強するべきかを判断することのほうが重要になる場面があります。

ログは、補強する場所を考えるための材料です

では、その判断を何に基づいて行えばよいのでしょうか。

ここで役立つのが、日々蓄積されていくログです。

アクセスログには、どのようなリクエストが届いたのかが記録されます。認証ログには、ログインの成功や失敗などが残ります。システムログには、サービスの起動や停止、エラーなどが記録されます。

それぞれの記録を確認することで、普段どのような通信が発生しているのか、どのような問題が繰り返されているのかを調べられます。

例えば、特定のURLに対して不審なリクエストが繰り返されているとします。その記録から、WAFのルールで検知できているのか、遮断できているのか、アプリケーションに到達しているのかを確認できます。

また、SSHへの認証失敗が繰り返されている場合には、現在のアクセス制御や認証方式が適切かどうかを見直すきっかけになります。

一件の記録だけでは分からないことも、長期間の記録を比較することで見えてくる場合があります。

ログは、単に過去の出来事を保存するためのものではありません。次にどこを補強するべきかを考えるための材料でもあるのです。

すべての問題に、すぐ対応する必要はありません

ログを確認していると、さまざまな問題や不審な動きが目に入ります。

対処できるものもあれば、調査が必要なものもあります。現在の設定で十分に防げているものもあるでしょう。

ここで重要になるのが、決断の順序です。

見つけた問題に片っ端から対応していけば、一見すると積極的に防御を強化しているように見えます。しかし、変更のたびに検証や影響確認が必要になり、管理する対象も増えていきます。

場合によっては、対策を追加したことで正規の通信まで遮断してしまうこともあります。

だからこそ、問題を発見したときには、まず現状を把握する必要があります。

  • 何が起きているのか
  • 現在の仕組みで防げているのか
  • 放置した場合、どのような影響が考えられるのか
  • 対策を変更した場合、既存のサービスにどのような影響があるのか
  • 変更したことを、後から検証できるのか

こうした点を整理してから、対応する順序を決めます。

すぐに対処するべきものは対処し、継続して観察するものは記録を追い、現状で十分に防げているものはその状態を維持する。

この区別ができれば、目に入った問題すべてに同じだけの時間を費やす必要はなくなります。

判断を先送りすることと、状況を把握したうえで経過を観察することも違います。

何もしないという選択にも、状況を確認したうえで維持するという判断があり得ます。

未来への備えは、未来を完全に予測することではありません

サーバーの運用では、これから何が起きるかを完全に予測することはできません。

新たな脆弱性が発見されるかもしれません。攻撃の傾向が変わるかもしれません。ソフトウェアの更新によって、これまで問題のなかった設定を見直す必要が生じるかもしれません。

そのすべてを事前に予測し、対策を完成させておくことは困難です。

では、未来に備えるとは、どういうことなのでしょうか。

それは、未来に起きることをすべて当てることではなく、変化が起きたときに対応できる状態を維持することだと考えています。

ログを残しておく。設定変更の内容を記録する。変更前の状態に戻せるようにしておく。定期的に更新情報を確認する。必要なときに調査できるよう、基本的な運用手順を整えておく。

こうした準備があれば、問題が発生したときにも、手がかりを探し、影響を確認し、対応を選ぶことができます。

未来への備えとは、すべての問題に対する答えを先に用意することではありません。

問題が起きたときに、考え、判断し、行動できる余地を残しておくことです。

決断コストを減らすために、決断の仕組みを作る

ここで、日々のサーバー運用と決断コストの関係についても考えてみます。

運用を続けていれば、何らかの判断を求められる場面は必ず発生します。

  • どのログを調べるのか。
  • どの設定を変更するのか。
  • どの脆弱性に優先して対応するのか。
  • どこまで対策を追加するのか。

そのたびに、すべてをゼロから考えていては、時間も注意力も消費してしまいます。だからこそ、あらかじめ判断の基準を持っておくことが役立ちます。

例えば、設定を変更するときには、変更の目的、影響範囲、確認方法、切り戻し方法を整理しておく。問題を発見したときには、実際の影響と現在の防御状況を確認する。定期的な更新や点検は、可能な範囲で手順化する。

そうすれば、毎回すべてを考え直す必要がなくなります。

一方で、手順化したからといって、状況を確認せずに機械的に実行すればよいわけでもありません。前提条件が変わっていれば、以前の判断基準が適切でなくなることもあります。

重要なのは、考えることを放棄するのではなく、繰り返し発生する判断を整理し、本当に検討が必要な部分に時間を使えるようにすることです。

壁を作り、点検し、必要に応じて補強する。その一連の仕事に、一定の基準と手順を設けておく。これによって、日々の判断に必要なコストを抑えながら、状況の変化にも対応しやすくなります。

心構えを維持するということ

こうした運用を続けるうえで、もう一つ大切なのが、管理者自身の心構えです。

セキュリティ対策は、一度実施すれば終わる仕事ではありません。ログは日々増え、ソフトウェアは更新され、環境は少しずつ変化していきます。

毎日すべてを完璧に確認することは難しくても、必要な点検を続け、問題があれば調べ、必要な変更を行うことはできます。そのためには、運用を一時的な気合いや緊張感だけに頼らないことも重要です。

  • 作業を手順化する。
  • 変更内容を記録する。
  • 定期的に確認する項目を決める。
  • 問題が発生したときに、どこから調べればよいかを整理しておく。

こうした仕組みがあれば、日々の気分や忙しさだけに左右されず、必要な作業を継続しやすくなります。

すべてを一度に解決しようとしないことも大切です。今日できる点検を行い、必要な修正を加え、次に確認するべきことを残しておく。状況が変われば、そのときに改めて判断する。

これもまた、壁を長持ちさせるための手入れの一つです。

おわりに

サーバーを守るための仕組みは、一度作れば完成するものではありません。

環境の変化に応じて点検し、必要な部分を補強し、役割を果たし続けられるように維持していく必要があります。

そのために、ログがあります。過去の出来事を確認し、現在の状態を理解し、次に何をするべきかを考えるための材料です。

そして、その材料を使って判断するのは、運用者自身です。

すべての問題を予測することはできません。すべての対策を一度に実施することもできません。それでも、状況を記録し、判断の基準を持ち、必要なときに対応できる状態を維持することはできます。

壁を作る。壁を手入れする。ログを読み、必要な場所を補強する。そして、変化に備えて次の判断ができるようにしておく。

その繰り返しが、長く使い続けられるサーバーを支えます。

未来を完全に予測することはできなくても、未来に向けて判断できる状態を維持することはできます。

そういう意味で、筆者が心に留めている言葉があります。『未来戦隊タイムレンジャー』

未来は変えられなくたって自分達の明日ぐらい変えようぜ。
出来るって! だってさ、次の瞬間、何するか決めるの
どう考えたって自分だろ?

このログ(言葉)があるからこそ、筆者は少なくとも未来をちょっとはマシにできると考えています。

さておき、日々の運用とは、そうした小さな決断を積み重ねながら、必要な安全性と安心を保ち続ける仕事なのだと思います。

【WAF検知ログ解析】難読化された JavaScript 偵察ツールを ModSecurity はどう見抜いたのか

はじめに

Redmine 6.1への移行作業がようやく一段落したので、久しぶりにサーバーログを眺めていました。

すると、トップページ (hoge.example.com) に対して、見慣れない長大なペイロードが飛んできていました。

最近の攻撃は「脆弱性を突く」ことだけが目的ではありません。まずは対象がどんな環境なのかを調べ、その結果によって次の手を変えてきます。

今回は、その偵察段階で送られてきたJavaScriptペイロードがなかなか興味深い内容だったので、ModSecurityのログを追いながら見ていきます。

検出された ModSecurity ログ

まずは実際のログです。

例によってIPアドレスはダミーに置き換えています。テロリストに名前を与えていません。

[Wed Sep 02 02:04:07 2026] [security2:error] [client 198.51.100.24:56250] ModSecurity: Warning. Pattern match "(?i)(?:b[\\"'\\\\)\\\\[\\\\x5c]..." at ARGS:0. [file "REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "205"] [id "932235"] [msg "Remote Command Execution: Unix Command Injection (command without evasion)"] [data "Matched Data: eval)(global[String['from'+'CharCode'](66,117,102,102,101,114)].from('KGFzeW5jIGZ1bmN0aW9uKCl7Ci8vIGZhc3RfcmVjb25fdjY..."] [hostname "hoge.example.com"] [uri "/"]
[Wed Sep 02 02:04:07 2026] [security2:error] [client 198.51.100.24:56250] ModSecurity: Rule [id "932250"] - Execution error - PCRE limits exceeded (-47): (null). [hostname "hoge.example.com"] [uri "/"]
[Wed Sep 02 02:04:07 2026] [security2:error] [client 198.51.100.24:56250] ModSecurity: Warning. Pattern match "(?i)\\\\b\\\\(?[\\"']*(?:assert|eval|exec|passthru)..." at ARGS:0. [file "REQUEST-933-APPLICATION-ATTACK-PHP.conf"] [line "406"] [id "933160"] [msg "PHP Injection Attack: High-Risk PHP Function Call Found"] [hostname "hoge.example.com"] [uri "/"]

最初に目を引くのは Rule 932235 が反応していることです。

Remote Command Execution:
Unix Command Injection

さらに途中では

PCRE limits exceeded (-47)

というログも出ています。

Base64の中身を見てみる

ログ中に埋め込まれていたBase64文字列をデコードすると、次のようなヘッダーが現れました。

(async function(){
// fast_recon_v6 — signature-rotated recon payload
// Changes from v5:
//   - Randomized top-level JSON keys (no fixed schema to fingerprint)
//   - Variable output structure per invocation
//   - IMDS calls use randomized User-Agent + jittered timeouts
//   - File reads are shuffled order (no deterministic sequence)
...

名前からも分かるように、これは偵察を目的としたJavaScriptです。面白いのは「何を調べるか」よりも、「どうやってWAFの検知を避けようとしているか」の方でした。

難読化の目的はコードを隠すことではない

例えば、

global[String['from'+'CharCode'](...)]

という書き方。普通なら

Buffer

と書けば済むものを、わざわざ文字コードから組み立てています。さらに

(0,eval)(...)

という間接呼び出しも使われています。どちらもJavaScriptとしては動作は同じですが、単純な文字列検索やシグネチャ検知を避けるための定番手法です。

コードを読めなくすることより、「機械に見つかりにくくすること」の方が目的と言った方が近いでしょう。

偵察対象も今どきらしい

コードを見ると、次のような情報収集も行おうとしていました。

  • クラウドメタデータ(IMDS)へのアクセス
  • IAMロールなど認証情報の取得
  • ファイル探索順序のランダム化
  • User-Agentやタイムアウト値のランダム化

固定パターンをできるだけ作らないよう工夫されており、「同じ攻撃を毎回少しずつ変える」という最近の攻撃らしい作りになっています。

PCRE が限界を迎えても、防御は止まらない

途中で

PCRE limits exceeded (-47)

が記録されています。これは巨大な入力に対して、ある正規表現がバックトラック上限へ達したことを示しています。

しかし、OWASP CRSは一つの巨大なルールだけで防御しているわけではありません。このリクエストでは、

  • 932235
  • 932260
  • 933160
  • 933210

と、別方向から検査するルールが続いてヒットしました。

つまり、一つの正規表現が処理を諦めても、他のルールが引き継ぐ設計になっています。

多層防御という言葉はよく聞きますが、今回のログはその動きを非常に分かりやすく見せてくれました。

おわりに

最近は攻撃そのものより、「検知をどう回避するか」の工夫を見る機会が増えてきました。

とはいえ、こうして落ち着いて中身を眺められるのは、防御基盤が先に仕事をしてくれているからです。

「サーバー運用はサファリパークに似ている」ようなものです。猛獣を間近で観察できるのは面白いですが、それは檻や装甲車があるからこそです。

今回も同じでした。難読化されたJavaScriptをじっくり読めたのは、攻撃がアプリケーションまで届かなかったからです。

運用者としては、その「観察できる余裕」こそが、一番ありがたい成果だったのかもしれません。

Powered by WordPress & Theme by Anders Norén