Az - Storage Accounts & Blobs

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

기본 정보

Azure Storage Accounts는 바이너리 대형 객체(blobs), 파일, 큐, 테이블 등 다양한 데이터 유형에 대해 확장 가능하고 안전하며 높은 가용성을 제공하는 Microsoft Azure의 기본 서비스입니다. 이들은 단일 네임스페이스 아래에 여러 스토리지 서비스를 그룹화하여 관리하기 쉽게 해주는 컨테이너 역할을 합니다.

주요 구성 옵션:

  • 모든 storage account는 Azure 전역에서 유일한 이름을 가져야 합니다.
  • 모든 storage account는 리전 또는 Azure 확장 존에 배포됩니다.
  • 더 나은 성능을 위해 premium 버전의 storage account를 선택할 수 있습니다.
  • 랙, 드라이브 및 데이터센터 장애로부터 보호하기 위해 4가지 유형의 중복성 중에서 선택할 수 있습니다.

보안 구성 옵션:

  • Require secure transfer for REST API operations: storage와의 모든 통신에 TLS 요구
  • Allows enabling anonymous access on individual containers: 비활성화 상태이면 나중에 익명 접근을 활성화할 수 없음
  • Enable storage account key access: 비활성화 시 Shared Keys로 접근 금지
  • Minimum TLS version
  • Permitted scope for copy operations: 모든 storage account에서 허용, 같은 Entra tenant의 모든 storage account에서 허용 또는 같은 가상 네트워크에 있는 private endpoints가 있는 storage account에서 허용

Blob Storage 옵션:

  • Allow cross-tenant replication
  • Access tier: Hot(자주 접근하는 데이터), Cool 및 Cold(드물게 접근하는 데이터)

네트워킹 옵션:

  • Network access:
  • 모든 네트워크에서 허용
  • 선택된 가상 네트워크 및 IP 주소에서 허용
  • 공개 액세스 비활성화 후 private access 사용
  • Private endpoints: 가상 네트워크에서 storage account로의 프라이빗 연결 허용

데이터 보호 옵션:

  • Point-in-time restore for containers: 컨테이너를 이전 상태로 복원 허용
  • 이를 위해 versioning, change feed 및 blob soft delete가 활성화되어야 함.
  • Enable soft delete for blobs: 삭제된 blob(덮어써진 경우 포함)에 대한 일 단위 보존 기간을 설정
  • Enable soft delete for containers: 삭제된 컨테이너에 대한 일 단위 보존 기간을 설정
  • Enable soft delete for file shares: 삭제된 file share에 대한 일 단위 보존 기간을 설정
  • Enable versioning for blobs: blob의 이전 버전 유지
  • Enable blob change feed: blob 생성, 수정, 삭제 변경 로그 유지
  • Enable version-level immutability support: 계정 수준에서 모든 blob 버전에 적용될 시간 기반 보존 정책 설정 허용
  • version-level immutability support와 point-in-time restore for containers는 동시에 활성화될 수 없음.

암호화 구성 옵션:

  • Encryption type: Microsoft-managed keys(MMK) 또는 Customer-managed keys(CMK) 사용 가능
  • Enable infrastructure encryption: 데이터를 “추가로 암호화“하여 보안 강화 허용

Storage endpoints

스토리지 서비스엔드포인트
Blob storagehttps://<storage-account>.blob.core.windows.net

https://<stg-acc>.blob.core.windows.net/<container-name>?restype=container&comp=list
Data Lake Storagehttps://<storage-account>.dfs.core.windows.net
Azure Fileshttps://<storage-account>.file.core.windows.net
Queue storagehttps://<storage-account>.queue.core.windows.net
Table storagehttps://<storage-account>.table.core.windows.net

공개 노출

“Allow Blob public access“가 활성화된 경우(기본값은 비활성화), 컨테이너를 생성할 때 다음이 가능합니다:

  • public access to read blobs 허용(이름을 알아야 함).
  • 컨테이너의 blobs 목록 조회읽기 가능.
  • 완전히 private로 설정 가능.

