日々是精進。(はてな館)

日々ネットで調べたり、付箋に書き留めたものをアップしています。子育てで中断しながらも、年に数回投稿しています。皆様の恩恵に感謝しつつ。

インフラ勉強会 / 20180810 「作ってみようWAF」を聞きました&Ubuntuでやってみました。

みなさまこんにちは。 はてなでの6つめの記事は、@柴雑種さまの インフラ勉強会 20180810 「作ってみようWAF」を聞いた感想や、その後試してみたことのメモになります!

https://wp.infra-workshop.tech/event/作ってみようwaf/

LTの流れ

ハンズオンの流れ

LT自体は、ハンズオン形式で進めてくださいました。 ライブで伺っている段階では、ハンズオン用の環境をすぐには用意できなかったので、お話を伺うのに専念。

  • CentOS7にApacheをインストールする
  • mod_securityをインストールする
  • 簡単なデモ用のconfを適用する
  • デモでブロック対象になるパターンでアクセスしてみる

といった流れでした。

実際に同じタイミングで参加されていたみなさんも、「curlで叩いてみたら確かにブロックされた!」というコメントをされていたり、やはり実際にやってみるのは大事だなと感じた次第です。

f:id:akiko-pusu:20180813224325j:plain
20180810 インフラ勉強会「作ってみようWAF」

フリートーク

30分くらいのハンズオンのあとは、参加されているみなさんの間でのフリートーク。 実際にWAFを導入したり、設定で色々ご経験がある方が割といらしたようで、こちらも大変参考になりました。

今であれば、今回のmod_securityのようなシグネチャ型(攻撃パターン、パラメータ定義に従ってフィルタする)方式だけでなく、一定間隔のアクセスパターンを判断したりして攻撃と判断するような、振る舞い型の防御策も採られているようで、いろいろ進化しているんだな..と思った次第。

(振る舞いを観測するものといえば、たとえばログを収集して解析するような、Splunkといったものも該当するのかな?)

とにかく、(現在運用の当事者ではないのですが)ワクワクしてお話を伺っておりました。

また、クラウドを利用した環境であれば、クラウド型のWAFを使うのが良い、といったお話も出ていました。 こちらに関しては、クラウドベンダーのエンドポイントにWAFを適用する場合、証明書はどこに置くの?といった質問も出ていました。 実際は、ベンダ側のDNSを利用するとかベンダに証明書を渡す、ただし証明書の更新は自分たちでやる...といった方法をとるようです。 (ベンダさんに色々お話を聞くと、このあたりは面白いと思います)

なるほど、ですね。

その他の話題

今回のWAFの件をもう少し踏み込んでみたり、OWASPについて触れてみたり、脆弱性のあるアプリケーションを攻撃してみるハンズオン...といったことも良さそう、という話題が出ていました。 あとは、マルウェア、ボットウェア(miraiとかその亜種とか)のソースコードを読んでみようといったものなど。

まずは@柴雑種さま、お話ありがとうございました!

以下は、あとからUbuntuにmod_securityを組み込んでみたので、その覚書になります。

Ubuntuでやってみる

ハンズオンではCentOS7をベースにということでしたが、手っ取り早く立ち上げられる環境がなかったので、Ubuntuで試すことにしました。 以下、淡々とした作業のメモになります。

Vagrantで "bento/ubuntu-18.04” を指定してインストール。

そのあとに、apcheを追加してみます。

vagrant@vagrant:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04 LTS”

vagrant@vagrant:~$ sudo apt install apache2

vagrant@vagrant:~$ curl -I -v localhost:80
* Rebuilt URL to: localhost:80/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> HEAD / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Sun, 12 Aug 2018 03:12:20 GMT
Date: Sun, 12 Aug 2018 03:12:20 GMT
< Server: Apache/2.4.29 (Ubuntu)
Server: Apache/2.4.29 (Ubuntu)
< Last-Modified: Sun, 12 Aug 2018 03:11:18 GMT
Last-Modified: Sun, 12 Aug 2018 03:11:18 GMT
< ETag: "2aa6-573345495bd3a"
ETag: "2aa6-573345495bd3a"
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Content-Length: 10918
Content-Length: 10918
< Vary: Accept-Encoding
Vary: Accept-Encoding
< Content-Type: text/html
Content-Type: text/html

< 
* Connection #0 to host localhost left intact

うまく入りました。 確認は、Vagrant内であればcurlコマンドを利用しましが、VagrantのホストOS (Mac側) の localhost 8000 番にもポートフォワードして、ホスト側のブラウザでも確認できるようにしてみました。

f:id:akiko-pusu:20180811164934p:plain

ModSecurityの公式に行ってみる

