クラウドセキュリティエンジニアブログ

ニューリジェンセキュリティのクラウドセキュリティエンジニアチームが AWSなどのクラウドセキュリティについて気になることや調べたことを書くブログ

Amazon InspectorはAWS Lambda関数の何を検知しているのか?パターン別に検証してみた

こんにちは、クラウドセキュリティアーキテクトの大島悠司です。
先日のAWS re:Invent 2022で、「Amazon InspectorがLambda関数の診断をサポート」が発表されました。
私も普段からこの機能を使わせてもらっているのですが、意図的に脆弱なパッケージを入れても検知しないことがあり、気になったので調査してみました。

aws.amazon.com

以前の検証記事

devblog.nuligen.com

まずは結論から

長文のため、全部読むお時間が無い方のために結論を述べます。

Amazon Inspectorは、一般的なパッケージマネージャーのアーティファクトを使用して、AWS Lambda関数内のパッケージを診断します。
そのため、アーティファクトから外れたものは検知できません。

以下、パターン別の検証です。

(1)バージョンが古いレイヤーを追加する

以前の検証記事でもご紹介した、お手軽な検証方法です。

関数「test-vulnerabirity-lambda-1」を作成します。

ランタイムはpython3.8です。
以降の検証も全てランタイムpython3.8で実施しています。

AWSから提供されている、レイヤー「arn:aws:lambda:ap-northeast-1:249908578461:layer:AWSLambda-Python38-SciPy1x:109」を追加します。

1件のnumpyがInspectorにより検知されました。

関数「test-vulnerabirity-lambda-1」で、「CVE-2021-34141 - numpy」が検知されています。

ファイルパス「python/lib/python3.8/site-packages/numpy-1.21.3.dist-info/METADATA」を検知したようです。

(2)pipコマンドで取得

(1)でレイヤーを追加しましたが、検知されたものと同じバージョンのnumpyをpipコマンドで導入してみます。

関数「test-vulnerabirity-lambda-2」を作成します。

最初なので丁寧に解説します。
当該関数から、「アクション」→「関数のエクスポート」を押下します。

「デプロイパッケージのダウンロード」を押下します。

zipファイルを取得できるので、解凍します。
中身は、Lambda関数を作成したときにデフォルトで作成される「lambda_function.py」のみです。

lambda_function.py

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

pipコマンドが使える環境を用意し、(1)で検知されたものと同じバージョンのnumpyをダウンロードします。
4つのフォルダを取得できます。

$ pip3.7 install -t . numpy==1.21.3
Collecting numpy==1.21.3
  Downloading numpy-1.21.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (15.7 MB)
     |????????????????????????????????| 15.7 MB 321 kB/s
Installing collected packages: numpy
Successfully installed numpy-1.21.3
$ ls
bin  numpy  numpy-1.21.3.dist-info  numpy.libs

これを、先ほど関数「test-vulnerabirity-lambda-2」をエクスポートして解凍したフォルダに入れて、再度zip化します。

このzipファイルをLambda関数にアップロードします。
関数「test-vulnerabirity-lambda-2」から、「アップロード元」→「.zipファイル」を押下します。

「アップロード」から先ほど作成したzipファイルを選択し、保存します。

アップロードが完了しました。

numpyの検知数が2に増えています。

関数「test-vulnerabirity-lambda-2」で、「CVE-2021-34141 - numpy」が検知されています。

ファイルパス「numpy-1.21.3.dist-info/METADATA」を検知したようです。

このファイルはいったい何なのでしょうか。
エクスプローラーから探してみると、同じファイルがありました。

このファイルにはバージョンやライセンスなどの情報が書かれており、どうやらInspectorはこのファイルを見ていそうです。

METADATA

Metadata-Version: 2.1
Name: numpy
Version: 1.21.3
Summary: NumPy is the fundamental package for array computing with Python.
Home-page: https://www.numpy.org
Author: Travis E. Oliphant et al.
Maintainer: NumPy Developers
Maintainer-email: numpy-discussion@python.org
License: BSD
Download-URL: https://pypi.python.org/pypi/numpy
Project-URL: Bug Tracker, https://github.com/numpy/numpy/issues
Project-URL: Documentation, https://numpy.org/doc/1.21
Project-URL: Source Code, https://github.com/numpy/numpy
Platform: Windows
Platform: Linux
Platform: Solaris
Platform: Mac OS-X
Platform: Unix
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: C
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Operating System :: Unix
Classifier: Operating System :: MacOS
Requires-Python: >=3.7,<3.11

It provides:

- a powerful N-dimensional array object
- sophisticated (broadcasting) functions
- tools for integrating C/C++ and Fortran code
- useful linear algebra, Fourier transform, and random number capabilities
- and much more

Besides its obvious scientific uses, NumPy can also be used as an efficient
multi-dimensional container of generic data. Arbitrary data-types can be
defined. This allows NumPy to seamlessly and speedily integrate with a wide
variety of databases.

All NumPy wheels distributed on PyPI are BSD licensed.



(3)WindowsでWebサイトから取得

Windowsで開発する人は、Webサイトからパッケージをダウンロードしてくることもあると思います。
Webサイトから同パージョンのnumpyをダウンロードして、Lambdaに導入してみます。

関数「test-vulnerabirity-lambda-3」を作成します。

以下のWebサイトから、「numpy-1.21.3.zip」をダウンロードします。

pypi.org

zipを解凍すると以下のようにたくさんのファイルがあります。

