ログ分析に使えるLinuxコマンド6選

ログを主にセキュリティ目線で分析するときに、役立つ6つのコマンドとその使い方です。
SIEM等の環境がなくても、LinuxまたはWindows上の[Cygwin](https://www.cygwin.com/)等があれば分析できます。


## 役立つケース
* ハニーポットやWebサーバを運用していて、急にアクセス数が多くなり、原因を知りたいとき
* 運用しているサーバに脆弱性が見つかり、Exploitの痕跡の有無をログから調査したいとき

## コマンド6選
| コマンド | 用途 |
| :--: | ---- |
| grep | 指定した文字列を含む行を検索 |
| awk | 列の分解や条件付き行の検索 |
| sort | 行の並び替え |
| uniq | 重複行の除去や数のカウント |
| wc | 文字数、行数のカウント |
| sed | 指定した条件の置換 |


## 分析対象(例)
### access_log(Apache HTTP Serverのアクセスログ)
```
203.0.113.1 - - [03/May/2020:12:00:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
203.0.113.1 - - [03/May/2020:12:10:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
203.0.113.2 - - [03/May/2020:12:20:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64)"
203.0.113.2 - - [03/May/2020:12:30:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64)"
203.0.113.2 - - [03/May/2020:12:40:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64)"
198.51.100.3 - - [03/May/2020:12:50:00 +0900] "GET /index.cgi?page=<Script>alert('Evil')</Script> HTTP/1.1" 200 3000 "-" "Evil User Agent"
198.51.100.3 - - [03/May/2020:13:00:00 +0900] "GET /../../../../../etc/shadow HTTP/1.1" 200 3000 "-" "Evil User Agent"
```

### 補足
* `203.0.113.0/24`からは正常アクセス、`198.51.100.0/24`は不審なアクセスと想定
* ログフォーマットの詳細は下記を参照してください。
  [ログファイル - Apache HTTP サーバ バージョン 2.4](http://httpd.apache.org/docs/2.4/ja/logs.html#accesslog)

## 活用方法(例)
### 特徴の検索(grep)
* ディレクトリトラバーサル攻撃の調査

```
$ grep -n "\.\." access_log
7:198.51.100.3 - - [03/May/2020:13:00:00 +0900] "GET /../../../../../etc/shadow HTTP/1.1" 200 3000 "-" "Evil User Agent"
```

* 不審なスクリプト挿入の調査

```
$ grep -i "<script>" --color access_log
198.51.100.3 - - [03/May/2020:12:50:00 +0900] "GET /index.cgi?page=<Script>alert('Evil')</Script> HTTP/1.1" 200 3000 "-" "Evil User Agent"
※実環境では<Script>が色付けされて表示されます
```

* 不審なHTMLタグ挿入の調査

```
$ grep -E "<[^>]+>[^<]+<[^>]+>" -o access_log
<Script>alert('Evil')</Script>
```

* オプション説明

| オプション | 用途 |
| :--: | ---- |
| -n | マッチする行の行番号を表示 |
| -i | 大文字・小文字を区別しない |
| --color | 検索に一致した部分を色付けする |
| -o | 検索に一致した部分を表示する |
| -E | 拡張正規表現を使用する |

### 不要ログの除去(grep)
* 正常なアクセス元からのログの除去

```
$ grep -v "203.0.113." access_log
198.51.100.3 - - [03/May/2020:12:50:00 +0900] "GET /index.cgi?page=<Script>alert('Evil')</Script> HTTP/1.1" 200 3000 "-" "Evil User Agent"
198.51.100.3 - - [03/May/2020:13:00:00 +0900] "GET /../../../../../etc/shadow HTTP/1.1" 200 3000 "-" "Evil User Agent"
```

* オプション説明

| オプション | 用途 |
| :--: | ---- |
| -v | 検索に一致した行を表示しない |


### 要素の抽出(awk)
* 送信元IPアドレスの抽出

```
$ awk '{print $1}' access_log 
203.0.113.1
203.0.113.1
203.0.113.2
203.0.113.2
203.0.113.2
198.51.100.3
198.51.100.3
```

* User Agentの抽出

```
$ awk -F[\"] '{print $6}' access_log 
Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Mozilla/5.0 (Windows NT 6.3; Win64; x64)
Mozilla/5.0 (Windows NT 6.3; Win64; x64)
Mozilla/5.0 (Windows NT 6.3; Win64; x64)
Evil User Agent
Evil User Agent
```

* オプション等説明

| オプション等 | 用途 |
| :--: | ---- |
| {print $1}| 区切り文字で区切った1列目を表示 |
| -F | 区切り文字を指定する(デフォルトはスペース) |


### 集計・ソート(sort/uniq/wc)
* 送信元IPアドレスごとのアクセス数(降順)

```
$ awk '{print $1}' access_log | sort | uniq -c | sort -rn
      3 203.0.113.2
      2 203.0.113.1
      2 198.51.100.3
```

* 送信元IPアドレスごとの種類数

```
$ awk '{print $1}' access_log | sort | uniq | wc -l
3
```

* オプション説明

| コマンド、オプション等 | 用途 |
| :--: | ---- |
| uniq -c | 重複する数を表示する(前後のみ比較するためsortが必要) |
| sort -n | 数字を文字列ではなく、数字として扱う |
| sort -r | 降順で並べ替える(デフォルトは昇順) |
| wc -l | 行数を表示する |

### 置換(sed)
* 正常アクセスの送信元IPアドレスの匿名化

```
$ sed "s/203\.0\.113\.[0-9]\{1\,3\}/xxx.xxx.xxx.xxx/g" access_log
xxx.xxx.xxx.xxx - - [03/May/2020:12:00:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
xxx.xxx.xxx.xxx - - [03/May/2020:12:10:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
xxx.xxx.xxx.xxx - - [03/May/2020:12:20:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64)"
xxx.xxx.xxx.xxx - - [03/May/2020:12:30:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64)"
xxx.xxx.xxx.xxx - - [03/May/2020:12:40:00 +0900] "GET /index.html HTTP/1.1" 200 1000 "http://example.com/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64)"
198.51.100.3 - - [03/May/2020:12:50:00 +0900] "GET /index.cgi?page=<Script>alert('Evil')</Script> HTTP/1.1" 200 3000 "-" "Evil User Agent"
198.51.100.3 - - [03/May/2020:13:00:00 +0900] "GET /../../../../../etc/shadow HTTP/1.1" 200 3000 "-" "Evil User Agent"
```

* オプション説明

| オプション | 用途 |
| :--: | ---- |
| s/文字列A/文字列B/g | 文字列Aを文字列Bに置き換える。gを付けることで全て置換する。正規表現も使用可能。 |


## 参考
IPAからログ分析を支援するツールも公開されており、こちらの活用も有効です。

* ウェブサイトの攻撃兆候検出ツール iLogScanner  
  https://www.ipa.go.jp/security/vuln/iLogScanner/


## まとめ
grep、awk、sort、uniq、wc、sed等のコマンドを駆使すれば、SIEMがなくともある程度の分析が可能です。
実際に分析を行うときは、下記のようにパイプ`|`で多くのコマンドをつないで、分析します。

```
$ grep -v "203.0.113." access_log | awk '{print $1}' | sort | uniq -c | sort -rn
      2 198.51.100.3
```

そのため、イディオムのようにコマンドのつなぎ方を覚えておくのが良いと思います。


##
各ブログ（[はてブ](https://moneymog.hatenablog.com/)、[Qiita](https://qiita.com/moneymog)、[Note](https://note.com/moneymog)）の更新やセキュリティニュース等をTwitterでお知らせしています。
よろしければ、Twitter（[@moneymog](https://twitter.com/moneymog)）をフォローください。