Ubuntuの場合はこのあと、どうすれば良いのかな?ということで、公式サイトを見て見ます。 Ubuntu / Debianでは libapache2-mod-security をインストール、と書いてありますが、どうやら libapache2-mod-security2 な模様です。

ということで、aptで追加をいたしました。

$ sudo apt install libapache2-mod-security2

-- [ 中略 ] --

Setting up liblua5.1-0:amd64 (5.1.5-8.1build2) ...
Setting up libapache2-mod-security2 (2.9.2-1) ...
apache2_invoke: Enable module security2
Processing triggers for libc-bin (2.27-3ubuntu1) ...

公式に従うと、a2enmod を使ってモジュールを有効化しないといけない模様です。 (こちらが済むまでは適用されません)

NAME
       a2enmod, a2dismod - enable or disable an apache2 module

vagrant@vagrant:/var/www/html$ sudo a2enmod
Your choices are: access_compat actions alias allowmethods asis auth_basic auth_digest auth_form authn_anon authn_core authn_dbd authn_dbm 

-- [ 中略 ] --

usertrack vhost_alias xml2enc
Which module(s) do you want to enable (wildcards ok)?

有効化 / 無効化

単純にa2enmodコマンドを打つと、どれを有効にしたいか聞かれます。

securityは mod_security2ではなくて、security2 のようなので、a2enmod security2 を実行してみます。 実行する前は、/etc/apache2/mods-enabled/ には mod_security関連の設定がありませんが、実行後は設定が追加されたのが分かります。

vagrant@vagrant:/var/www/html$ ls -la /etc/apache2/mods-enabled/security2.*
ls: cannot access '/etc/apache2/mods-enabled/security2.*': No such file or directory

vagrant@vagrant:/var/www/html$ sudo a2enmod security2
Considering dependency unique_id for security2:
Module unique_id already enabled
Enabling module security2.
To activate the new configuration, you need to run:
  systemctl restart apache2

vagrant@vagrant:/var/www/html$ ls -la /etc/apache2/mods-enabled/security2.*
lrwxrwxrwx 1 root root 32 Aug 12 04:04 /etc/apache2/mods-enabled/security2.conf -> ../mods-available/security2.conf
lrwxrwxrwx 1 root root 32 Aug 12 04:04 /etc/apache2/mods-enabled/security2.load -> ../mods-available/security2.load

設定をもう少し読み解く

/etc/apache2/mods-enabled/security2.conf

