🤩

AWS DevOps Agent × OWASP Juice Shop:セキュリティインシデントをAIで調査するみたいなのやってみたい!

に公開

はじめに

AWS DevOps Agent触りたい!!!!!!!!!!

ということで、AWS公式が出してくれているテストシナリオをやりました。

https://docs.aws.amazon.com/ja_jp/devopsagent/latest/userguide/getting-started-with-aws-devops-agent-creating-a-test-environment.html

……

触り足りない!!!!!!!!!!

ということで、もう少し触りたいから、やられアプリをAWS上に構築してちょこちょこっと脆弱性つっつきたいなと思っていたところに以下の記事(本が正しい?)が目に留まりました。

https://zenn.dev/tsukamoto/books/f1e1d83931ca92

これだぁ!!!!!!!!!!

ということで、本題の「セキュリティインシデントをAIで調査するみたいなの」をやってみた話に入ります。

準備

やった準備は大きく分けて大体6つ。詳細は畳んでおくので気になる場合は展開してください。(といっても書いてあるとおりに進めるものばかりだけれども…)

  1. 「AWSハンズオンで考えるクラウドのセキュリティ」のChapter01をみながら、OWASP Juice ShopをAWS上に展開する。
詳細1

基本的に書いてある通り進めればOK!
私はOWASP Juice ShopのCloudFormation(CFn)スタックを作るより前に、Guard Dutyを有効化していたので、提供されているYAMLの該当箇所をコメントアウトして進めました。

該当箇所
  Detector:
    Type: "AWS::GuardDuty::Detector"
    Properties:
      Enable: true
      Features:
        - Name: S3_DATA_EVENTS
          Status: ENABLED
        - Name: EKS_AUDIT_LOGS
          Status: ENABLED
        - Name: EBS_MALWARE_PROTECTION
          Status: ENABLED
        - Name: RDS_LOGIN_EVENTS
          Status: ENABLED
        - AdditionalConfiguration:
            - Name: EKS_ADDON_MANAGEMENT
              Status: ENABLED
          Name: EKS_RUNTIME_MONITORING
          Status: ENABLED
        - Name: LAMBDA_NETWORK_LOGS
          Status: ENABLED
      FindingPublishingFrequency: FIFTEEN_MINUTES

ただ、これをやったせいかは定かじゃないんですが、最後スタックの削除でコケました。「AWSハンズオンで考えるクラウドのセキュリティ」にはスタックの削除について、注意点等はなかったため、多分これをやったせいだと思います。CFnで作成したサブネットの削除でコケるんですが、紐づいてるネットワークインターフェースか何かを消してあげれば消すことができます。記録を取らずに削除を進めてしまったので曖昧ですいません……

  1. AWS DevOps Agentのセットアップをする。
詳細2

Agent Spaceはデフォルトの設定値で作成しました。また、Slack連携も行い、調査結果がSlackでも確認できるよねというのも試しました。

  1. (好みで)AWS WAFやAWS Security Hubなどセキュリティ系サービスの設定する。
詳細3

そもそも「AWSハンズオンで考えるクラウドのセキュリティ」では、Guard Dutyによる振る舞いの検知と確認が入っていますが、それ以外にも個人的に使いたいセキュリティ系サービスとしてAWS WAFがあったので、CloudFrontを対象にWebACLをかけました。設定はこんな感じです。

アプリカテゴリ:その他
アプリケーションフォーカス:APIとウェブの両方
保護するリソース:CloudFrontのみ
初期の保護を選択:お客様のために推奨されるルール
デフォルトのルールアクション:すべてをCountアクションに設定
  1. 「AWSハンズオンで考えるクラウドのセキュリティ」のChapter02をみながら、OWASP Juice Shopをつついてみる。
詳細4

書いてある通りに進めました。特殊なことはしていません。

  1. 「AWSハンズオンで考えるクラウドのセキュリティ」のChapter03をみながら、OWASP Juice ShopがのっているEC2のロールの認証情報を取得する。
