脆弱性体験学習ツール AppGoat

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/ef1ae72d-c758-44e6-9eff-aed842a7ce9e.png)
# 始め方
IPA公式に従って導入
https://www.ipa.go.jp/security/vuln/appgoat/toolabust.html
### 起動しない場合（主な原因は3つ）
#### ➀解凍していない
→解凍は必ずする
#### ➁他のプログラムがAppGoatのデフォルト設定のポート80、50001をすでに利用している。
以下の場合は、このケースである。
- ポート80番を他のアプリが使っていると、エラーが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/d705831f-74a8-4197-a439-bbd7de35ca05.png)
- 以下のコマンドを実行し、ポート80や50001がローカルで利用されている（XXXXは80や50001が入る）。
```
netstat -nao | find ":XXXX"
```
##### 解決策
- ポート80や50001を利用しているプログラムを終了させる
- AppGoat環境設定の画面でポート番号を80番から未使用のポート番号に変更および保存してからAppGoatを起動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/25bd2613-5ed3-4582-8b5b-33ca1e4f9560.png)
#### ➂AppGoatのパッケージに含まれているApache Webサーバが正しく起動してない。
- 以下のプロンプトが表示された状態のまま止まる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/d9521ca9-a339-4fbd-a75e-d38087ab8655.png)
- タスクバーにApacheのアイコン（赤い羽根）が新しく表示されていない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/44a5bf3f-0b77-4449-adae-73f111c9b60d.png)
##### 解決策
- AppGoatのパッケージに含まれているMicrosoft Visual C++再頒布可能パッケージをインストールした後、AppGoatを起動する。
`AppGoat展開フォルダ\IPATool\IPATool\Framework\Tools\vcredist_x86.exe`
# MEMO
- 編集中
# クロスサイトスクリプティング
### アンケートページの改ざん（反射型）
#### 手順1：【脆弱アンケートアプリケーション】で全項目を入力し、アンケート投稿を行います。
- 以下の画面遷移でアンケート投稿が行われることが分かった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/d4d436d7-77da-498a-b22f-d4270d6cd102.png)
#### 手順2：「脆弱性の発見手法」で学習した方法を使い、【脆弱アンケートアプリケーション】に存在する脆弱性のある箇所を探しましょう。脆弱性のある箇所がわからない場合はヒント1を参照しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/b351d9ca-73ac-4f13-b635-3ed7e2693a65.png)
- `'>"<hr>`を名前欄に入力して、アンケートを送信すると水平線が表示され、クロスサイトスクリプティングの脆弱性があることが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/a65f5dad-e0f9-4349-b8b8-91ba6e3424b9.png)
#### 手順3：罠のリンクを作るための事前準備として、罠のリンクのもとになるURLを確認しましょう。URLを確認できたら②で確認した脆弱性のある箇所に相当するパラメータを見つけましょう。URLやパラメータがわからない場合はヒント2を参照しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/7a811889-3248-4fac-ae3e-8c4c3dd63d0b.png)
- 手順1完了後のURLを確認する
- `name=%27%3E%22%3E%3Chr%3E`部分をURLデコードすると`name='>"<hr>`となる。意図しないHTMLタグを挿入できてしまっていることが分かる。
```
http://localhost/Users/_personal/Web/Scenario1121/VulSoft/enquete.php?page=2&name=%27%3E%22%3E%3Chr%3E&sex=0&old=21&company=&xss=1&trouble=1&content=aa
```
#### 手順4：【脆弱アンケートアプリケーション】の内容を書き換えるスクリプトを作成しましょう。スクリプトの作成はある程度のスキルが必要となるため、分からない場合はヒント3を参照しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/f5b2947a-dd94-4e1a-8168-b5c5f9954df2.png)
- 名前欄に`<script>document.getElementById("account").innerHTML='変更内容'</script>`を入力してアンケートを送信すると、アンケートの内容が書き換わっていることが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/1b9b653b-ac1f-4574-bd7f-fc9ba2df0e9c.png)
##### ※詳細に
- `$_GET`は、アクセスURLの ? 以降のクエリーストリングに含まれる情報（連想配列）。
- この場合は、以下の情報が収集される。
```
array(
    "name" => "<script>document.getElementById(\"account\").innerHTML='変更内容'</script>",
    "age" => "30",
    "sex" => "1"
    ・・・
)
```
- enquete.phpによると、`$_GET`で取得された情報は`Enqueteクラス`に渡される。
```enquete.php
$enquete = new Enquete($_GET);
$content = $enquete->check()->process()->get_content();
```
- `enquete.class.php`を見てみる。
- `base_enquete.class.php`を一度だけ実行して、親子関係を確立している。
- `base_enquete.class.php`は、アンケート処理の基本的なメソッドやプロパティをまとめているクラス（基底クラス）になっている。
- `enquete.class.php`は、これを継承していくつかの関数を実行する仕様になっている。
```enquete.class.php
<?php
require_once "Enquete/base_enquete.class.php";
```
- 引き続き、`enquete.class.php`を見てみる。
- `is_success() メソッド`が呼ばれる。
- `get_name()` は `$_GET['name']`を内部的に返している（つまり、`<script>document.getElementById(\"account\").innerHTML='変更内容'</script>`）。
- その name に `<script>～</script>` が含まれていれば 成功（XSS成立） と判定してる。
- `is_success()メソッド`は、XSSが成立したかどうかを確かめるメソッドの模様。
```enquete.class.php
public function is_success()
	{
		if (parent::get_page() == self::PAGE_CONFIRM) {
			/*課題の成功判定*/
			if (preg_match("/<script>.*<\/script>/i", parent::get_name())) {
				$this->set_content(array("success" => true));
			}
		}
		return $this;
	}
```
- 引き続き、`enquete.class.php`を見てみる。
- `get_error_name()メソッド`が呼ばれる。
- `$this->get_get();`は`base_enquete.class.php`から継承している関数。
- `get_get()関数`は、基本的に`$_GET配列`をそのまま返す関数である。
- `isset()関数`は、変数が定義されているかどうかを確認するための関数である。
-  `get_error_name()メソッド`は、`$_GET['name']`の値を安全に取得するメソッドの模様。
```enquete.class.php
	public function get_error_name()
	{
		// リクエストパラメータを取得
		$param = $this->get_get();
		// リクエストパラメータに名前がセットされている場合
		if (isset($param[parent::NAME])) {
			return $param[parent::NAME];
		// リクエストパラメータに名前がセットされていない場合
		} else {
			return "";
		}
	}
```
- また、`enquete.php`に戻る。
- PHP の Smarty テンプレートを利用していることが分かる。
```
$smarty->assign($messages);
$smarty->assign("content", $content);

$tpl_name =  $enquete->get_tpl_name();
if ($tpl_name != "enquete1.tpl") {
	$tpl_name = "../../../Common/Enquete/" . $tpl_name;
} else {
	$tpl_name = "enquete1121.tpl";
}
// テンプレート表示
$smarty->display($tpl_name);
```
- テンプレートファイルを見てみる。
- テンプレート内の「名前」欄の出力部分は、以下のようになっている。
```enquete1121.tpl
<div class="question"><input type="text" name="name" value="{$content.name}" /></div>
```
 - `{$content.name}` に含まれる文字列がエスケープされずにHTMLに埋め込まれる。
 - これは、`id="account"` の要素の中身が `変更内容` に書き換えられるスクリプトである。