さて、security2.confが読み込まれているようなので、こちらを確認してみます。 /etc/modsecurity/*.conf が追加で読み込まれること、それから、OWASPが提供しているCSRが読みこまれるよ、という設定になっています。

CRSとは、攻撃を検知するための基本的なルールセット (Core Rule Set) のことです。 *1

<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        IncludeOptional /etc/modsecurity/*.conf

        # Include OWASP ModSecurity CRS rules if installed
        IncludeOptional /usr/share/modsecurity-crs/owasp-crs.load
</IfModule>

さらに /etc/ 以下の設定と、CRSについても確認してみます。

/etc/modsecurity/*.conf

パッケージでインストールした直後は、該当する *.conf は無く、modsecurity.conf-recommended という雛形が配置されています。 なので、いったんはこの設定が読み込まれていない状態。

有効化した場合の、一部の設定を載せてみます。

SecRuleEngine DetectionOnly
SecRequestBodyAccess On

SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log

/usr/share/modsecurity-crs/owasp-crs.load

/usr/share/modsecurity-crs/owasp-crs.load は、こんな内容でした。

##
## This file loads OWASP CRS's rules when the package is installed
## It is Included by libapache2-mod-security2
##
Include /etc/modsecurity/crs/crs-setup.conf
IncludeOptional /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
Include /usr/share/modsecurity-crs/rules/*.conf
IncludeOptional /etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

有効化してみる

まず簡単に、modsecurity.conf-recommended を modsecurity.conf として配置し、設定を有効化してみます。 そのうえで、q=? といったパラメータをつけてアクセスしてみると...。

SecRuleEngine DetectionOnly なので防御はされませんが、定義にひっかかるようなリクエストだと、modsec_audit.log にメッセージが出力されるようになります。

$ sudo tail -f /var/log/apache2/modsec_audit.log

-- [ 抜粋 ] --

--6881f71e-H--
Message: Warning. detected XSS using libinjection. [file "/usr/share/modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "64"] [id "941100"] [rev "2"] [msg "XSS Attack Detected via libinjection"] [data "Matched Data: accept found within ARGS:q: <script></script>"] [severity "CRITICAL"] [ver "OWASP_CRS/3.0.0"] [maturity "1"] [accuracy "9"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "OWASP_CRS/WEB_ATTACK/XSS"] [tag "WASCTC/WASC-8"] [tag "WASCTC/WASC-22"] [tag "OWASP_TOP_10/A3"] [tag "OWASP_AppSensor/IE1"] [tag "CAPEC-242"]

/usr/share/modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf にひっかかるよ、ということなので、そちらも見てみます。 対象業の近辺はこのようになっていました。

    37  SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@detectXSS" \
    38          "msg:'XSS Attack Detected via libinjection',\
    39          id:941100,\
    40          phase:request,\
    41          severity:'CRITICAL',\
    42          rev:'2',\
    43          ver:'OWASP_CRS/3.0.0',\
    44          maturity:'1',\
    45          accuracy:'9',\
    46          t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\
    47          block,\
    48          ctl:auditLogParts=+E,\
    49          capture,\
    50          tag:'application-multi',\
    51          tag:'language-multi',\
    52          tag:'platform-multi',\
    53          tag:'attack-xss',\
    54          tag:'OWASP_CRS/WEB_ATTACK/XSS',\
    55          tag:'WASCTC/WASC-8',\
    56          tag:'WASCTC/WASC-22',\
    57          tag:'OWASP_TOP_10/A3',\
    58          tag:'OWASP_AppSensor/IE1',\
    59          tag:'CAPEC-242',\
    60          logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    61          setvar:'tx.msg=%{rule.msg}',\
    62          setvar:tx.xss_score=+%{tx.critical_anomaly_score},\
    63          setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\
    64          setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}"

ルールエンジンをOnにしてみる

では、SecRuleEngine DetectionOnly を SecRuleEngine On にして、apacheの設定をreloadしてみます。 この状態で、curlで同じように ?q= といったリクエストしてみると...。

403 Forbiddenになりました。

vagrant@vagrant:~$ curl -I -v http://localhost:80/?q=%3Cscript%3E%3C/script%3E
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> HEAD /?q=%3Cscript%3E%3C/script%3E HTTP/1.1
> Host: localhost
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< Date: Sun, 12 Aug 2018 05:18:51 GMT
Date: Sun, 12 Aug 2018 05:18:51 GMT
< Server: Apache/2.4.29 (Ubuntu)
Server: Apache/2.4.29 (Ubuntu)
< Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=iso-8859-1

< 
* Connection #0 to host localhost left intact[f:id:akiko-pusu:20180813050113p:plain]

同じく、ブラウザからアクセスしてみても、403になることが分かりました。

f:id:akiko-pusu:20180813050113p:plain
forbidden

ハンズオンの設定をあててみる

さて、Ubuntuのmod_securityを有効化した場合、サンプル設定ではOWASPのCSRに従った強力な?(厳しい)定義が適用されています。 こちらを、ハンズオンでの設定に置き換えてみます。

具体的には、/etc/apache2/mods-enabled/ 以下の security2.conf を書き換える形で、apacheを再起動しました。

ハンズオンでのサンプル設定

SecRuleEngine On
SecRequestBodyAccess On

SecDefaultAction "phase:1,deny,log,status:403"


SecRule QUERY_STRING "zash11o" "id:'90000'"
SecRule QUERY_STRING "zash.*11o" "id:'90001'"

再起動後、上記のパターンにあるとおり、リクエストのQueryStringにzash11oというパラメータをつけてみたところ...。

vagrant@vagrant:/etc/apache2/mods-enabled$ curl -i localhost:80?q=zash11o
HTTP/1.1 403 Forbidden
Date: Sun, 12 Aug 2018 05:32:37 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Length: 284
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.<br />
</p>
<hr>
<address>Apache/2.4.29 (Ubuntu) Server at localhost Port 80</address>
</body></html>

期待通りに弾かれました!

audit.log側もこのような感じ。 ブラウザでも確かに403が返りました。

vagrant@vagrant:/etc/apache2/mods-enabled$ 
vagrant@vagrant:/etc/apache2/mods-enabled$ sudo tail -f /var/log/apache2/modsec_audit.log
Action: Intercepted (phase 2)
Stopwatch: 1534051341366134 7127 (- - -)
Stopwatch2: 1534051341366134 7127; combined=2252, p1=323, p2=1553, p3=0, p4=0, p5=375, sr=21, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.9.2 (http://www.modsecurity.org/); OWASP_CRS/3.0.2.
Server: Apache/2.4.29 (Ubuntu)
Engine-Mode: "ENABLED"

まとめ

...ということで、@柴雑種さまのハンズオン的な内容を、Ubuntuに対してざっと試しみました。 まだ適用した、という簡単な自習ではありますが、どこに何を設定して、なにがログに書き出されるかというのは、やってみるとなるほど、と思いました。

あらためて、お話ありがとうございました!!