詳細5

書いてある通りに進めました。特殊なことはしていません。メモ帳などに逐一コピペしてコマンド作るみたいにすると楽です。

  1. 「AWSハンズオンで考えるクラウドのセキュリティ」のChapter04をみながら、Amazon S3格納ファイルを取得する。
詳細6

書いてある通りに進めました。特殊なことはしていません。メモ帳などに逐一コピペしてコマンド作るみたいにすると楽です。

本題

準備が終わったらやっと本題です。ちなみに今回はMitigation planの実行はしません、あくまでどこまで調査できるのかな~という好奇心のためのやってみた話なのでご了承ください。

そのいち:GuardDutyによる不審な振る舞いの検知

「AWSハンズオンで考えるクラウドのセキュリティ」のChapter05に書いてある通り、

Credentials for instance role {$StackName}-TheRole-xxxxxxxxxxxx were used from an external IP address.

というような検出結果が出たことを確認します。

そのに:DevOps Agentで調査開始

Guard Dutyで認証情報の窃取が確認できたら、DevOps Agentに調査を依頼しましょう。今回はどこまで調査できるのが気になったため、こちらからはほとんど情報を与えませんでした。

「Start an investigation」には以下の文章のみを渡して、「Start Investigation」を押した後も特に追加情報は入力せずに調査を開始します。

Guard Duty detected an instance role named 'juiceshop-test-TheRole-hEkzPqqxzRmz' accessing credentials from an external IP address. Please investigate.

DevOps Agentに投げたテキスト
DevOps Agentに投げたテキスト

そのさん:DevOps Agentの調査結果を確認

おおよそ10分強待つと、「Root Cause」が表示されました。

DevOps Agentの調査結果1
DevOps Agentの調査結果1

Root Cause(根本原因)を読んでみると、「AWSハンズオンで考えるクラウドのセキュリティ」のChapter03の解説に書いてある通りの原因に辿りつけたようです。

Root Cause 全文(リンク無効化のため編集有)
  1. EC2 instance configured with IMDSv1 enabled allowing metadata service exploitation
    The EC2 instance i-034091d9c7e4a6a73 has IMDSv1 enabled (MetadataOptions HttpTokens: 'optional') instead of requiring IMDSv2. IMDSv1 is vulnerable to SSRF attacks because it responds to simple HTTP GET requests without requiring session tokens. When an attacker exploits an SSRF vulnerability in the application, they can directly retrieve IAM credentials from http://169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/ without any additional authentication. IMDSv2 would have prevented this attack by requiring PUT requests with session tokens (HttpPutResponseHopLimit), making SSRF exploitation significantly more difficult. This configuration weakness is the root cause that enabled the credential exfiltration attack detected by GuardDuty.

また、Key findings(主な調査結果)として背景情報も述べられていました。

Key findings 全文(リンク無効化のため編集有)
  1. SSRF vulnerability in OWASP Juice Shop application enabled credential exfiltration
    The EC2 instance i-034091d9c7e4a6a73 is running OWASP Juice Shop, a deliberately vulnerable web application with known SSRF (Server-Side Request Forgery) vulnerabilities. An attacker exploited one of these SSRF vulnerabilities to trick the application into making HTTP requests to the EC2 instance metadata service at http://169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/juiceshop-test-TheRole-hEkzPqqxzRmz, allowing them to retrieve the temporary IAM role credentials. GuardDuty detected this credential exposure at 03:43:51Z. The application is publicly accessible through CloudFront (d1qwq54p8o4mgn.cloudfront.net) and an Application Load Balancer, providing the attack surface for the SSRF exploitation.

  2. Session revocation policy ineffective due to credential refresh capability
    The automated incident response system added a 'RevokeOldSessions' policy at 03:40:04Z that denies all actions for sessions issued before 03:18:12Z. However, this mitigation was ineffective because: (1) The EC2 instance obtained fresh credentials at 03:22:06Z - AFTER the revocation cutoff time - allowing it to continue normal operations with SSM and CloudFormation services. (2) The session revocation policy does not prevent the EC2 instance or an attacker who has already exfiltrated credentials from simply requesting new credentials from the metadata service. (3) Any attacker with access to the SSRF vulnerability can continue retrieving fresh credentials indefinitely as long as the instance is running and the instance profile is attached. This demonstrates a fundamental limitation of session revocation as a containment mechanism for metadata service credential theft - it only invalidates old sessions but cannot prevent new credential issuance to the compromised instance.