Static website ($web) 노출 및 leaked secrets

  • Static websites는 지역별 엔드포인트(예: https://<account>.z13.web.core.windows.net/)를 통해 특수 $web 컨테이너에서 제공됩니다.
  • $web 컨테이너는 blob API를 통해 publicAccess: null을 보고할 수 있지만, 파일은 여전히 static site endpoint를 통해 접근 가능하므로 config/IaC 아티팩트를 그곳에 올리면 secrets가 leak될 수 있습니다.
  • 빠른 감사 워크플로:
# Identify storage accounts with static website hosting enabled
az storage blob service-properties show --account-name <acc-name> --auth-mode login
# Enumerate containers (including $web) and their public flags
az storage container list --account-name <acc-name> --auth-mode login
# List files served by the static site even when publicAccess is null
az storage blob list --container-name '$web' --account-name <acc-name> --auth-mode login
# Pull suspicious files directly (e.g., IaC tfvars containing secrets/SAS)
az storage blob download -c '$web' --name iac/terraform.tfvars --file /dev/stdout --account-name <acc-name> --auth-mode login

익명 blob 노출 감사

  • 데이터를 노출할 수 있는 storage accounts 찾기: az storage account list | jq -r '.[] | select(.properties.allowBlobPublicAccess==true) | .name'. allowBlobPublicAccessfalse이면 컨테이너를 public으로 전환할 수 없습니다.
  • 취약한 accounts 확인 — 플래그 및 기타 약한 설정 확인: az storage account show --name <acc> --query '{allow:properties.allowBlobPublicAccess, minTls:properties.minimumTlsVersion}'.
  • 플래그가 활성화된 경우 컨테이너 수준 노출 열거:
az storage container list --account-name <acc> \
--query '[].{name:name, access:properties.publicAccess}'
  • "Blob": 익명 읽기 허용 오직 blob 이름을 알 때만 (목록 불가).
  • "Container": 익명이 모든 blob에 대해 목록 + 읽기 가능.
  • null: 비공개; 인증 필요.
  • 접근 증명 자격 증명 없이:
  • 만약 publicAccessContainer이면, 익명 목록 조회가 가능합니다: curl "https://<acc>.blob.core.windows.net/<container>?restype=container&comp=list".
  • BlobContainer 둘 다, 이름을 알면 익명으로 blob을 다운로드할 수 있습니다:
az storage blob download -c <container> -n <blob> --account-name <acc> --file /dev/stdout
# or via raw HTTP
curl "https://<acc>.blob.core.windows.net/<container>/<blob>"

스토리지에 연결

연결할 수 있는 storage를 찾았다면 Microsoft Azure Storage Explorer 도구를 사용해 연결할 수 있습니다.

스토리지 접근

RBAC

Entra ID principals를 RBAC roles와 함께 사용해 스토리지 계정에 접근할 수 있으며, 권장되는 방법입니다.

Access Keys

스토리지 계정에는 접근에 사용할 수 있는 액세스 키가 있습니다. 이는 스토리지 계정에 대한 full access to the storage account.

Shared Keys & Lite Shared Keys

액세스 키로 서명된 generate Shared Keys를 생성하여 서명된 URL을 통해 특정 리소스에 대한 접근을 권한 부여할 수 있습니다.

Note

CanonicalizedResource 부분은 스토리지 서비스의 리소스(URI)를 나타냅니다. URL의 어떤 부분이 인코딩되어 있다면, CanonicalizedResource 내부에서도 동일하게 인코딩되어야 합니다.

Note

이는 기본적으로 요청 인증에 az cli에서 사용됩니다. Entra ID principal 자격 증명을 사용하려면 파라미터 --auth-mode login을 지정하세요.

  • 다음 정보를 서명하여 shared key for blob, queue and file services를 생성할 수 있습니다:
StringToSign = VERB + "\n" +
Content-Encoding + "\n" +
Content-Language + "\n" +
Content-Length + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
If-Modified-Since + "\n" +
If-Match + "\n" +
If-None-Match + "\n" +
If-Unmodified-Since + "\n" +
Range + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
  • 다음 정보를 서명하여 shared key for table services를 생성할 수 있습니다:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
  • 다음 정보를 서명하여 lite shared key for blob, queue and file services를 생성할 수 있습니다:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
  • 다음 정보를 서명하여 lite shared key for table services를 생성할 수 있습니다:
StringToSign = Date + "\n"
CanonicalizedResource

그런 다음 키를 사용하려면 Authorization 헤더에 다음 구문을 따라 넣으면 됩니다:

Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"
#e.g.
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=

PUT http://myaccount/mycontainer?restype=container&timeout=30 HTTP/1.1
x-ms-version: 2014-02-14
x-ms-date: Fri, 26 Jun 2015 23:39:12 GMT
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=
Content-Length: 0

공유 액세스 서명 (SAS)

Shared Access Signatures (SAS)는 계정의 액세스 키를 노출하지 않고 Azure Storage 계정의 리소스에 대한 특정 권한을 부여하는 보안적이고 시간 제한이 있는 URL입니다. 액세스 키는 모든 리소스에 대한 전체 관리자 액세스를 제공하는 반면, SAS는 읽기나 쓰기 같은 권한을 지정하고 만료 시간을 정의해 세분화된 제어를 허용합니다.

SAS Types

  • User delegation SAS: This is created from an Entra ID principal which will sign the SAS and delegate the permissions from the user to the SAS. It can only be used with blob and data lake storage (docs). It’s possible to revoke all generated user delegated SAS.
  • 사용자가 가진 것보다 “더 많은” 권한으로 delegation SAS를 생성할 수 있는 경우가 있습니다. 그러나 principal에게 해당 권한이 없으면 작동하지 않습니다 (no privesc).
  • Service SAS: This is signed using one of the storage account access keys. It can be used to grant access to specific resources in a single storage service. If the key is renewed, the SAS will stop working.
  • Account SAS: It’s also signed with one of the storage account access keys. It grants access to resources across a storage account services (Blob, Queue, Table, File) and can include service-level operations.

A SAS URL signed by an access key looks like this:

  • https://<container_name>.blob.core.windows.net/newcontainer?sp=r&st=2021-09-26T18:15:21Z&se=2021-10-27T02:14:21Z&spr=https&sv=2021-07-08&sr=c&sig=7S%2BZySOgy4aA3Dk0V1cJyTSIf1cW%2Fu3WFkhHV32%2B4PE%3D

A SAS URL signed as a user delegation looks like this:

  • https://<container_name>.blob.core.windows.net/testing-container?sp=r&st=2024-11-22T15:07:40Z&se=2024-11-22T23:07:40Z&skoid=d77c71a1-96e7-483d-bd51-bd753aa66e62&sktid=fdd066e1-ee37-49bc-b08f-d0e152119b04&skt=2024-11-22T15:07:40Z&ske=2024-11-22T23:07:40Z&sks=b&skv=2022-11-02&spr=https&sv=2022-11-02&sr=c&sig=7s5dJyeE6klUNRulUj9TNL0tMj2K7mtxyRc97xbYDqs%3D

Note some http params:

  • The se param indicates the expiration date of the SAS
  • The sp param indicates the permissions of the SAS
  • The sig is the signature validating the SAS

SAS permissions

When generating a SAS it’s needed to indicate the permissions that it should be granting. Depending on the objet the SAS is being generated over different permissions might be included. For example:

  • (a)dd, (c)reate, (d)elete, (e)xecute, (f)ilter_by_tags, (i)set_immutability_policy, (l)ist, (m)ove, (r)ead, (t)ag, (w)rite, (x)delete_previous_version, (y)permanent_delete

SFTP Support for Azure Blob Storage

Azure Blob Storage now supports the SSH File Transfer Protocol (SFTP), enabling secure file transfer and management directly to Blob Storage without requiring custom solutions or third-party products.

Key Features

  • Protocol Support: SFTP works with Blob Storage accounts configured with hierarchical namespace (HNS). This organizes blobs into directories and subdirectories for easier navigation.
  • Security: SFTP uses local user identities for authentication and does not integrate with RBAC or ABAC. Each local user can authenticate via:
  • Azure-generated passwords
  • Public-private SSH key pairs
  • Granular Permissions: Permissions such as Read, Write, Delete, and List can be assigned to local users for up to 100 containers.
  • Networking Considerations: SFTP connections are made through port 22. Azure supports network configurations like firewalls, private endpoints, or virtual networks to secure SFTP traffic.

Setup Requirements

  • Hierarchical Namespace: HNS must be enabled when creating the storage account.
  • Supported Encryption: Requires Microsoft Security Development Lifecycle (SDL)-approved cryptographic algorithms (e.g., rsa-sha2-256, ecdsa-sha2-nistp256).
  • SFTP Configuration:
  • Enable SFTP on the storage account.
  • Create local user identities with appropriate permissions.
  • Configure home directories for users to define their starting location within the container.

Permissions

권한기호설명
읽기r파일 내용 읽기.
쓰기w파일 업로드 및 디렉터리 생성.
목록l디렉터리 내용 나열.
삭제d파일 또는 디렉터리 삭제.
생성c파일 또는 디렉터리 생성.
소유권 수정o소유 사용자 또는 그룹 변경.
권한 수정p파일 또는 디렉터리의 ACL 변경.

Enumeration

az cli 열거 ```bash # Get storage accounts az storage account list #Get the account name from here

BLOB STORAGE

List containers

az storage container list –account-name

Check if public access is allowed

az storage container show-permission
–account-name
-n

Make a container public

az storage container set-permission
–public-access container
–account-name
-n

List blobs in a container

az storage blob list
–container-name
–account-name

Download blob

az storage blob download
–account-name
–container-name
–name
–file </path/to/local/file>

Create container policy

az storage container policy create
–account-name mystorageaccount
–container-name mycontainer
–name fullaccesspolicy
–permissions racwdl
–start 2023-11-22T00:00Z
–expiry 2024-11-22T00:00Z

QUEUE

az storage queue list –account-name az storage message peek –account-name –queue-name

ACCESS KEYS

az storage account keys list –account-name

Check key policies (expiration time?)

az storage account show -n –query “{KeyPolicy:keyPolicy}”

Once having the key, it’s possible to use it with the argument –account-key

Enum blobs with account key

az storage blob list
–container-name
–account-name
–account-key “ZrF40pkVKvWPUr[…]v7LZw==”

Download a file using an account key

az storage blob download
–account-name
–account-key “ZrF40pkVKvWPUr[…]v7LZw==”
–container-name
–name
–file </path/to/local/file>

Upload a file using an account key

az storage blob upload
–account-name
–account-key “ZrF40pkVKvWPUr[…]v7LZw==”
–container-name
–file </path/to/local/file>

SAS

List access policies

az storage <container|queue|share|table> policy list
–account-name
–container-name

Generate SAS with all permissions using an access key

az storage <container|queue|share|table|blob> generate-sas
–permissions acdefilmrtwxy
–expiry 2024-12-31T23:59:00Z
–account-name
-n

Generate SAS with all permissions using via user delegation

az storage <container|queue|share|table|blob> generate-sas
–permissions acdefilmrtwxy
–expiry 2024-12-31T23:59:00Z
–account-name
–as-user –auth-mode login
-n

Generate account SAS

az storage account generate-sas
–expiry 2024-12-31T23:59:00Z
–account-name
–services qt
–resource-types sco
–permissions acdfilrtuwxy

Use the returned SAS key with the param –sas-token

e.g.

az storage blob show
–account-name
–container-name
–sas-token ‘se=2024-12-31T23%3A59%3A00Z&sp=racwdxyltfmei&sv=2022-11-02&sr=c&sig=ym%2Bu%2BQp5qqrPotIK5/rrm7EMMxZRwF/hMWLfK1VWy6E%3D’
–name ‘asd.txt’

#Local-Users

List users

az storage account local-user list
–account-name
–resource-group

Get user

az storage account local-user show
–account-name
–resource-group
–name

List keys

az storage account local-user list
–account-name
–resource-group

</details>

{{#endtab }}

{{#tab name="Az PowerShell" }}

<details>
<summary>Az PowerShell enumeration</summary>
```powershell
# Get storage accounts
Get-AzStorageAccount | fl
# Get rules to access the storage account
Get-AzStorageAccount | select -ExpandProperty NetworkRuleSet
# Get IPs
(Get-AzStorageAccount | select -ExpandProperty NetworkRuleSet).IPRules
# Get containers of a storage account
Get-AzStorageContainer -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context
# Get blobs inside container
Get-AzStorageBlob -Container epbackup-planetary -Context (Get-AzStorageAccount -name <name> -ResourceGroupName <name>).context
# Get a blob from a container
Get-AzStorageBlobContent -Container <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context -Blob <blob_name> -Destination .\Desktop\filename.txt

# Create a Container Policy
New-AzStorageContainerStoredAccessPolicy `
-Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context `
-Container <container-name> `
-Policy <policy-name> `
-Permission racwdl `
-StartTime (Get-Date "2023-11-22T00:00Z") `
-ExpiryTime (Get-Date "2024-11-22T00:00Z")
#Get Container policy
Get-AzStorageContainerStoredAccessPolicy `
-Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context `
-Container "storageaccount1994container"

# Queue Management
Get-AzStorageQueue -Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context
(Get-AzStorageQueue -Name <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).Context).QueueClient.PeekMessage().Value

#Blob Container
Get-AzStorageBlob -Container <container-name> -Context $(Get-AzStorageAccount -name "teststorageaccount1998az" -ResourceGroupName "testStorageGroup").Context
Get-AzStorageBlobContent `
-Container <container-name> `
-Blob <blob-name> `
-Destination <local-path> `
-Context $(Get-AzStorageAccount -name "teststorageaccount1998az" -ResourceGroupName "testStorageGroup").Context

Set-AzStorageBlobContent `
-Container <container-name> `
-File <local-file-path> `
-Blob <blob-name> `
-Context $(Get-AzStorageAccount -name "teststorageaccount1998az" -ResourceGroupName "testStorageGroup").Context

# Shared Access Signatures (SAS)
Get-AzStorageContainerAcl `
-Container <container-name> `
-Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context

New-AzStorageBlobSASToken `
-Context $ctx `
-Container <container-name> `
-Blob <blob-name> `
-Permission racwdl `
-ExpiryTime (Get-Date "2024-12-31T23:59:00Z")

파일 공유

Az - File Shares

권한 상승

Az - Storage Privesc

사후 침해 활동

Az - Blob Storage Post Exploitation

지속성

Az - Storage Persistence

참고자료

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기