セキュリティ診断ツール "Dastardly" を WSL2 上で実行してみた

:::note info
[LIFULL Advent Calendar 2022](https://qiita.com/advent-calendar/2022/lifull) 23日目の記事です
:::

LIFULL に新卒入社し、もうすぐ4年目になるヒラノです。
普段はセキュリティエンジニアとして、セキュリティ/テスト自動化に関する推進、支援などを中心に取り組んでいます。

[15日目の記事](https://qiita.com/nk-ty/items/6a9bf6c12ef94499f4b8) では Dastardly を GitHub 上で動かしていましたが、今回はローカル（WSL2）上で動かしてみようと思います。

# What is Dastardly?

[Dastardly](https://portswigger.net/burp/dastardly) は、無料で利用できる CI/CD パイプライン用の Web アプリケーションセキュリティ診断ツールです。
開発元は Burp Suite でおなじみの PortSwigger で、重要な7つの脆弱性に関して10分以内で見つけることができます。

1. **Cross-site scripting (XSS) (reflected)**
2. **Cross-origin resource sharing (CORS) issues**
3. **Vulnerable JavaScript dependency**
4. **Content type is not specified**
5. **Multiple content types specified**
6. **HTML does not specify charset**
7. **Duplicate cookies set**

Jenkins, GitHub Actions, TeamCity といった有名な CI/CD プラットフォームが対応しています。
また、Docker を実行できる任意のプラットフォームでも動作します。

# WSL2 上で Dastardly を実行する

以降の手順は [公式ドキュメント](https://portswigger.net/burp/documentation/dastardly/generic) に沿って行います。

任意のプラットフォームで Dastardly を実行するには、以下のようなコマンドを入力します。

```bash
docker run --user $(id -u) --rm -v $(pwd):/dastardly -e \
DASTARDLY_TARGET_URL=https://ginandjuice.shop -e \
DASTARDLY_OUTPUT_FILE=/dastardly/dastardly-report.xml \
public.ecr.aws/portswigger/dastardly:latest
```

:::note info
`DASTARDLY_TARGET_URL` : 診断対象のURL
`DASTARDLY_OUTPUT_FILE` : 診断レポート（JUnit XML）の出力パス及びファイル名
:::

実行中は以下のような画面が表示され、最後に検出した脆弱性のタイプ及び重大度が表示されます。

```bash
2022-12-20 23:35:10 INFO  dastardly.StartDastardly - Using Java version 17.0.4
2022-12-20 23:35:11 INFO  bsee.BurpProcess.scan.scan-1 - Dec 20, 2022 11:35:11 PM java.util.prefs.FileSystemPreferences$1 run
2022-12-20 23:35:11 INFO  bsee.BurpProcess.scan.scan-1 - INFO: Created user preferences directory.
2022-12-20 23:35:15 INFO  bsee.BurpProcess.scan.scan-1 - 2022-12-20 11:35:15: REST API running on http://localhost:43539/
〜〜〜 中略 〜〜〜
2022-12-20 23:42:50 INFO  dastardly.EventLogPrinter - Dec 20 2022 23:42:48 INFORMATION Audit finished.
2022-12-20 23:42:50 ERROR dastardly.ScanFinishedHandler - Failing build as scanner identified issue(s) with severity higher than "INFO":
2022-12-20 23:42:50 ERROR dastardly.ScanFinishedHandler - Path: /catalog/search/2 Issue Type: Cross-site scripting (reflected) Severity: HIGH
2022-12-20 23:42:50 ERROR dastardly.ScanFinishedHandler - Path: /catalog/search/3 Issue Type: Cross-site scripting (reflected) Severity: HIGH
2022-12-20 23:42:50 ERROR dastardly.ScanFinishedHandler - Path: /catalog/search/4 Issue Type: Cross-site scripting (reflected) Severity: HIGH
2022-12-20 23:42:51 INFO  bsee.BurpProcess.scan.scan-1 - Deleting temporary files - please wait ... done.
```

最後に出力された XML を確認すると、検出したホスト名＆パス、脆弱性の詳細などより詳しい情報が分かります。

```xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<testsuites failures="4" name="Dastardly scan results - have a vulnerability-free day!" tests="50">
    <testsuite failures="0" name="https://ginandjuice.shop:443/" tests="1">
        <testcase name="No issues were identified"/>
    </testsuite>
    <testsuite failures="0" name="https://ginandjuice.shop:443/?search=699110" tests="1">
        <testcase name="No issues were identified"/>
    </testsuite>
    〜〜〜 中略 〜〜〜
    <testsuite failures="1" name="https://ginandjuice.shop:443/catalog/product-search-results/1" tests="1">
        <testcase name="Cross-site scripting (reflected)">
            <failure message="Cross-site scripting (reflected) found at https://ginandjuice.shop/catalog/product-search-results/1" type="Info"><![CDATA[
Severity: Info

Confidence: Certain

Host: https://ginandjuice.shop

Path: /catalog/product-search-results/1


Issue Detail
The value of the term request parameter is copied into the HTML document as plain text between tags. The payload e0wzf<script>alert(1)</script>yff6q was submitted in the term parameter. This input was echoed unmodified in the application's response.

This proof-of-concept attack demonstrates that it is possible to inject arbitrary JavaScript into the application's response.

The response does not state that the content type is HTML. The issue is only directly exploitable if a browser can be made to interpret the response as HTML. No modern browser will interpret the response as HTML. However, the issue might be indirectly exploitable if a client-side script processes the response and embeds it into an HTML context.

〜〜〜中略〜〜〜
</testsuites>
```

# 診断レポートを見やすくしてみる (JUnit XML → HTML)

ここからはおまけですが、JUnit XML のままだと視認性が悪いので HTML に変換してみようと思います。
変換するための手順は色々とあるらしいのですが、今回は Ian Norton さんが提供しているこちらのツールを利用します。

https://gitlab.com/inorton/junit2html

リポジトリをクローンし以下のコマンドを実行すると、HTML に変換され、次のように表示されます。
なお、`/path/to` 及び `/output/to` はご自身の環境に合わせてよしなに書き換えてください。

```bash
./junit2html /path/to/dastardly-report.xml /output/to/dastardly-report.html
```

![脆弱性情報](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323641/cbbab3a1-876d-b99e-d282-20551e513ec3.png)

# まとめ

本記事では、 CI/CD パイプライン用セキュリティ診断ツールである "Dastardly" を WSL2 上で動かしてみました。

実行した所感は以下の通りです。

- シフトレフトに繋がる
  - 10分以内に結果が分かるので、気軽に実行できる
  - 脆弱性の詳細も確認でき、早期修正ができる
- Dastardly のみで診断は十分かと言えば、そうではない
  - リリース前などでは、幅広い診断項目をカバーする他のツールでのテストが不可欠

Docker さえ動作する環境であれば実行できますので、開発時などに手元からちょっと診断してみるということが容易に実現できます（それこそ CI/CD プラットフォームでやればよいのでは、という話はさておき）。

ぜひ、みなさんも一度お試しを！