加えて、Investigation gaps(調査の空白)というものも記されていました。

DevOps Agentの調査結果2
DevOps Agentの調査結果2

Investigation gaps 全文
  1. GuardDuty finding details not accessible
    The hypothesis that GuardDuty detected SSRF-based credential exfiltration at 03:43:51Z could not be fully validated because access to the actual GuardDuty finding details (GetFindings API) was denied due to insufficient IAM permissions (guardduty:GetFindings not allowed). The finding details would have provided: (1) The specific external IP address that accessed the credentials, (2) The exact GuardDuty finding type (e.g., 'UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS'), (3) The detection mechanism used (VPC Flow Logs, DNS logs, etc.), (4) Additional context about the attack including geolocation and threat intelligence. With this data, we could definitively confirm whether the alert was triggered by SSRF exploitation of the metadata service versus other credential exposure mechanisms.

  2. Application and access logs not available for SSRF attack confirmation
    The hypothesis that an attacker exploited SSRF vulnerabilities in the Juice Shop application could not be directly confirmed because: (1) No CloudWatch log groups exist for the EC2 instance application logs, (2) ALB access logs are disabled (access_logs.s3.enabled: false), (3) CloudFront access logs were not checked, (4) WAF logs are stored in S3 bucket 'aws-waf-logs-xxxxxx' but S3 data plane access is not available through CloudTrail. These logs would have shown: HTTP requests with suspicious URL parameters attempting to access 169.254.169.254, injection patterns in query strings or POST bodies, the attacker's source IP address and user agent, timing of the SSRF attempts relative to the GuardDuty alert, and success/failure indicators. Without this data, we can only infer SSRF exploitation based on the combination of IMDSv1 configuration, known Juice Shop vulnerabilities, and GuardDuty detection of external credential access.

  3. VPC Flow Logs not accessible for network-level attack evidence
    VPC Flow Logs data was not accessible through CloudTrail LookupEvents API to analyze network traffic patterns from the EC2 instance (10.0.3.26 / 44.200.218.170) to the metadata service (169.254.169.254). Flow logs would have provided: (1) Direct evidence of HTTP connections from the application to the metadata service IP, (2) Timing and frequency of metadata service access attempts, (3) Volume of data transferred that could indicate credential retrieval, (4) Correlation with GuardDuty's detection timestamp, (5) Unusual traffic patterns compared to baseline behavior. This network-level evidence would have definitively proven SSRF exploitation of the metadata service rather than relying on inference from configuration weaknesses and GuardDuty alerts.

これは何かというと

「証拠(ログ)が見られないせいで、犯人がどうやって攻撃したのかを100%断定することができない」という調査の限界の報告

です。

DevOps Agentの権限が足りなかったり、そもそもの設定がなされていなかったり等で、調査が十分に行えなかった場合に出るもののようです。
AWSの公式ドキュメントにも以下のような記述がありました。

Investigation gaps are a list of things the agent wanted to introspect during its investigation but was unable to do so because it lacked necessary connectivity or permissions.

(おまけ)そのよん:Slack通知の確認

折角やるならSlack通知したいと思ったのでやりました。本題ではないので嬉しそうポイントをさくっと書きます。こうなってくれるとより嬉しいポイントは今のところ思い浮かばないです。

  • Agent SpaceのInvestigation timelineと同一の内容が流れてくるため、タイムラインに張り付いて確認しなくていい
  • ひとつの調査に対してひとつのスレッドが発行されるので、チャンネル内がごちゃごちゃしない
  • 調査結果のみならず、Mitigation planも同一のスレッドに流してくれる
  • 通知内容がSlackでの表示に最適化されている

