Hardening 2024 Convolutionsに向けてAyato Hardeningを開催した話

こんにちわ。<a href="https://www.z.fore-co.ltd/">株式会社フォアーゼット</a>にてペンテスターをしている<a href="https://twitter.com/AyatoShitomi">蔀</a>と申します。

今回はHardeningにおける、技術演習を通じたチームビルディングについて書きます。現在もHardening競技会に向けて準備を進めている方がたくさんいると思いますので、参考にしていただければ幸いです。

# Hardening競技会

自身は「Hardening競技会」という大会に出場できることとなりました。
Hardening競技会は、様々なサイバー攻撃を受けながらも自身のチームで経営するECサイトを８時間にわたり運営する、というロールプレイングゲームの競技会です。

システムのセキュリティを強固にしなくてはいけない反面、システム稼働やビジネスに影響を与えてはいけないという面白さがあり、競技会では毎年様々なドラマが繰り広げられます。

自身が初めて参加したハードニングの体験記があるので、併せてこちらもご覧ください。

https://qiita.com/labpixel/items/a2780ded7533405b02a5

チームは競技会への申し込み後、運営の方によって決定され初めましての方とチームになることが一般的です。１チーム１０人前後のチームで編成され、競技本番までの３か月をチーム一丸となって準備に勤しみます。

自身は参加が３回目ということもあり、積極的にチームを引っ張ろうと自負しております。

# チームビルディングでの演習における課題

「皆さん、初めまして」

私はHardeningのチームビルディングにおいて一番大切なのは「目線合わせ」だと感じております。

様々なバックグラウンドや職種の人が集まって１つのチームになっています。もちろん得意領域や苦手な領域がそれぞれのメンバーには存在します。しかしながら、幸運なことに、全員がHardening競技会への参加を前提に準備を進めています。

準備の中でインシデントレスポンスの演習などを行うことが多くありますが、ここで大切なのは**誰も取り残されないこと**だと考えております。コマンドラインやプログラミングの学習を進めるとチームとしての力は多少上がりますが、学習速度に関しては個人差があります。既に技術の分野で仕事をしている人に技術分野の初学者が追いつけるはずはありません。そのため、自身の設計する演習では、誰でもHardeningを体験することができることを意識しています。演習をこのような設計にすることで、チームとして競技当日にどのようなことが起こるのかを明確にし目線を併せることができます。

# Ayato Hardening

自身参加しているチームでは、チームビルディングとして「Ayato Hardening」と呼ばれる演習を実施しました。

https://github.com/ayato-shitomi/ayato-hardening

## ハイブリット開催

弊社のオフィスを利用し現地で演習に参加できる方は集まるという方針で、演習はハイブリットで開催しました。これにより、オンラインコミュニケーションではわかりずらい、各メンバー理解度の把握を鮮明に行うことができました。

## 演習の設計

先述にもある通り、演習での目的は「競技会ではどのようなことが起こるか」をチームの共通認識として目線を会わせることにあります。そのため以下のような形で演習を設計いたしいました。

- １セット４０分
- 同じ内容で２セット実施
- 途中に３０分の準備時間を設ける
- インシデントが発生したら報告を行う
- サイトが稼働していると１分ごとに加点（ベーススコア）
- 攻撃を防ぐと加点（アディショナルスコア）
- 参加者を２チームに分ける。１チームそれぞれ３人と４人

## 演習環境

サーバーはDockerで構築し、コンテナのOSは一般的なUbuntuを利用しました。

アカウントは初期で以下のアカウントが設置されています。

- root
- user1~11
- dev
- hardening

サービスは以下がインストールされています。

- vsftpd 2.3.4
- Python FLASK HTTP Server
- Apache2
- Open SSH

## 発生するインシデント（攻撃シナリオ）

攻撃は大きく４回発生します。

### ユーザーへのブルートフォース

デフォルトのユーザーへの攻撃が行われます。デフォルトでクレデンシャルは以下のように設定されているので、参加者は最初に変更することが必要です。

- root: root
- user1: user1
- user6: user6
- user11: pass

侵入された場合には、`sg`という不正なユーザーが作成され、WEBサーバーが停止してしまいます。

### vsftpdの脆弱性を利用した攻撃

続いて、vsftpdの脆弱性を利用した攻撃が行われます。

vsftpd 2.3.4ではユーザー名に`:)`が含まれるユーザーでログインした際に、6200番ポートで認証情報を必要とせずにコマンドを実行できるバックドアが起動するという脆弱性が存在しました。これはCVE-2011-2523と呼ばれる脆弱性です。

詳しくは以下の記事にて解説されています。

https://www.intellilink.co.jp/column/vulner/2011/070600.aspx

この脆弱性を利用されると、不正な`test`ユーザーが作成されます。参加者はファイアウォール等でFTPへのアクセスをできなくするかFTPサーバーを停止する必要があります。

### クレデンシャル情報の流出

