Lab: https://pwnedlabs.io/labs/azure-blob-container-to-initial-access

Scenario

Mega Big Tech have adopted a hybrid cloud architecture and continues to use a local on-premise Active Directory domain, as well as the Azure cloud. They are wary of being targeted due to their importance in the tech world, and have asked your team to assess the security of their infrastructure, including cloud services. An interesting URL has been found in some public documentation, and you are tasked with assessing it.

URL: https://mbtwebsite.blob.core.windows.net/$web/index.html


Enumerate domain name

Let’s start our enumeration on the domain megabigtech.com. I’ll be using AADInternals for this. If you have never used it, go ahead and install it:

Install-Module -Name AADInternals -Force -scope currentuser

We can use the Invoke-AADIntReconAsOutsider module to enumerate the domain. If you have no idea how to use a certain module in powershell, you can always use the Get-Help cmdlet.

Get-Help -Name Invoke-AADIntReconAsOutsider -Examples

Let’s use the first example on our target domain.

Invoke-AADIntReconAsOutsider -DomainName megabigtech.com | Format-Table

This domain is associated with a tenant, that indicates that is being hosted in Azure.

Troubleshoot

The Resolve-DnsName cmdlet is windows only. However, as you can see from the screenshots, I’m using pwsh for linux. There is a port of Resolve-DnsName for linux that you can install:
https://github.com/rhymeswithmogul/Resolve-DnsNameCrossPlatform

After installing, you’ll want to remove every instance of the -NoHostsFile flag used in AADInternals, as that flag is not supported by the port and will print out some errors.

Now for the Webapp enumeration

Check for DNS records with our newly installed tool.

Resolve-DnsName dev.megabigtech.com

There is a CNAME record pointing to mbtwebsite.blob.core.windows.net, which is a blob URL. A blob URL will always have this structure https://<storageAccountName>.blob.core.windows.net.

So we can conclude that this webapp is being served in a blob container called $web.

Enumerating the blob

We are going to enumerate the blob manually, but first I’d like to show you the automated way with AzSubEnum.

python3 azsubenum.py -b mbtwebsite -t 10 -p permutations.txt --blobsenum -bt 10

Flags:

-b BASE (storage account name)
-t Threads
-p Permutations file for storage account
--blobsenum (flag to enumerate blobs)
-bw Blob Wordlist (default is permutations file)
-bt Blob Threads

Thanks to Priest, this tool is now able to enumerate blobs as well and will print out their path. It also generates an .html file for better navigation or if you want to include the results in a report.

Manual enumeration

To check if the file is being served in a blob, you can make a request to it and see the headers it returns.

Invoke-WebRequest -Uri 'https://mbtwebsite.blob.core.windows.net/$web/index.html' -Method Head

In this case, we see the x-ms-blob-type: BlockBlob header in the response, confirming it is indeed a blob.

Listing the Blob Container:

To list a Blob Container, you can add the following parameters to the request: ?restype=container&comp=list.

https://mbtwebsite.blob.core.windows.net/$web?restype=container&comp=list&delimiter=%2F

The delimiter parameter is to filter blobs that have a /.

As you can see, nothing really interesting, only the static/ prefix. We are not stopping here, there is more stuff we can try.

Including versions

The include=versions parameter can be used to list the version of the blobs and some metadata. This will disclose every blob in this container alongside with it’s version (which we don’t really care, we just want the file name).

To use this parameter, we also have to include the header x-ms-version.

Using BurpSuite for this:

Some files are now appearing that weren’t showing before! That scripts-transfer.zip is especially interesting.

Downloading the Blob

Requesting the blob with the correct versionId:

Copy the VersionId that was included in the response for the file that we want to fetch and add it in the versionId parameter.

Download the zip and extract it:

Powershell files are always a good sign. Let’s see their contents:

And we find hard-coded credentials!

marcus@megabigtech.com
TheEagles12345!

marcus_adm
MegaBigTech123!

Connecting to Azure

To interact with Azure, I’m using Az Powershell. You can install it with:

Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force

Logging in as Marcus:

$Username = "marcus@megabigtech.com"
$Password = "TheEagles12345!" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ($Username, $Password)
Connect-AzAccount -Credential $Credential 

Achieved inital access. Let’s check the details for this account.

Get-AzADUser -SignedIn | fl

And we get the flag!