(2)で実施したのと同様に、関数「test-vulnerabirity-lambda-3」をエクスポートして、解凍します。
そこに先ほどダウンロードしたファイルを一式入れて、再度zip化します。

このzipファイルを、関数「test-vulnerabirity-lambda-3」にアップロードします。

InspectorはLambda関数を認識していますが、検知数は変化しません。

pipコマンドで取得したものとフォルダ構成が異なるため、METADATAを検知できなかったと考えられます。

「(2)pipコマンドで取得」を深堀りする

(2)のpipコマンドで取得した場合はInspectorの検知に成功します。
そのため、pipコマンドで取得したパッケージを前提として、特定のファイルを見ているのではないかと予想できます。
そこで、他のパターンを試してみました。

(2-2)pipコマンドで取得&METADATAファイル名を変更

検知されたファイル名を変更してみます。
関数「test-vulnerabirity-lambda-2-2」を作成します。

METADATAをMETADATAtestと変更し、再度zip化してアップロードします。

検知数は変化なしです。

ファイル名が変更されると検知できなくなるようです。

(2-3)pipコマンドで取得&METADATAファイルパスを変更

検知されたファイルパスを変更してみます。
関数「test-vulnerabirity-lambda-2-3」を作成します。

METADATAを一つ上の階層に移動し、再度zip化してアップロードします。

検知数は変化なしです。

ファイルパスが変更されると検知できなくなるようです。

(2-4)pipコマンドで取得&METADATAファイルを削除

検知されたファイルパスを削除してみます。
関数「test-vulnerabirity-lambda-2-4」を作成します。

METADATA削除し、再度zip化してアップロードします。

検知数は変化なしです。

ファイルが削除されると検知できなくなるようです。

(2-5)pipコマンドで取得&METADATAファイルを書き換える

検知されたファイルのバージョンを書き換えてみます。
関数「test-vulnerabirity-lambda-2-5」を作成します。

METADATAのVersionを「1.21.3」から「1.21.0」に書き換えます。

書き換え前

Metadata-Version: 2.1
Name: numpy
Version: 1.21.3
Summary: NumPy is the fundamental package for array computing with Python.
Home-page: https://www.numpy.org
Author: Travis E. Oliphant et al.
(省略)

書き換え後

Metadata-Version: 2.1
Name: numpy
Version: 1.21.0
Summary: NumPy is the fundamental package for array computing with Python.
Home-page: https://www.numpy.org
Author: Travis E. Oliphant et al.
(省略)

再度zip化してアップロードします。

検知数が2から3に増えています。

関数「test-vulnerabirity-lambda-2-5」で、「CVE-2021-34141 - numpy」が検知されています。

ファイルパス「numpy-1.21.3.dist-info/METADATA」を検知したようです。

ここで、検知されたバージョンを見てみると、「 (2)pipコマンドで取得」では「numpy 1.21.3」として検知されていたのに対し、今回の「(2-5)pipコマンドで取得&METADATAファイルを書き換える」では「numpy 1.21.0」として検知されています。

「 (2)pipコマンドで取得」では「numpy 1.21.3」

「(2-5)pipコマンドで取得&METADATAファイルを書き換える」では「numpy 1.21.0」

numpyの場合は、METADATA内のバージョンを参照して、脆弱化否かを判断されていると考えられます。

まとめ

以上の検証をまとめると、以下の表のようになります。

Amazon Inspectorでnumpyを様々なパターンで診断させた場合

検証番号 Lambda名 条件 結果
(1) test-vulnerability-lambda-1 バージョンが古いレイヤーを追加する METADATAで検知
(2) test-vulnerability-lambda-2 pipコマンドで取得 METADATAで検知
(2-2) test-vulnerability-lambda-2-2 pipコマンドで取得&METADATAファイル名を変更 検知無し
(2-3) test-vulnerability-lambda-2-3 pipコマンドで取得&METADATAファイルパスを変更 検知無し
(2-4) test-vulnerability-lambda-2-4 pipコマンドで取得&METADATAファイルを削除 検知無し
(2-5) test-vulnerability-lambda-2-5 pipコマンドで取得&METADATAファイルを書き換える METADATAで書き換えたバージョンとして検知
(3) test-vulnerability-lambda-2-6 WindowsでWebサイトから取得 検知無し

仮説として、Amazon Inspectorはパッケージごとに特定のパスの特定のファイルを見ることで、脆弱か否かを診断しているものと考えられます。
おそらく、AWS側でそういったリストを所有しており、マッチングをかけているロジックのため、リストから外れるものは検知されないと考えられます。 また、コードはLambda関数作成時のデフォルトのものを使っており、importの定義はしていないので、importして実際に呼び出されている否かは関係ないようです。

ちなみに、この結果をもとにAWSサポートに問い合わせたところ、以下のような回答を頂きました。

  • Amazon Inspector は、一般的なパッケージマネージャーのアーティファクトを使用して、サードパーティのソフトウェアパッケージを識別する
  • パッケージマネージャーを使用せずに手動でインストールされたパッケージを検出できない
  • 各パッケージについて具体的にどのような情報・ファイルを確認しているかについては、内部情報のため公開できない

やはり仮説の通りでした。

結論として、Amazon Inspectorは、一般的なパッケージマネージャーのアーティファクトを使用して、AWS Lambda関数内のパッケージを診断しています。
そのため、特殊な方法でインストールしたパッケージは検知することができません。
このような特性を理解したうえでAmazon Inspectorを活用していければ良いと思います。