DevOps AgentのSlack通知
DevOps AgentのSlack通知

(おまけ)そのご:Chat機能使ってみた

丁寧に調査してくれるのでChatで再実行の指示も必要ないけどなんか使ってみたいな~と思って、とりあえず調査結果のサマライズをお願いしました。AIなので当然っちゃ当然なんですが、しっかりと要約してくれました。綴り間違っててもちゃんと要約してくれてありがとう、DevOps Agentくん。

調査結果の要約全文(リンク無効化のため編集有)

Investigation Summary

Incident: GuardDuty detected IAM role juiceshop-test-TheRole-hEkzPqqxzRmz credentials being accessed from an external IP on 2026-01-02 at 03:43:51Z.

Root Causes

  1. SSRF Vulnerability in OWASP Juice Shop
    EC2 instance i-034091d9c7e4a6a73 runs OWASP Juice Shop, a deliberately vulnerable web application
    Attacker exploited SSRF vulnerabilities to trick the application into accessing the EC2 metadata service
    Retrieved IAM credentials from http://169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/
    Application is publicly accessible via CloudFront and Application Load Balancer

  2. IMDSv1 Enabled (Critical Configuration Weakness)
    Instance has IMDSv1 enabled (HttpTokens: optional) instead of requiring IMDSv2
    IMDSv1 responds to simple HTTP GET requests without authentication
    IMDSv2 would have prevented this attack by requiring PUT requests with session tokens

  3. Session Revocation Ineffective
    Automated response added RevokeOldSessions policy at 03:40:04Z (cutoff time: 03:18:12Z)
    However, instance obtained fresh credentials at 03:22:06Z - AFTER the revocation cutoff
    Session revocation cannot prevent new credential issuance from the metadata service
    Attacker can continuously refresh credentials via the SSRF vulnerability

Timeline

02:36:55Z - CloudFormation stack deployed vulnerable infrastructure
02:39:51Z - EC2 instance launched with IMDSv1 enabled
03:18:12Z - Session revocation cutoff time
03:22:06Z - Instance obtained fresh credentials (after revocation cutoff)
03:37:26Z - GuardDuty performed S3 bucket security investigation
03:40:04Z - Automated response added session revocation policy (ineffective)
03:43:51Z - GuardDuty alert triggered

Potential Impact
With exfiltrated credentials, attacker could:
Access, modify, or delete S3 bucket contents (juiceshop-test-thesecurebucket-geu1vj3kcymx)
Execute commands via SSM on the instance (if credentials still valid)
However, CloudTrail shows no unauthorized API calls from external IPs, suggesting credentials were exfiltrated but not yet weaponized

Investigation Gaps
GuardDuty finding details - Access denied to GetFindings API (missing external IP, finding type, detection mechanism)
Application logs - No CloudWatch logs for EC2 instance; ALB access logs disabled; WAF logs inaccessible
VPC Flow Logs - Not accessible to confirm network-level metadata service access

Mitigation Status
A mitigation plan has been generated to:
Terminate the compromised instance
Revoke all existing IAM role sessions
Enforce IMDSv2 on replacement instances via updated launch template

さいごに

「セキュリティインシデントをAIで調査するみたいなの」をやってみた話でした。
DevOps Agent触りたい欲がかなり満たされて満足しています。

また、丁寧に調査してくれて、どこかに明記されているわけではない情報もしっかり拾ってきてくれるところは、実際に業務で使うことを考えたときに頼れる相棒になってくれそうだなと思わせてくれました。

人生初の技術系記事なので至らぬ点がたくさんあったかと思いますが、ここまで読んでいただきありがとうございました!お気づきの点や質問等ありましたら、是非Xのほうまで連絡いただけたらと思います!!

Discussion