脆弱性の公表時に、特定の文字列をgrepで探す
ライブラリやソフトウェアの脆弱性が公表されると、「自分のサーバーに該当するものがあるか」を素早く確かめる必要が出てきます。ここでは grep を使って、特定の文字列を手早く洗い出す手順を整理します。
どんな場面か
脆弱性情報には、影響を受けるバージョン、問題のある設定値、攻撃時にログへ残りやすいパターンなど、「探すべき文字列」が書かれていることが多くあります。これらを手がかりに、設定ファイル・ログ・ソースコードの中から該当箇所を探すのが最初の一歩です。なお、パッケージの有無やバージョンは dpkg -l や rpm -qa でも確認できますが、設定の記述やログの痕跡は grep で探すことになります。
調査の進め方
ステップ1:探す文字列と範囲を決める
公表情報から、探す文字列(バージョン番号、設定キー、関数名、攻撃パターンなど)と、探す場所(/etc、アプリのディレクトリ、/var/log など)を決めます。範囲を絞らずに / 全体を探すと、時間がかかるうえ、擬似ファイルシステムの出力も混ざります。
ステップ2:ディレクトリを再帰的に探す
$ grep -rn "log4j" /opt/app 2>/dev/null # -r 再帰、-n 行番号つき
$ grep -rl "Options +Indexes" /etc/apache2 # -l 該当ファイル名だけ表示
-r でサブディレクトリまで探し、-n で行番号、-l でファイル名のみを表示できます。権限のないファイルのエラーが邪魔なときは 2>/dev/null で標準エラー出力を捨てます。ただし、読めなかったファイルがあることは頭に置いておきましょう。
ステップ3:大文字小文字・単語・固定文字列を使い分ける
$ grep -rniw "debug" /etc/myapp # -i 大文字小文字を無視、-w 単語として一致
$ grep -rnF "${jndi:" /var/log/myapp # -F 正規表現ではなく固定文字列として扱う
記号を含む文字列は、正規表現として解釈されて意図しない結果になることがあります。そのまま探したいときは -F を使うと安心です。
ステップ4:ログから痕跡を探す
$ grep -c "攻撃パターン" /var/log/nginx/access.log # 件数だけ数える
$ zgrep "攻撃パターン" /var/log/nginx/access.log.*.gz # 圧縮済みの過去ログも探す
ログローテーションで圧縮された過去ログは zgrep で探せます。ヒットした行は -B・-A で前後の行も表示すると、前後の流れを確認できます。ヒットが多いときは awk や sort | uniq -c と組み合わせて、アクセス元ごとに集計するとよいでしょう。
ステップ5:結果を記録する
$ grep -rn "log4j" /opt/app 2>/dev/null > ~/grep-result.txt
調査結果はファイルに残しておくと、対応の判断や報告のときに役立ちます。
解決方法・次の一手
- 該当が見つかった場合:
公表情報の影響範囲(バージョン・設定)と照らし合わせ、修正バージョンへの更新や回避策の適用を検討します。 - 該当がなかった場合: 探した範囲と文字列を記録しておきます。「見つからなかった」ことも調査結果です。
- ログに痕跡があった場合: 日時・アクセス元を整理し、被害の有無を慎重に確認します。
grep で見つからなくても、安全とは限りません。文字列が分割・エンコードされている場合や、圧縮ファイル・バイナリの中にある場合は検出できないことがあります。
公表元の対応手順を必ず確認してください。
grep の基本は初級「ファイルの中身を見る」、パイプでの絞り込みは中級「テキストフィルタ」、セキュリティ運用は上級「セキュリティ運用」で扱っています。練習用ターミナルでも
grep -rn を試せます。