セキュリティのためのログ分析入門の個人的メモ

## はじめに
[セキュリティのためのログ分析入門 サイバー攻撃の痕跡を見つける技術](https://www.amazon.co.jp/%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%AD%E3%82%B0%E5%88%86%E6%9E%90%E5%85%A5%E9%96%80-%E3%82%B5%E3%82%A4%E3%83%90%E3%83%BC%E6%94%BB%E6%92%83%E3%81%AE%E7%97%95%E8%B7%A1%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%82%8B%E6%8A%80%E8%A1%93-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/429710041X)を読んで、個人的に重要と思った知識やマインドを見返すためのメモです。
あくまで主観的なまとめであり、本書の内容を完全に表したものではありません。

## Linux標準コマンドを使ったログ分析
### grep
指定したパターンを含む行を抽出するコマンド。
主に使用されるオプションとして以下のものがある。
 `-c` オプション：パターンマッチした**行数**を抽出する
 `-v` オプション：パターンに**マッチしない行**を抽出する
 `-o` オプション：**正規表現**を使ってパターンマッチングを行う
```
grep "HTTP/1.1\" 404" access_log
# \"はダブルクォーテーションをエスケープ処理している
grep "HTTP/1.1\" 404" access_log | grep -c -v "favicon.ico"
# 404エラーのログの中でfavicon.icoではない行をカウント
```
### uniq -c
集約して数え上げを行うコマンド。
時間帯別に何件ログが来たかを調べるのに便利。
```
grep -o '[0-9]\{2\}/.../2015:[0-9]\{2\}' access_log | uniq -c
# 各時間帯ごとのリクエストを数え上げしている
```
### Process Substitution
`<(コマンド)`という記法でコマンドの実行結果を入力ファイルとして他のコマンドに渡せる。
一時ファイルや名前付きファイルを作らず、必要な情報だけを記した結果を出力できる。
（逆に出力ファイルとして渡す`>(コマンド)`もあるが利用場面が非常に少ないため省略。）

## Apache httpd
ログの設定はデフォルトだと`http.conf`に格納される。
効率よくログ分析を行うには出力すべき項目を絞る必要がある。以下に分析で必要なログ項目を記載する。
- いつ（When） → **日時（%t）**※タイムゾーンの注意が必要
- 誰が（Who） →  **ユーザID（%u）**※ただしHTTPの認証が無いと使えない
- どこから（Where） → **ソースIPアドレス（%h）**
- 何を用いて（How） → **User-Agent**
- 何をして（What） → **リクエストURL（%r）**
- どうなった（What） → **処理結果（%>s,%b）**※本来データが送られるはずのレスポンスサイズが0だったり、明らかに異常サイズのデータが送られたりしたら注意
- 利用者の導線を追跡 → **Referer**
- 利用者の振る舞いを追跡 → **セッションID（%{SessionId}C,%{Set-Cookie}o）**※conbined形式ではデフォルトで搭載されていないので注意

## mod_dumpio
Apache httpdで有効にすると、Apacheが受け取ったすべての入力/出力の両方もしくは一方を`error_log`に収集。つまり**POSTデータをログ収集**することができる。
組み込むには`httpd.conf`で以下の行を追加、もしくはコメントアウトの削除を行う。
```
LoadModule dumpio_module modules/mod_dumpio.so
DumpIOInput On # 入力の記録を行う
DumpIOOutput On # 出力の記録を行う
LogLevel debug dumpio:trace7 # どのレベルのログまでを記録するか指定
```

しかしPOSTデータの集積を行うため、**セキュアで扱う必要のあるデータを平文でログに残しても問題ないか**、POSTの情報が必要なら**アプリケーション側でログを残す方法がないかなど検討する必要**があるので、利用シーンは少ないと思える。

## 攻撃者の検知回避
- **オプションを略式で書かずに正式名称で書く**
- **小文字と大文字をわざと混ぜる**
- **パーセントエンコーディング**
（二重に利用するダブルエンコーディングという方法も）
- **空白や改行でパターン検知から逃げる**
- **本来HTTPバージョンが入るところに攻撃が含まれている**
（検知対象のフィールドを限定していると検知されないという危険性がある）
- **Base64を使ったデコード化でコードを隠ぺいする**

## プロキシログ（squid）
クライアントのアクセス解析、適切なフィルタリングのチェックをする用途で使われる。
ログの設定ファイルは`etc/squid3/squid.conf`で定義されている。
形式を変更する場合は`squid.conf`に以下の行を追加してsquidを再起動することで可能。
```
access_log /var/log/squid3/access.log <形式名>
```

プロキシログでは**ユーザ名の情報**を含めることが推奨される。
IPアドレスの利用者が頻繁に変わるDHCPのような環境では、MACアドレスをDHCPのサーバから確認する必要があるが、その作業がなくなるので非常に有用的。

### 注目すべき項目
- User-Agent：どのプログラムでアクセスしたかが見られる
- Status-Code：悪性サイトに入ってしまったかが確認できる
- Content-Type：どんなデータかを確認し、それが悪性かを確認できる
- User：IPアドレスが変化しても特定ができる
- Byte：データ量によって本来とは違う通信か、情報漏洩してるかなど判断できる

## IPSログ（Snort）
監査シグネチャが検知したログを表示する。
もちろん、シグネチャの精度が低ければ攻撃を検知できないため、公式からリリースされているシグネチャセットのインストールやログ分析と定期的なチューニングが必要。

## ファイアウォールログ
ある通信に対して「許可」または「拒否」した通信のログを表示する。
検知ルールを独自に設けることで以下のような攻撃や索敵行為の検知が可能。

- **ホストスキャン**：IPアドレスを増加させながら対象ホストの存在を確認する索敵行為
- **ポートスキャン**：特定のサーバがどのポート番号を使用しているか確認する索敵行為
- **不審な外部サービスの利用**：通常では想定されないサービスの利用による攻撃
- **DoS攻撃**：大量のトラフィックを送りサーバを応答不能にする攻撃
- **SlowDoS攻撃**：コネクションを張りっぱなしにして他ユーザのアクセスを妨害する攻撃

## システムコールログ（Linux Audit）
アプリケーションがOSの機能を呼び出した履歴をログとして表示する。
設定については2つファイルが存在し、`/etc/audit/auditd.conf`はauditd自身について、`/etc/audit/audit.rules`はどのシステムコールを監視するかについてを設定する。

オプションについて多数記載があるが、今回は`-a list,action`に絞って説明する。
listはどこに監視ポイントを設定するかを指定する項目。どちらかと言えばフィルター的な役割を持っている？
- `task`：falkやcloneシステムコールのみにチェックされ、ほぼ使わない
- `user`：uidやpidなどのユーザ情報をフィルタリングする
- `entry`：システムコールの開始時に監視ポイントを置く
- `exit`：システムコールの終了時に監視ポイントを置く
- `exclude`：イベントが除外された地点に監視ポイントを置く

actionは監査ログを出力するかを決定でき、`always`なら出力、`never`なら出力しない。

検知方法として、OSに対するシステム実行は通常`execve`システムコールを使用して実行しているため、そこを監視すべきと考えられるのがまず考えられるが、そのままだと甚大な量のログが出力されてしまう。
そこで**どこに対して`execve`システムコールを監視するかが要**となってくる。

さらに監査ログのkey、特に実際に送られたコマンドが確認できる`a0~a4`を確認し、通常サービスから見たら異常と思われるコマンドを探し出す必要がある。

## 関数トレースログ（SystemTap）
呼び出されたアプリケーションの関数の履歴をログとして表示する。
システムコールログだけでは検知できない、アプリケーションの関数の機能だけを悪用した攻撃を検知するために用いられる。

`SystemTap`はどの関数やシステムコールをフックするか、フックした後どのように動作するかを記入した`stp`スクリプトを用意する必要がある。使い方については[プローブポイントについての記事](https://hana-shin.hatenablog.com/entry/2023/01/16/230339#google_vignette)や[SystemTapについての記事](https://qiita.com/hana_shin/items/0f82ea9d8bc8ed5fd70b)を見た方が早い。

前述したシステムコールログも含め、より粒度の細かいログを検知し攻撃を特定できるというメリットがあるが、その分アプリケーションのパフォーマンスに影響を与えてしまうため、取得する情報の取捨選択が必要となる。

またこのSystemTapには仮想パッチと呼ばれる正式な修正パッチが出るまでの攻撃を防ぐ暫定的な対処方法をstpスクリプト内に記載することが出来るが、変数を書き換えるようなコードを記載した場合には安全制御機能が働く。`-g`オプションでその制御を解除できるが、**プログラムの動作に影響を与えるため慎重に行わなくてはならない**。

## ログ分析における重要なマインドセット
### ログ分析の自動化について
単にツールを導入するのではなく、**ログ分析を行う目的**、**分析の対象となるログ**、**どういう挙動をしていたら攻撃か**など軸を設けて検討し、どういうログ分析ツールを使うか選定すべきである。その中でも『どういう挙動をしていたら攻撃か』については**具体的な数値を設けて検討**する必要がある。

### ログの保存期間について
『コンピューターセキュリティログ管理ガイド』によると、
- 低位影響レベルのシステムでは**1～2週間**
- 中位影響レベルのシステムでは**1～3か月**
- 高位影響レベルのシステムでは**3～12か月**

を目安に検討を始めると良いとされている。
ただこれはあくまでも目安であり、クライアントのリソースや事情、セキュリティポリシーに応じて適切な期間を決めるべきという結論にどうしても落ち着いてしまう。

### ログ分析前のデータクレンジング(ETL)について
まずETLが有効なケースについて、端的に言うとログの形式を整形した方が分析しやすい場合に使用される。具体的な例として
- 異なるアプリや機器から出力されたログを統合的に扱いたい場合
- 同一ログ内で出力カラム数が異なる時
- ログに情報を追加したい時/ログから有用な行を抽出したい場合
が挙げられる。
あと大事な注意点として、**オリジナルのログデータは絶対に残しておくこと**。

### ログ改ざんについて
攻撃者の中にはシステムのログを編集し、攻撃の痕跡を隠ぺいするケースもある。
そうしないための技術の一つとして`syslog`がある。

syslogはサーバ/クライアント型のプロトコルで、クライアント側からテキストメッセージをサーバ側に送信できる。これにより保護したいログを別サーバに送り改ざんを防ぐ。
syslogの機能を使ったアプリケーションとして、`rsyslog`というソフトウェアが近年よく使われている。実装方法などについては[こちら](https://qiita.com/sugar_salt75/items/1d1980d5b66becc9f38f)に詳細を記している。