続いて、WEBサーバーからのクレデンシャル情報流出が起こります。これはWEBサーバーにて誤って公開されているREADME.mdファイルにクレデンシャルが含まれていることに起因します。参加者はクレデンシャル情報が含まれるファイルを公開されるディレクトリから移動する必要があります。

### WEBアプリへの攻撃

最後にFlaskのSSTI（Server Side Template Inkection）でWEBアプリへの攻撃が行なわれます。Flaskではテンプレートをレンダリングする実装に不備があると、任意のコマンドが実行できることがあります。この脆弱性が悪用されるとWEBサーバーが停止してしまいます。

１回目のリクエストの攻撃が成功してしまうと、以下のようなリクエストで`whoami`が実行されます。

```
/app?name={{request.application.__globals__.__builtins__.__import__("os").popen("whoami").read()}}
```

２回目のリクエストの攻撃が成功してしまうと、以下のようなリクエストでサーバーが停止されてしまいます。

```
/app?name={{request.application.__globals__.__builtins__.__import__("os").popen("pkill -f 'python3 /var/www/html/webapp/app.py'").read()}}
```

いずれの脆弱性も、セキュリティの現場やHardening競技会でよくみられるものです。

## 堅牢MAX

攻撃を完全に対策するには以下のコマンドを利用します。

```bash
# 不要なユーザー削除
for i in {1..11}; do userdel -r user$i; done
userdel dev && userdel ubuntu && echo "root:toor" | chpasswd

# FTPの停止
pkill -f "/usr/local/sbin/vsftpd /etc/vsftpd.conf"

# READMEの削除
rm -rf /var/www/html/webapp/README.md && rm -rf /var/www/html/webapp/webapp/README.md && rm -rf /var/www/html/README.md

# WEBアプリの修正
sed -i 's/<h1>Welcome {}, your browser infomation<\/h1>/<h1>Welcome, your browser infomation<\/h1>/' /var/www/html/webapp/app.py
pkill -f "python3 /var/www/html/webapp/app.py" && python3 /var/www/html/webapp/app.py &>/dev/null &
```

## セットアップ

セットアップは特に難しくありません。Dockerがインストールされたマシン上で以下のコマンドを実行します。

```bash
# やられサーバーの起動
docker-compose up -d

# スコアボードの起動
python3 ./white-team/score.py

# スコアBOTの起動
python3 ./red-team/check.py
# 攻撃BOTの起動
python3 ./red-team/main.py
```

# 演習の流れと気が付いたこと

## 演習の流れ

|時刻|イベント|
|---|---|
|15:00|集合、Ayato Hardeningの説明|
|15:20～16:00|１セット目の競技|
|16:00～16:30|全体で観測した攻撃の確認と対処方法のすり合わせ|
|16:30～|２セット目準備開始|
|16:40～17:20|２セット目の競技|

最終的な結果といたしましては、以下のようになりました。

１セット目（チーム３はすべて守った場合のスコア）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/3968d67e-22c1-fc23-71af-4653631ac64f.png)

２セット目（チーム３はすべて守った場合のスコア）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/7e087637-338e-7ffb-0c7c-8d9af720efe2.png)

チームメンバーには実際のHardeningと同様に、「チームへの報告を行うこと」と「記録を残すこと」を意識してもらいました。具体的にはDiscordでチームメンバーへの周知を行うことと気が付いた点をDiscordに掲載することを行っていただきました。

![AA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/ff807918-9ea5-a343-a125-f1711843308a.png)

これにより、中間での「全体で観測した攻撃の確認と対処方法のすり合わせ」というのをスムーズ進められたと思います。中間でのすり合わせではMiroを用いて以下のようにチームごとに気が付きを共有しました。

![AAA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/7eda4e54-ac65-1d29-5239-f3878099f296.png)

結果としては**２セット目で両チームともすべての攻撃から防御ができました！**

## 思ったこと

実務でもHardening競技会においても現場において一番重要なのは、「自身がどこまで調べられたかの共有、方針の議論ができる」という点だと思います。

中間報告では、それぞれのチームから発見した脆弱性や対処法を発表するという形をとりました。これは先述した「自身がどこまで調べられたかの共有」と「方針の議論」をできるようにするということにつながると思います。初めて会うメンバーの中では共有や議論におけるハードルがいくつかあると思います。その中で競技を模した演習を行うことで全員が目線を合わせていることの再認識とともに共有や議論の大切さを認識できたと思います。

さらに、すべての攻撃に対して防御策を作りだせたことに関しても非常に良い経験になったのではないかと思います。

# まとめ

Hardening 2024 Convolutionsに向けてAyato Hardeningを開催したまとめといたしましては以下のようになると思います。

- チームの技術力を大きく上げることよりも、目線合わせとして技術の演習を行う
- 共有や議論ができるような簡単な共通スキームを作る
- 報告のフォーマットや当日の動きを確認するための演習を行う

Hardening本番まではちょうど１ヵ月となりました。引き続き頑張ります！