```html
<div class="question">
<input type="text" name="name" value="<script>document.getElementById("account").innerHTML='変更内容'</script>" />
</div>
```
- `enquete1121.tpl`内を見てみると、`id="account"`は、元は `{$must}` が表示されるエリアであることが分かる（*マーク）。これが、`変更内容`という文字列に書き換えられることになる。
```html
	<div id="account">
		<span class="must">*</span>{$must}
	</div>
```
- 最終的に以下になり、画面が出力される。
```html
<div id="account">
  変更内容
</div>
```
#### 手順5：②③で確認した情報を参考に、④で作成したスクリプトを含む罠のリンクを作成し、【掲示板】に貼り付けましょう。罠のリンクがわからない場合はヒント4を参照しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/6162a30e-1663-4e9d-9975-40e08b4b9b42.png)
- どこにクロスサイトスクリプティングの脆弱性があるかを調べるために、`'>"<hr>`を全ての入力フィールドに入れて投稿してみる。
- URLが不正であると怒られる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/dc90afb2-b5e2-405e-b036-bc087eae534f.png)
- URL以外の入力フィールドに、`'>"<hr>`を入れて投稿してみる。
- クロスサイトスクリプティングの脆弱性はなさそう。
- ということは、URLの入力フィールドにクロスサイトスクリプティングの脆弱性があると推測できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/bc63a252-40d1-49c8-aec0-18d3b0512966.png)
- URLの入力フィールドにヒントのスクリプトを入れて投稿する。
- タイトル部分（い）がリンク化していることが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/2e88939b-4f21-4902-8474-3ef6909cf639.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/ab3dace3-428a-4f95-a07c-3a74bcc82c43.png)
#### 手順6：罠のリンクをクリックすることによって、内容が書き換えられた【脆弱アンケートアプリケーション】が表示されることを確認しましょう。
- 手順5で、リンクをクリックすると内容が書き換えられたアンケートが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668345/690a06ae-6482-4363-afe7-e6ce5cfc0152.png)