Snowflake Cortexで脆弱性情報から対策を立案させる

## 概要
今回は、公開されている脆弱性情報を元に、LLMを用いて対策立案を行います。

## 準備
今回利用したのは、NVDが公開しているAPIです。
データの取得方法については以下の記事が参考になるでしょう。

https://qiita.com/pbjpkas/items/5bd6082a0742121d2d4a#31-%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89

あるいは、[公式サイト](https://nvd.nist.gov/developers/vulnerabilities)を直接読んだ方が早いかもしれません。

Snowflake上で外部のAPIを利用する方法についても、[公式サイト](https://docs.snowflake.com/ja/developer-guide/external-network-access/external-network-access-examples)に記載があります。
少し癖はありますが、結局はPythonで関数を定義するだけです。
面倒であればステージからロードする、本記事にあるサンプルをコピーするなどしていただければと思います。

さて、APIからデータを取得できたら、テーブルに保存します。
大きめのJSONなので面食らうかもしれませんが、今回利用するフィールドには
```
res.vulnerabilities.cve.descriptions
```
などとアクセスできます。
ここだけをカラムに切り出して保存しておくとスムーズかもしれません。

## LLMの利用
ここからが本題になるわけですが、実はもう面倒な作業はありません。
というのも、SnowflakeにはSnowflake Cortexという備え付けの関数群があるからです。
つまり、後はこれらの関数に取得したデータを入力するだけです。

Snowflake Cortexについては、以前の記事

https://qiita.com/sdt-bizdev/items/b081113ea7e3c3f50285

や[公式サイト](https://docs.snowflake.com/ja/user-guide/snowflake-cortex/llm-functions)を参照していただくのが良いでしょう。

さて、ここでは簡略化のため、`descriptions`が直接カラムに保存してあるとします。
`descriptions`の中身は次のようになっています。
```JSON:CVE-2019-1010218.json
{
  "descriptions": [
    {
      "lang": "en",
      "value": "Cherokee Webserver Latest Cherokee Web server Upto Version 1.2.103 (Current stable) is affected by: Buffer Overflow - CWE-120. The impact is: Crash. The component is: Main cherokee command. The attack vector is: Overwrite argv[0] to an insane length with execl. The fixed version is: There's no fix yet."
    },
    {
      "lang": "es",
      "value": "El servidor web de Cherokee más reciente de Cherokee Webserver Hasta Versión 1.2.103 (estable actual) está afectado por: Desbordamiento de Búfer - CWE-120. El impacto es: Bloqueo. El componente es: Comando cherokee principal. El vector de ataque es: Sobrescribir argv[0] en una longitud no sana con execl. La versión corregida es: no hay ninguna solución aún."
    }
  ]
}
```
今回は `"en"` の `"value"` を利用していきます。



## 実験
例として、5つのCVEを利用しました。
先述した通り、以下のデータを元に試していただくこともできます。
```JSON:CVE-2020-24574.json
{
  "descriptions": [
    {
      "lang": "en",
      "value": "The client (aka GalaxyClientService.exe) in GOG GALAXY through 2.0.41 (as of 12:58 AM Eastern, 9/26/21) allows local privilege escalation from any authenticated user to SYSTEM by instructing the Windows service to execute arbitrary commands. This occurs because the attacker can inject a DLL into GalaxyClient.exe, defeating the TCP-based \"trusted client\" protection mechanism."
    }
  ]
}
```

```JSON:CVE-2001-0408.json
{
  "descriptions": [
    {
      "lang": "en",
      "value": "vim (aka gvim) processes VIM control codes that are embedded in a file, which could allow attackers to execute arbitrary commands when another user opens a file containing malicious VIM control codes."
    }
  ]
}
```

```JSON:CVE-2009-2730.json
{
  "descriptions": [
    {
      "lang": "en",
      "value": "libgnutls in GnuTLS before 2.8.2 does not properly handle a '\\0' character in a domain name in the subject's (1) Common Name (CN) or (2) Subject Alternative Name (SAN) field of an X.509 certificate, which allows man-in-the-middle attackers to spoof arbitrary SSL servers via a crafted certificate issued by a legitimate Certification Authority."
    }
  ]
}
```

```JSON:CVE-2017-0732.json
{
  "descriptions": [
    {
      "lang": "en",
      "value": "A elevation of privilege vulnerability in the Android media framework (libstagefright). Product: Android. Versions: 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2. Android ID: A-37504237."
    }
  ]
}
```

```JSON:CVE-2018-10307.json
{
  "descriptions": [
    {
      "lang": "en",
      "value": "error.php in ILIAS 5.2.x through 5.3.x before 5.3.4 allows XSS via the text of a PDO exception."
    }
  ]
}
```

### 翻訳
まずはシンプルに翻訳させてみます。
Snowflake Cortexには翻訳専用の関数 `TRANSLATE` がありますので、こちらを利用してみます。

```
SELECT SNOWFLAKE.CORTEX.TRANSLATE(
    descriptions[0].value, 'en', 'ja'
) FROM cve_json LIMIT 5;
```

この結果、CVE-2020-24574は次のように翻訳されました。
> GOG GALAXYのクライアント（GalaxyClientService.exe）が2.0.41まで（2021年9月26日午前12時58分東部標準時）で、Windowsサービスに任意のコマンドを実行するように指示することで、認証されたユーザーからSYSTEMへのローカル権限昇格を許可している。これは、攻撃者がGalaxyClient.exeにDLLを注入し、TCPベースの「信頼されたクライアント」保護メカニズムを回避することができるため発生します。

翻訳精度はそこそこですが、敬体と常体が混ざっているなど問題点もあります。
そこで、カスタマイズのできない `TRANSLATE` の代わりに `COMPLETE` という関数を利用してみます。

`COMPLETE` は、カスタマイズ性が高い代わりに自分でモデルを選択し、プロンプトを与える必要があります。

今回は以下のように実行しました。
```
SELECT SNOWFLAKE.CORTEX.COMPLETE(
    'mistral-large2',
        CONCAT('次の文章を翻訳してください: <text>', descriptions[0].value, '</text>')
) FROM cve_json LIMIT 5;
```
タグに関しては、[公式ドキュメント](https://docs.snowflake.com/ja/sql-reference/functions/complete-snowflake-cortex)で用いられていたものを真似て入れてみました。

さて、`TRANSLATE` と同様にCVE-2020-24574を翻訳させてみましょう。
>  GOG GALAXYのバージョン2.0.41（2021年9月26日午前12時58分、東部標準時点）までのクライアント（別名GalaxyClientService.exe）は、任意の認証されたユーザーがWindowsサービスに任意のコマンドを実行させることで、ローカル特権昇格を許可します。これは、攻撃者がGalaxyClient.exeにDLLを注入することで、TCPベースの「信頼されたクライアント」保護メカニズムを無効にするために発生します。

文体が敬体で統一されていますね。
翻訳自体の精度はそこまで変わらないように見えますが、こちらはプロンプト次第でさらにカスタマイズできるという強みがあります。
以下では全て `COMPLETE` を用いることにします。

### 対策立案
さて、翻訳自体はできたわけですが、これだけではあまり面白みがありません。
やはり、LLMを用いるからには何かを生成させてみたいところです。

そこで今回は、`descriptions` を元に対策を立案させてみることにします。
ですが、対策案が分かっても具体的な手順が分からなければ、結局自分で調べる必要が生じます。
ということで、今回は対策案に加えて、それに必要な手順まで出力させてみましょう。

以上を踏まえて出来上がったものがこちらです。
```
SELECT SNOWFLAKE.CORTEX.COMPLETE(
    'mistral-large2',
    CONCAT('以下の【入力】から、【出力】を生成してください。
    【出力】は【制約条件】を満たす必要があります。
    
    【入力】<text>', descriptions[0].value, '</text>
    【出力】
    ・【入力】に対し、有効と考えられる対策とその実行手順を出力する
    ・実行手順は、セキュリティ知識の乏しいユーザーを想定して分かりやすく説明する
    ・フォーマットは以下で、対策案同士は改行で分割する:
        Strategy 1. (対策案1の要約内容) / Tactics 1. (対策案1の実行手順)
        Strategy 2. (対策案2の要約内容) / Tactics 2. (対策案2の実行手順)
        ...
    【制約条件】
    ・箇条書きにすること
    ・結果のみを出力すること
    ・不要な改行、インデントは削除すること'
    )
) FROM cve_json LIMIT 5;
```
さて、CVE-2020-24574への対策案とその実行手順を見てみましょう。
>  Strategy 1. GOG GALAXYのアップデート / Tactics 1. GOG GALAXYを最新バージョンにアップデートする。以下の手順でアップデートを行ってください。1. GOG GALAXYを起動します。2. 画面右上の「設定」アイコンをクリックします。3. 「アップデートの確認」を選択し、最新バージョンがあればアップデートを実行します。

> Strategy 2. 不要なサービスの無効化 / Tactics 2. GalaxyClientService.exeを無効化する。以下の手順で無効化を行ってください。1. Windowsの「サービス」を開きます。2. 「GalaxyClientService」を見つけます。3. 右クリックして「停止」を選択し、次に「プロパティ」を開きます。4. 「スタートアップの種類」を「無効」に設定します。

> Strategy 3. アンチウイルスソフトのインストール / Tactics 3. 信頼できるアンチウイルスソフトをインストールし、定期的にスキャンを行う。以下の手順でインストールを行ってください。1. 信頼できるアンチウイルスソフトの公式サイトからダウンロードします。2. ダウンロードしたインストーラーを実行し、指示に従ってインストールします。3. インストール後、定期的にシステムスキャンを実行します。

サンプルのつもりで与えたプロンプトでしたが、存外しっかりした内容が返ってきましたね。
手順に関しても、しっかり箇条書きを使えています。
対策案自体は当たり前のことを言っているだけのようにも見えますが、この辺りはプロンプト次第でしょうか。

## まとめ
今回は Snowflake Cortexを使用しました。
1つのコマンドで即座にデータベースとLLMがつながるというのは魅力的ですね。
コストなど考慮すべき事項は他にもありますが、実用に足るだけのポテンシャルがあるのではないでしょうか。