ApacheのModSecurityのSecRuleを解読していく。

# <font color=red>はじめのさらに初めに！！</font>
『お？これは誤検知しているかも???』と思った場合、
『SecRule』の`t:none,t:urlDecodeUni`を`t:utf8toUnicode`に変換してみる方がいいかもです！
ちなみに本当は、本当は全部`t:utf8toUnicode`とマッチしたデータが見やすいのです。
流石にしんどいですが、、
ちなみにちゃんと`t:utf8toUnicode`に変換すると、、以下のようにマッチデータ表示されます。みやすい!!
『"Matched Data: -------』
『ARGS:discription: SELECT-------』←こっちはどの引数名で弾いたかまでわかりますね！

```
Message: Access denied with code 403 (phase 2). Pattern match "\\W{4,}" at ARGS:discription. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_40_generic_attacks.conf"] [line "37"] [id "960024"] [rev "2"] [msg "Meta-Character Anomaly Detection Alert - Repetative Non-Word Characters"] [data "Matched Data: ------- found within ARGS:discription: SELECT-------"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "8"]
```

ちなみに変換がうまくいかない時もあったりするので調べてある程度調整は必要そうです。

# はじめに
認識間違え等あるよというものあればご指摘よろしくお願いいたします！:bow_tone1:

あと最初はボ〜〜〜っと眺めてへ〜〜〜ふ〜〜〜んって感じでいいかと思います！

今回解読するルールは以下です！
全文載せてますが上1行~2行ぐらいわかれば問題ない認識です！
![スクリーンショット 2022-05-02 15.51.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/dc9e74e2-43cd-e969-c20b-1a9c23647dbc.png)

説明の前に関連したこと少し説明。飛ばしても問題ないです！

**<font color="blue">【ModSecurityとは?】</font>**
apacheに入れるWAF的なもの。
モジュールでありライブラリ的なパッケージ的なものであります。

**<font color="blue">【WAFとは?】</font>**
サイトへの攻撃を弾くものです。
具体的に怪しい文字列が送られてきたりした場合にそれ以降の処理をさせないといったものです。

**<font color="blue">【ModSecurityはどんな人におすすめ？】</font>**
apacheに私は入れているのでapache使っている人にはとりあえずおすすめです。
ただ他のものにも入れれるようなので、
WAF入れたいけどお金はかけたくない的な方におすすめです。
有料のWAFとか課金性のものでない場合数万~数十万かかるイメージなので、、、

**<font color="blue">【なぜ記事にしたか？】</font>**
ドキュメント等探すのにある程度時間を要したこと、
結構詳しい記事がなかったため記事にしておこうと思った感じです。

**<font color="blue">【導入方法は？】</font>**
導入に関しては以下リンクみて簡単に入れられたので難しくないかと思います。
(以下リンクの作者様に感謝です！)
ただその後ある程度調整しないとかなり弾くなという感じでした。
(最初にきつくしていただけるのはありがたいのですがね、これはあたりまえなことなのでしょうがないのです。)

https://tex2e.github.io/blog/linux/centos-apache-modsecurity

**<font color="blue">【参考URL】</font>**
今回先に書いておきます！
各箇所にもなるべく入れるようにはしています！

**【ルールで使われてる用語の説明】**
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29

**【実際に読み込んでいる設定ふぁいるの大まかな説明はこの記事が一番わかりやすかったイメージです。】**
https://ai-soldier.work/waf-modsecurity-crs-rule-file/

**【ルールの説明等わかりやすく説明してくださっているもの】**
https://www.tohoho-web.com/ex/modsecurity.html

**【間接的に関係しているだろうOWASP ZAPのリンク】**
https://coreruleset.org/docs/rules/creating/

**【ルールどんなものがあるのかの参考。confファイルの中に色々なルールが書いてあります ※公式とかではなさそうです?】**
https://github.com/SEC642/modsec/tree/master/rules/base_rules

**【ModSecurityのgithub(今回記事中ではあまりこのサイトに触れるようなことはないの認識です)】**
https://github.com/SpiderLabs/ModSecurity


# 今回サンプルで解読していくルールサンプル文

ちなみに下記のルールを日本語で雑に表すと
```
『__utm』が入っていたり、『"』や『;』の文字が入っていればブロックします。
ちなみにこれらルールたまに誤検知あるからよろしく！。
誤検知したらログとか吐くよ！
```
です！
詳しくは以下で説明していきます！


