LoginSignup
5
1

More than 3 years have passed since last update.

AWS Inspectorの評価内容をメール通知

Last updated at Posted at 2019-03-17

経緯

InspectorのWebコンソールにアクセスせずとも結果を見たい。
かつ通知は重要度が高のものに限定し大量の通知は避けたい。
標準では評価結果を通知することが出来ない為、lambdaで頑張ります。
※プログラミング素人の為、参考にさせて頂いた方とほぼ同じです。

Inspector

InspectorはEC2の脆弱性を評価し、結果をレポートにまとめてくれる素晴らしいサービスです。

公式
ブラックベルト

メールの通知に必要な3つのJSON

inspectorからSNS連携すればよいのかと思っていましたが、違いました。
検知された脆弱性の詳細を得るには3つのJSONファイルを順番に参照する必要があります。

  • 「実行完了」時に受信できるJSON
{
    "template": "arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:target/x-xxxxxxxx/template/x-xxxxxxxx",
    "findingsCount": "{arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:rulespackage/x-xxxxxxxxxx, arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:rulespackage/x-xxxxxxxxxx, arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:rulespackage/x-xxxxxxxxxx, arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:rulespackage/x-xxxxxxxxxx, arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:rulespackage/x-xxxxxxxxxx}",
    "run": "arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:target/x-xxxxxxxx/template/x-xxxxxxxx/run/x-xxxxxxxx",
    "event": "ASSESSMENT_RUN_COMPLETED",
    "target": "arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:target/x-xxxxxxxx"
}
  • 上記のrunに記載されてあるArnから拾える「評価結果」一覧
    ※検知された脆弱性の数で以下arnの件数は増減します。
{
    "findingArns": [
        "arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:target/x-xxxxxxxx/template/x-xxxxxxxx/run/x-xxxxxxxx/finding/x-xxxxxxxx",
        "arn:aws:inspector:ap-northeast-1:xxxxxxxxxxxx:target/x-xxxxxxxx/template/x-xxxxxxxx/run/x-xxxxxxxx/finding/x-xxxxxxxx",
    ]
}
  • 「評価結果」のArnから拾える脆弱性の詳細

{
    "findings": [
        {
            "assetType": "ec2-instance",
            "confidence": 10,
            "numericSeverity": 9.0,
            "description": "During key agreement in a TLS handshake using a DH(E) based ciphersuite a malicious server can send a very large prime value to the client. This will cause the client to spend an unreasonably long period of time generating a key for this prime resulting in a hang until the client has finished. This could be exploited in a Denial Of Service attack. Fixed in OpenSSL 1.1.0i-dev (Affected 1.1.0-1.1.0h). Fixed in OpenSSL 1.0.2p-dev (Affected 1.0.2-1.0.2o).",
            "service": "Inspector",
            "title": "Instance i-xxxxxxxxxxxxxxxxx is vulnerable to CVE-2018-0732",
            "assetAttributes": {
                "amiId": "ami-xxxxxxxxxxxxxxxxx",
                "hostname": "ec2-xx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
            },
            "recommendation": "Use your Operating System's update feature to update package openssl-1:1.0.2k-12.amzn2.0.3, openssl-libs-1:1.0.2k-12.amzn2.0.3. For more information see [https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732)",
            "id": "CVE-2018-0732",
            "severity": "High"
        }
    ]
}

Lambda(Python3.6)


import json
import boto3

TOPIC_ARN = 'SNSトピックのArn'

def mail(subject, msg):

    client = boto3.client('sns')

    request = {
        'TopicArn': TOPIC_ARN,
        'Message': msg,
        'Subject': subject
    }

    response = client.publish(**request)
    return response


# 評価結果
def get_findingArns(assessmentRunArn):
    client = boto3.client('inspector')

    findingArns = []
    nextToken = ""

    while(True):
        if(nextToken != ""):
            response = client.list_findings(
                assessmentRunArns=[
                    assessmentRunArn,
                ],
                maxResults=500,
                nextToken=nextToken
            )
        else:
            response = client.list_findings(
                assessmentRunArns=[
                    assessmentRunArn,
                ],
                maxResults=500
            )

        if("nextToken" not in response):
            for arn in response["findingArns"]:
                findingArns.append(arn)
            break
        else:
            for arn in response["findingArns"]:
                findingArns.append(arn)
            nextToken = response["nextToken"]

    return findingArns


# main
def lambda_handler(event, context):

    try:
        client = boto3.client('inspector')

        # RunArn
        obj = event["Records"][0]["Sns"]["Message"]
        obj = json.loads(obj)
        assessmentRunArn = obj["run"]
        assessmentTemplateArn = assessmentRunArn.rsplit("/", 2)[0]

        # findingArns
        findingArns = get_findingArns(assessmentRunArn)
        size = 100
        output = ""
        describe_findings = []
        findingArns_split = [findingArns[x:x + size] for x in range(0, len(findingArns), size)]
        for findingArns_100 in findingArns_split:
            describe_findings = describe_findings + client.describe_findings(findingArns=findingArns_100, locale='EN_US')["findings"]
        # 脆弱性の詳細内の"severity" = "High"である条件に合致した内容から以下の項目抜粋
        for finding in describe_findings:
            if finding["severity"] == "High": 
                title = finding["title"]
                amiId = finding["assetAttributes"]["amiId"]
                ec2name = finding["assetAttributes"]["hostname"]
                cveid = finding["id"]
                severity = finding["severity"]
                recommendation = finding["recommendation"]

                output = output + '【' + str(title) + '】' + \
                    '\n ami Id :' + str(amiId) + \
                    '\n ec2 name :' + str(ec2name) + \
                    '\n vulnerability id :' + str(cveid) + \
                    '\n severity :' + str(severity) + \
                    '\n recommendation :' + str(recommendation) + \
                    '\n inspector arn :' + finding["arn"] + '\n \n'
            else:
                pass

        # アラート
        if(output != ""):
            mail('Inspector alert', output)
        else:
            output = "Nothing to alert."
            mail('Inspector alert', output)

        return output

    except:
        import traceback
        output = traceback.format_exc()
        mail('Inspector error', output + "\n\n" + json.dumps(event, indent=4))
        return output

Lambdaの必要なPolicy

  • AmazonInspectorReadOnlyAccess
  • "sns:Publish"

通知内容

image.png

まとめ

当初SNS連携では詳細が得られなかった為、無理なのだと思いましたが、
様々な方のナレッジのお陰で実装することができました。
内容は薄いですが、誰かの参考になれば幸いです。

参考リンク

Inspectorの実行結果をCSVファイルとして出力する
Amazon Inspector の評価結果詳細を自動通知できるか調べてみた
Amazon Inspectorの脆弱性診断結果の差分を通知する

5
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1