```/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(^[\"'`´’‘;]+|[\"'`´’‘;]+$)" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'9',accuracy:'8',capture,t:none,t:urlDecodeUni,block,msg:'SQL Injection Attack: Common Injection Testing Detected',id:'981318',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',severity:'2',tag:'OWASP_CRS/WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
```
上記の全体像↓
![スクリーンショット 2022-05-02 15.51.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/a6252043-6d73-fc2b-7b6e-af977d5db502.png)


# サンプルを見た時知っておかないといけない用語説明
参考リンク
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29

**<font color=orange>以下表ですが、</font>**
(行動)とされているものは一緒に記述すると分かりにくいと感じたためあえて表では分けてます！
(行動)はルールに当てはめられた時に実行される処理ですという意味で認識でします。

| 用語 | 説明 | 補足 |
|:-|:-|:-|
| **SecRule**  |  特に意味はありません。文章書く時の『・』ぐらいのイメージで。 |   |
|**変数**<br>$\tiny{※変数一部抜粋して説明}$|REQUEST_COOKIES：リクエストクッキーに関して<br>REQUEST_COOKIES_NAMES：クッキーの名前<br>ARGS_NAMES：リクエストパラメーターの名前<br>ARGS：POSTやGETその他で指定される引数全て<br>XML：XMLDOM部分。`<employees></<employees>`のような部分のチェック。<br>|[参考(REQUEST_COOKIES)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#REQUEST_COOKIES)<br>[参考(REQUEST_COOKIES_NAMES)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#request_cookies_names)<br>[参考(ARGS_NAMES)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#ARGS_NAMES)<br>[参考(ARGS)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#ARGS)<br>[参考(XML)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#XML)<br>|
| **変換関数**<br>$\tiny{※変換関数一部抜粋して説明}$| 入力データを変換する指示。『,』区切りで指定できるようです。<br>複数ある場合、変換してチェックの作業が複数あるということ。<br><br>t:none：変換しない<br>t:urlDecodeUni：`Microsoft固有の％uエンコーディング`で変換<br>|  [参考リンク(none)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#none)<br>[参考リンク(urlDecodeUni)](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#urlDecodeUni) |
| **phase**(行動)  |  いつチェックするかのルールを示すためのもの。『2』がデフォルト<br>1：Phase リクエストヘッダー<br>2：Phase リクエストボディ<br>3：Phase レスポンスヘッダー<br>4：Phase レスポンスボディ<br>5：Phase ロギング |  [参考リンク](https://www.a-frontier.jp/technology/mod-security1/)<br>[参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#Processing_Phases) |
| **maturity**(行動)  | 1(実験的なルール)-9(完璧なルール)のような意味合いです。<br><br>実験的なルールはとりあえず外しても問題ぐらいの認識でいても良さそうです。  | [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#maturity)  |
| **accuracy**(行動) |  1(精度低い誤検知等あり)-9(精度高い)<br><br>9(精度高い)のものは出来るだけ消したくないですね、、<br>逆に1(精度低い誤検知等あり)は最初消しときたい気持ちもあるようなないような。 | [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#accuracy)  |
| **everity**(行動)  | 0(緊急事態)- 7(デバッグ)どれだけ重大かの指標。<br><br>0とかついているルールのものはなるべく使うようにしたいですね、、<br>0：緊急事態<br>1：アラート<br>2：クリティカル<br>3：エラー<br>4：警告<br>5：注意<br>6：情報<br>7：デバッグ<br>  |  [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#severity) |
| **capture**(行動)  | 正規表現の`()`内のものを保存しておくよというもの。それらは`TX.0`や`TX.1`に配置されるようです。上のサンプルデータを見ると後で何がマッチしたかの出力に使っているようですね。 |  [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#capture) |
|  **setvar**(行動) |  変数作成や更新削除に使用とのことです。<br>変数とはあれです。 <br>a="aa"の`a`のことです。<br>イマイチ何のために設定されているか明確ではなかったのですがいい感じに変数をどこかで使っている認識です。<br><br><br>setvar:TX.score=10 <= 変数設定 <br>setvar:TX.score <= 変数指定。| [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#setvar)  |
|**block**(行動)|ルールにハマった時どうするかのということらしいです。<br>この場合ブロックするの意かと。|[参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#block)|
| **rev**(行動)  | ルールのリビジョン(機能に変更ない変更)。なので特に気にしなくていいかと思います。  |  [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#rev) |
|  **ver**(行動) | ルールのバージョン(機能に変更ある変更)。なので特に気にしなくていいかと思います。  |  [参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#ver) |

:sunflower:REQUEST_COOKIES_NAMES：参考の方には指定クッキー名前がないと弾くサンプルが書かれてました！
:sunflower:ARGS：参考の方には色々な指定の仕方記述されてました！

そのほかは、、、

```
A|B => AまたはB
/正規表現/ => 正規表現の記述様式
```

以下の2パターンある場合下の『!』がついていれば弾かないという認識。
[参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#ARGS_NAMES)
```
テキスト
!テキスト
```

他のものみたい時は[参考リンク](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29)から探していただければ問題ないかと！

:jack_o_lantern:上記参考に一部分の判定を解読すると、、、
『リクエストクッキー』または『リクエストクッキーでないものに』に『__utm』が含まれていれば弾くとなります。
(『__utm』について調べたら、期限無期限的なワード等見受けられました。)

```
REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/
```


# 今回のルールで使われていた正規表現の解説

```
チェック内容: 最初や最後に連続しないまたは連続した『"』のようなものが存在するかの確認。
^[\"'`´’‘;]+|[\"'`´’‘;]+$

当てはまるものサンプル以下
"aaa
aaa""
"
""
''
`
``
´
´´
’
’’
‘
‘‘
;
;;
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/14ce48b3-cb57-78df-3471-48511151264a.png" width=300></img>

# おまけ1 実際に上記のもの弾くかみてみましょう！！ヽ(´▽｀)/
ちゃんと不正な文字が入っている時は弾いている確認できますね！
![実際に行ったものです。.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/d0cddd5e-b3d1-2551-7181-ab88acc45e62.gif)

ちなみに弾いた時は以下のようなログが出力されます。(全文は載せていないです)
マッチされたところや、何でエラーを返したか、どこのルールが弾いたルールかlineまで書いてくれています。
丁寧ですね。(✿´ ꒳ ` )

```
Message: Access denied with code 403 (phase 2). Pattern match "(^[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98;]+|[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98;]+$)" at ARGS:short_message. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "64"] 
```

# おまけ2 ブロックされた時原因探すまで。(私の環境にて)

```
まずログを見る。だいたい一番最後にエラーのログあるのでそれを。
$ sudo vim /var/log/httpd/modsec_audit.log
```

そうすると以下のようなログが吐き出されるので(上と同じログです。)、
該当箇所のルールを調整するまたはコメントアウトしてapache等再起動で反映するという感じですかね。

```
Message: Access denied with code 403 (phase 2). Pattern match "(^[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98;]+|[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98;]+$)" at ARGS:short_message. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "64"] 
```

# おまけ3 誤検知色々
誤検知1：『す』一文字とか連続『す』を入れるだけとかだとなぜか弾く。『あ』とかなら突破する。
誤検知1ルール：メモしておくの忘れました。

# おまけ4
使われちる正規表現当てはまるもの色々。※あくまでこんな感じに引っかかるよという感じです。
:sun_with_face:modsecurity_crs_40_generic_attacks.conf line:37
これ上記のものしなく日本語使っている場合誤検知の可能性あります、、

```
文字以外の4桁連続 
\W{4,}
```
![スクリーンショット 2022-05-03 17.14.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/32f94272-20b7-c534-345b-8a044de5e009.png)
![スクリーンショット 2022-05-03 17.26.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/8c903844-1877-542f-740f-56c421ce312f.png)


:sun_with_face:modsecurity_crs_41_sql_injection_attacks.conf line:64
```
『"』等の文字
(^[\"'`´’‘;]+|[\"'`´’‘;]+$)
```
![スクリーンショット 2022-05-03 17.57.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/ab30022a-a77e-0c00-d4a0-609bc267f8e6.png)



:sun_with_face:modsecurity_crs_41_sql_injection_attacks.conf line:245
```
(?i:(?:[\"'`´’‘]\s*?\*.+(?:x?or|div|like|between|and|id)    \W*?[\"'`´’‘]\d)|(?:\^[\"'`´’‘])|(?:^[\w\s\"'`´’‘-]+(?<=and\s)(?<=or|xor|div|like|between|and\s)(?<=xor\s)(?<=nand\s)(?<=not\s)(?<=\|\|)(?<=\&\&)\w+\()    |(?:[\"'`´’‘][\s\d]*?[^\w\s]+\W*?\d\W*?.*?[\"'`´’‘\d])|(?:[\"'`´’‘]\s*?[^\w\s?]+\s*?[^\w\s]+\s*?[\"'`´’‘])|(?:[\"'`´’‘]\s*?[^\w\s]+\s*?[\W\d].*?(?:#|--    ))|(?:[\"'`´’‘].*?\*\s*?\d)|(?:[\"'`´’‘]\s*?(x?or|div|like|between|and)\s[^\d]+[\w-]+.*?\d)|(?:[()\*<>%+-][\w-]+[^\w\s]+[\"'`´’‘][^,]))
```
![スクリーンショット 2022-05-03 18.43.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/2ad851e1-2f28-dc50-fd67-3ef7405bc66b.png)



# 最後に
案外少しずつ見ていけばそんなに難しいこと書いてなかったなというのが今回の感想でした！

あとルールどんなのあるかは以下が参考になるかと。confファイルの中に色々なルールが書いてあります！
興味あればぜひ！ ※公式とかではなさそうです?
https://github.com/SEC642/modsec/tree/master/rules/base_rules