Skip to content

SSHenanigans⚓︎

Difficulty:
Direct link: Objective5.zip

In CAs We Trust⚓︎

image

Objective⚓︎

Request

Go to Pixel Island and review Alabaster Snowball's new SSH certificate configuration and Azure Function App. What type of cookie cache is Alabaster planning to implement?

Alabaster Snowball

Hello there! Alabaster Snowball at your service.

I could use your help with my fancy new Azure server at [ssh-server-vm.santaworkshopgeeseislands.org].

ChatNPT suggested I upgrade the host to use SSH certificates, such a great idea!

It even generated ready-to-deploy code for an Azure Function App so elves can request their own certificates. What a timesaver!

I'm a little wary though. I'd appreciate it if you could take a peek and confirm everything's secure before I deploy this configuration to all the Geese Islands servers.

Generate yourself a certificate and use the monitor account to access the host. See if you can grab my TODO list.

Hints⚓︎

SSH Certificates Talk

Check out Thomas Bouve's talk and demo to learn all about how you can upgrade your SSH server configuration to leverage SSH certificates.

Azure Function App Source Code

The get-source-control Azure REST API endpoint provides details about where an Azure Web App or Function App is deployed from.

Solution⚓︎

Getting Certified⚓︎

First, let's visit the Azure Function App Alabaster mentioned.

sshCertWebsite

It looks like we will need to generate an SSH key in order to get a certificate:

ssh-keygen -C 'holidayhackchallenge 2023' -f hhc_key

Result
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in hhc_key
Your public key has been saved in hhc_key.pub
The key fingerprint is:
SHA256:plvgP1Oa0V1RP/lxNCvqOG663PhY9TyzUIVeU7t6F4k holidayhackchallenge 2023
The key's randomart image is:`
+---[RSA 3072]----+
|               o+|
|              o.B|
|             o @o|
|            o * O|
|      . S. + E +.|
|     . +. * = . .|
|      o .O o * ..|
|      .+@.. . = .|
|      .***   .   |
+----[SHA256]-----+

ls                 
hhc_key.pub      hhc_key 

cat hhc_key.pub  
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCrONw9duytYH0SSLZoOtW1ya0gFW+7JIDX6OlrfUl3mE1/9qs2pqXrxmX6cahTLo7hH/vdO6TKLR4agbDnbpKsoJosNGO251iGMl+BeCjtELedz3c2oRlsApFfW10cB9CBUCtsxUvmWeyZidnQBsJPXm8QaRjSjyROhjijmxprg7jrE6vpu1AmSgfgh4GaSAbBTSDo5yw12IvPQkp8K6O2KSpeAJkCc9Y9qlp3aFEXDspsCj4tUNuwBdUPm1IijsnYUrKoCPpf1fjV1QAAjntaZpHf/Kg9yPiY2F3XCyCokzpH6nO+iy2dezBpESso06L9ucKJkx8OGWkYeSWV5U/wvKvZfak6oGt/MyPbLzK2knAVIHWgADLT0TdQcSy9MVQND/v3/yysj6qbtZIa4Y+zpscN6ogfQWFSUqp0OQd5jkSBSnEloB0jIv3CdwFJY5JMatv7ZXG8c0uAlid4zj7gKSvBfDIFRJyzUl7x83U9x/cbgIZVBVFtWTCF/8Pogq8= holidayhackchallenge 2023

Now when we go to the website Alabaster mentioned, we can plug in the public key form our hhc_key.pub so the website will give us a certificate.

requestCert

Copy the entirety of the cert into a file labeled hhc_elf-cert and then grab the key from the cert and paste that into to a file named hhc_elf-key.

hhc_elf-key
rsa-sha2-512-cert-v01@openssh.com AAAAIXJzYS1zaGEyLTUxMi1jZXJ0LXYwMUBvcGVuc3NoLmNvbQAAACczMTAyMTg1Mjg1MDkxNTcxMTQ0OTI2NTE5NTAwMzY3OTAzNDkwMzkAAAADAQABAAABgQCrONw9duytYH0SSLZoOtW1ya0gFW+7JIDX6OlrfUl3mE1/9qs2pqXrxmX6cahTLo7hH/vdO6TKLR4agbDnbpKsoJosNGO251iGMl+BeCjtELedz3c2oRlsApFfW10cB9CBUCtsxUvmWeyZidnQBsJPXm8QaRjSjyROhjijmxprg7jrE6vpu1AmSgfgh4GaSAbBTSDo5yw12IvPQkp8K6O2KSpeAJkCc9Y9qlp3aFEXDspsCj4tUNuwBdUPm1IijsnYUrKoCPpf1fjV1QAAjntaZpHf/Kg9yPiY2F3XCyCokzpH6nO+iy2dezBpESso06L9ucKJkx8OGWkYeSWV5U/wvKvZfak6oGt/MyPbLzK2knAVIHWgADLT0TdQcSy9MVQND/v3/yysj6qbtZIa4Y+zpscN6ogfQWFSUqp0OQd5jkSBSnEloB0jIv3CdwFJY5JMatv7ZXG8c0uAlid4zj7gKSvBfDIFRJyzUl7x83U9x/cbgIZVBVFtWTCF/8Pogq8AAAAAAAAAAQAAAAEAAAAkZjM3Y2M2Y2ItODdiZS00OWZhLTg5ZTgtODU4MzUxMzViMThjAAAABwAAAANlbGYAAAAAZabLJAAAAABly7ZQAAAAAAAAABIAAAAKcGVybWl0LXB0eQAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBpNhjTApiZFzyRx0UB/fkzOAka7Kv+wS9MKfj+qwiFhwAAAFMAAAALc3NoLWVkMjU1MTkAAABAYMSI5tYm5+e80x+IBmRNYIgK9ZAECp0sK3BelB/fl7JS5O9twHK6ch6gOdtiwzTVicOszoietK8yesaARcIOAQ==
ssh monitor@ssh-server-vm.santaworkshopgeeseislands.org -i ~/.ssh/hhc_key ~/.ssh/hhc_elf-key

Recon⚓︎

Upon login, we are dropped into a running program, but we can CTRL+C out of this to explore the host that we are logged into as the monitor user.

Explore the ssh folder⚓︎

cd /etc/ssh
ls -la
(This allows us to see if any permissions for private keys might be misconfigured or overly permissive. Looks like they're set up correctly.)
cd auth_principals

cat alabaster
Alabaster's assigned principal is admin.
cat monitor
Monitor, as seen from the website's output, is assigned the elf principal.

So how do we change the principal name for a signed certificate?

IMDS & APIs for Azure⚓︎

Now might be a good time to look at the other information contained in the Hints for this objective. One, included an API documentation website. At the top of the page, we get a better idea of the types of information we will need in order to use REST APIs.

GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web?api-version=2022-03-01
Let's get some baseline information from ChatGPT to familiarize ourselves with what APIs and REST APIs if we aren't familiar.

ChatGPT

APIs (Application Programming Interfaces)⚓︎

An API is a set of rules and definitions that allows different software applications to communicate with each other. It defines the methods and data formats that applications can use to communicate. APIs are used to enable the integration between different systems and platforms.

REST APIs (Representational State Transfer APIs)⚓︎

REST APIs are a specific type of API that adhere to the architectural style and constraints of REST, which is a set of principles for designing networked applications. They use HTTP requests to access and manipulate data.

Key Characteristics of REST APIs include:

  1. Stateless: Each request from a client to a server must contain all the information needed to understand and complete the request. The server does not store any session state about the client.

  2. Client-Server Architecture: REST applications have a client-server architecture where the client and the server are independent, allowing each to evolve separately.

  3. Cacheable: Responses must be defined as cacheable or not to improve client-side performance.

  4. Uniform Interface: REST APIs use a standard interface, which simplifies and decouples the architecture.

  5. Layered System: A client cannot ordinarily tell whether it is connected directly to the end server or to an intermediary along the way.

  6. Code on Demand (Optional): Servers can temporarily extend or customize the functionality of a client by transferring executable code.

REST APIs vs Traditional APIs⚓︎

  1. Communication Protocol: While traditional APIs can use any protocol for communication (like SOAP over HTTP, TCP, SMTP, etc.), REST APIs specifically use HTTP/HTTPS protocols.

  2. Data Formats: REST APIs typically use JSON (JavaScript Object Notation) for data interchange, but they can also use other formats like XML. Traditional APIs might use a wider range of formats, including XML, JSON, or even binary formats.

  3. Statelessness: REST APIs are stateless, meaning the server does not need to remember the client’s state. In contrast, other types of APIs might maintain state.

  4. Ease of Use: REST APIs are generally considered easier to understand and implement compared to other types of web services, like SOAP (Simple Object Access Protocol), which has more stringent standards and requires a SOAP header.

  5. Performance: REST APIs can be faster and use less bandwidth. They're often more suitable for internet use due to their stateless nature and the ability to cache requests.

Use Cases of REST APIs⚓︎

REST APIs are widely used in web services and are the backbone of many web applications. They are used for:

  • Web and mobile applications to communicate with backend servers.
  • Integration between different systems, like connecting a customer relationship management (CRM) system with an email marketing platform.
  • Cloud services, where they allow different services to communicate and share data.
  • IoT (Internet of Things) applications for device communication.

REST APIs have

become the standard for designing web-based APIs due to their simplicity, scalability, and compatibility with web technologies. They enable diverse applications, regardless of their underlying technology or platform, to communicate and exchange data efficiently.

It looks like based on the website, we'll need a couple of items of info before we can use APIs to interact with our cloud environment. Specifically, subscriptionID and resourceGroupName.

Well, first let's see what we can find through IMDS:

curl -s -w '\n' -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01&resource=https://management.azure.com/" | jq

This provides us with the:
"subscriptionId": "2b0942f3-9bca-484b-a508-abdae2db5e64"
"resourceGroupName": "northpole-rg1"

We can fill in our subscription ID and resource group name from our IMDS query and the name of the site is the subdomain information listed in the URL:
northpole-ssh-certs-fa

But in order to run this command, we need a token that shows we are trusted and we establish this by requesting one from a host that's connected to the cloud environment through IMDS:

curl -s -w '\n' -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2023-07-01&resource=https://management.azure.com/" | jq

The Token (this might be worth saving to a variable)

bash eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzkwYTM4ZWRhLTQwMDYtNGRkNS05MjRjLTZjYTU1Y2FjYzE0ZC8iLCJpYXQiOjE3MDUzNjMzNjQsIm5iZiI6MTcwNTM2MzM2NCwiZXhwIjoxNzA1NDUwMDY0LCJhaW8iOiJFMlZnWUlnNG1QTG1WWDdlcTJ1Ly9LdzB4Vk5xQUE9PSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsImlkdHlwIjoiYXBwIiwib2lkIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwicmgiOiIwLkFGRUEybzZqa0FaQTFVMlNUR3lsWEt6QlRVWklmM2tBdXRkUHVrUGF3ZmoyTUJQUUFBQS4iLCJzdWIiOiI2MDBhM2JjOC03ZTJjLTQ0ZTUtOGEyNy0xOGMzZWI5NjMwNjAiLCJ0aWQiOiI5MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQiLCJ1dGkiOiJkRUNmLWRVcTJrNlVqcmk0YUpqQkFRIiwidmVyIjoiMS4wIiwieG1zX2F6X3JpZCI6Ii9zdWJzY3JpcHRpb25zLzJiMDk0MmYzLTliY2EtNDg0Yi1hNTA4LWFiZGFlMmRiNWU2NC9yZXNvdXJjZWdyb3Vwcy9ub3J0aHBvbGUtcmcxL3Byb3ZpZGVycy9NaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXMvc3NoLXNlcnZlci12bSIsInhtc19jYWUiOiIxIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvMmIwOTQyZjMtOWJjYS00ODRiLWE1MDgtYWJkYWUyZGI1ZTY0L3Jlc291cmNlZ3JvdXBzL25vcnRocG9sZS1yZzEvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VkSWRlbnRpdHkvdXNlckFzc2lnbmVkSWRlbnRpdGllcy9ub3J0aHBvbGUtc3NoLXNlcnZlci1pZGVudGl0eSIsInhtc190Y2R0IjoxNjk4NDE3NTU3fQ.Ru-4SIML35NxS73f6akEeF70kjrf8TiOHzkLHjNgwIDkh8PVq4KbqaRVtuoy5Brrqp3_qrY5aqwiTzC1kE2dhzcqAwdJlWSJ7l2EwGlMIdxHDQHz6k8fheePQaiMmjM_X1n6Rcbs4_DCbQIF0qLm1s9go_55OLVvLOWxKbXBqkw-pXGigAgIfPoFDfaCG-qPDT49Fy4_PKbYZT3KPIL8nBCKkwS4sQHxdkpsRS6joHoK33T-_W2A9G0U6hfbXgMJixtDTOi7n1KzOxyArU0WTScL_7iaV4ymMpoojiyIGFOrjDp5jNdchnh5G61DrKQ39xddtohIMkGbwuhJQmCrKA

While it is not necessary, if we were to decode the token, here is what we would learn.
{
    "aud": "https://management.azure.com/",
    "iss": "https://sts.windows.net/90a38eda-4006-4dd5-924c-6ca55cacc14d/",
    "iat": 1703562782,
    "nbf": 1703562782,
    "exp": 1703649482,
    "aio": "E2VgYCi1mfa9Sd6Tpy8q+5vM/rN/AA==",
    "appid": "b84e06d3-aba1-4bcc-9626-2e0d76cba2ce",
    "appidacr": "2",
    "idp": "https://sts.windows.net/90a38eda-4006-4dd5-924c-6ca55cacc14d/",
    "idtyp": "app",
    "oid": "600a3bc8-7e2c-44e5-8a27-18c3eb963060",
    "rh": "0.AFEA2o6jkAZA1U2STGylXKzBTUZIf3kAutdPukPawfj2MBPQAAA.",
    "sub": "600a3bc8-7e2c-44e5-8a27-18c3eb963060",
    "tid": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
    "uti": "4PFpbyksN0-4Bf4-RwiKAg",
    "ver": "1.0",
    "xms_az_rid": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourcegroups/northpole-rg1/providers/Microsoft.Compute/virtualMachines/ssh-server-vm",
    "xms_cae": "1",
    "xms_mirid": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourcegroups/northpole-rg1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/northpole-ssh-server-identity",
    "xms_tcdt": 1698417557
}
Saving as a variable
export ELFCRED=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzkwYTM4ZWRhLTQwMDYtNGRkNS05MjRjLTZjYTU1Y2FjYzE0ZC8iLCJpYXQiOjE3MDU0MzY1MjksIm5iZiI6MTcwNTQzNjUyOSwiZXhwIjoxNzA1NTIzMjI5LCJhaW8iOiJFMlZnWUpEWHkrUzl6ZlY5Z3dTN092Y25nZlhuQUE9PSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsImlkdHlwIjoiYXBwIiwib2lkIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwicmgiOiIwLkFGRUEybzZqa0FaQTFVMlNUR3lsWEt6QlRVWklmM2tBdXRkUHVrUGF3ZmoyTUJQUUFBQS4iLCJzdWIiOiI2MDBhM2JjOC03ZTJjLTQ0ZTUtOGEyNy0xOGMzZWI5NjMwNjAiLCJ0aWQiOiI5MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQiLCJ1dGkiOiJpdHAtNk5UUWZVbXg3TzBVUzNOTEFBIiwidmVyIjoiMS4wIiwieG1zX2F6X3JpZCI6Ii9zdWJzY3JpcHRpb25zLzJiMDk0MmYzLTliY2EtNDg0Yi1hNTA4LWFiZGFlMmRiNWU2NC9yZXNvdXJjZWdyb3Vwcy9ub3J0aHBvbGUtcmcxL3Byb3ZpZGVycy9NaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXMvc3NoLXNlcnZlci12bSIsInhtc19jYWUiOiIxIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvMmIwOTQyZjMtOWJjYS00ODRiLWE1MDgtYWJkYWUyZGI1ZTY0L3Jlc291cmNlZ3JvdXBzL25vcnRocG9sZS1yZzEvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VkSWRlbnRpdHkvdXNlckFzc2lnbmVkSWRlbnRpdGllcy9ub3J0aHBvbGUtc3NoLXNlcnZlci1pZGVudGl0eSIsInhtc190Y2R0IjoxNjk4NDE3NTU3fQ.KWNkJHE0XbZ-dFNHwkqHirRyB15cGI94AzpBcAcAdFCaf0b206o1WbjdTL8rM-yth5eWrMK6muFITPknnvU_o6QtIrGZN8wWE3lRGPLl8dxU5z4iph4_GyesaO9npzwXrfNWAwAghFApGjuPdaa2K-y9XFiQW2OrlBHTaQzeZ9r-Oirb90c_us0JwTU3HNWY-a-qNqHQN91i_f0ISdH0Is5EL0DrfcBXthamsrQdRt-VZSvRBK6kSJC1fRPeUItdaEO62LbPieU_OsIExnVC36RISuC8dwPlrmfrc_0wzA_6k2vv1ROxwrzYv1rk9L81-Ozp2ySw8pY2OykyBsVW2g

Now we have enough information to run:

curl -X GET "https://management.azure.com/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Web/sites/northpole-ssh-certs-fa/sourcecontrols/web?api-version=2022-03-01" -H "Authorization: Bearer $ELFCRED" | jq

Result
{
  "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Web/sites/northpole-ssh-certs-fa/sourcecontrols/web",
  "name": "northpole-ssh-certs-fa",
  "type": "Microsoft.Web/sites/sourcecontrols",
  "location": "East US",
  "tags": {
    "project": "northpole-ssh-certs",
    "create-cert-func-url-path": "/api/create-cert?code=candy-cane-twirl"
  },
  "properties": {
    "repoUrl": "https://github.com/SantaWorkshopGeeseIslandsDevOps/northpole-ssh-certs-fa",
    "branch": "main",
    "isManualIntegration": false,
    "isGitHubAction": true,
    "deploymentRollbackEnabled": false,
    "isMercurial": false,
    "provisioningState": "Succeeded",
    "gitHubActionConfiguration": {
      "codeConfiguration": null,
      "containerConfiguration": null,
      "isLinux": true,
      "generateWorkflowFile": true,
      "workflowSettings": {
        "appType": "functionapp",
        "publishType": "code",
        "os": "linux",
        "variables": {
          "runtimeVersion": "3.11"
        },
        "runtimeStack": "python",
        "workflowApiVersion": "2020-12-01",
        "useCanaryFusionServer": false,
        "authType": "publishprofile"
      }
    }
  }
}

The most important take-away from this output is the github repo: https://github.com/SantaWorkshopGeeseIslandsDevOps/northpole-ssh-certs-fa If we plug that into a browser, we can now see the actual source code for the Azure Function App. Let's paste that into ChatGPT to see if it identifies any vulnerabilities for us!

ChatGPT

The provided Python code is for an Azure Function App designed to create SSH certificates. This app includes a web interface for users to request SSH certificates by submitting their public keys. Let's break down the key components and functionalities of the code:

Key Components⚓︎

  1. Imports and Global Variables:

    • Standard Python libraries and Azure-specific libraries are imported.
    • Environment variables DEFAULT_PRINCIPAL, KEY_VAULT_URL, and CA_KEY_SECRET_NAME are used to configure the app.
  2. Azure Function App Configuration:

    • The app is set up with an HTTP authentication level.
    • A DefaultAzureCredential and SecretClient are initialized for Azure Key Vault interactions.
  3. ValidationError Class:

    • A custom exception class for handling validation errors.
  4. parse_input Function:

    • Parses and validates the input data from the HTTP request.
    • Validates the SSH public key and the principal (user) data.
  5. get_form Function:

    • Returns an HTML form for the user interface. This form allows users to submit their SSH public key.
  6. create_cert Function (Main Functionality):

    • Handles HTTP requests (GET and POST).
    • For GET requests, it returns the HTML form.
    • For POST requests, it processes the creation of an SSH certificate:
      • Extracts and validates the SSH public key and principal from the request.
      • Retrieves the private key of the Certificate Authority (CA) from Azure Key Vault.
      • Creates an SSH certificate with specified fields (validity, principals, etc.).
      • Signs the certificate using the CA's private key.
      • Returns the signed SSH certificate.

Workflow⚓︎

  1. User Accesses the Function App:

    • The user accesses the app through a web interface (GET request).
    • The get_form function returns an HTML page with a form.
  2. Submitting the SSH Public Key:

    • The user submits their SSH public key through the form.
    • The form data is sent to the server (POST request).
  3. Certificate Creation:

    • The create_cert function processes the POST request.
    • It validates the input and retrieves the CA's private key from Azure Key Vault.
    • An SSH certificate is created, signed, and returned to the user in JSON format.

Error Handling⚓︎

  • The app includes error handling for validation errors and other exceptions.
  • Errors are returned as JSON with appropriate HTTP status codes (400 for client errors, 500 for

server errors).

Security and Best Practices⚓︎

  • The app uses Azure Key Vault to securely manage the private key of the Certificate Authority, ensuring that sensitive keys are not exposed.
  • Input validation is performed to prevent invalid or malicious data from being processed.
  • The use of environment variables for configuration allows for secure and flexible deployment settings.

Potential Enhancements or Considerations⚓︎

  • Logging and Monitoring: The app logs important information, which can be extended for better monitoring and debugging.
  • Scalability: Depending on the expected load, the app's scalability in the Azure environment might need consideration.
  • User Authentication and Authorization: Depending on the use case, integrating user authentication and authorization to control who can request certificates might be necessary.
  • Certificate Revocation and Management: While the app handles certificate creation, additional functionality for managing and revoking certificates could be implemented.

Overall, this Azure Function App provides a streamlined way to create and manage SSH certificates, leveraging Azure services for security and scalability.

Upgrading the Principal to Admin⚓︎

The principal field is set with the DEFAULT_PRINCIPAL value. Perhaps it can be changed through either Burp or through the Inspect tool on your browser (Chacho using Firefox and the Inspect tool).

  1. Go to the Azure Function App website and right click on the page opening the Inspect tool.

  2. Click on the Network tab. Grab your public key and paste it into the field on the website and click submit.
    requestCert

  3. Within the Network tab, click on the POST entry that lists "create-cert" in the Initiator column.

  4. Right-click this entry and select Edit and Resend. useInspector

  5. This pops up a section called "Body" where you will see the JSON code of your public key. Add the "principal": "admin" to your JSON file in the appropriate format (you can use the previous output as your guide) and click Send. You should see the output result in the "Response" section of the Request Details panel. Once this has happened, your cert should now have a certificate that gives you admin rights, but we still need to create that admin key from the signed certificate.
    editAndResend

  6. Similarly to the hhc_elf-key, we will copy the key from within the new certificate. I grabbed it by clicking on the ssh-cert key:value in the "Response" section fo the Request Details panel and then right-clicking to select "Copy Value." copyCred

Setting Up the New Creds⚓︎

  1. Create a key called "admin-key" and pasted the value into there.

    To check to see if your cert now has admin rights, you can go back to your host machine and run the following command:

    ssh-keygen -L -f admin-key
    

  2. Log in with alabaster's new creds:

    ssh alabaster@ssh-server-vm.santaworkshopgeeseislands.org -i hhc_key -i admin-key`
    

Achieving the Objective⚓︎

After SSHing into alabaster's account, his home directory indicates it has impacket and one other file: alabaster_todo.md.

cat alabaster_todo.md 
# Geese Islands IT & Security Todo List
- [X] Sleigh GPS Upgrade: Integrate the new "Island Hopper" module into Santa's sleigh GPS. Ensure Rudolph's red nose doesn't interfere with the signal.
- [X] Reindeer Wi-Fi Antlers: Test out the new Wi-Fi boosting antler extensions on Dasher and Dancer. Perfect for those beach-side internet browsing sessions.
- [ ] Palm Tree Server Cooling: Make use of the island's natural shade. Relocate servers under palm trees for optimal cooling. Remember to watch out for falling coconuts!
- [ ] Eggnog Firewall: Upgrade the North Pole's firewall to the new EggnogOS version. Ensure it blocks any Grinch-related cyber threats effectively.
- [ ] Gingerbread Cookie Cache: Implement a gingerbread cookie caching mechanism to speed up data retrieval times. Don't let Santa eat the cache!
- [ ] Toy Workshop VPN: Establish a secure VPN tunnel back to the main toy workshop so the elves can securely access to the toy blueprints.
- [ ] Festive 2FA: Roll out the new two-factor authentication system where the second factor is singing a Christmas carol. Jingle Bells is said to be the most secure.

And now we have the answer to our Objective for SSHenanigans: What kind of cookie cache does alabaster plan to implement?

Objective Answer

Gingerbread

Wrap-up

In the end, this specific challenge did not end up requiring us to use IMDS, get a token, run API commands, or look at the github repo's source code in order to get the creds necessary, BUT doing all of those steps is what demonstrates where the vulnerabilities actually exist so that the victim can fix them."

Response⚓︎

Alabaster Snowball

Oh my! I was so focused on the SSH configuration I completely missed the vulnerability in the Azure Function App.

Why would ChatNPT generate code with such a glaring vulnerability? It's almost like it wanted my system to be unsafe. Could ChatNPT be evil?

Thanks for the help, I'll go and update the application code immediately!

While we're on the topic of certificates, did you know Active Directory (AD) uses them as well? Apparently the service used to manage them can have misconfigurations too.

You might be wondering about that SatTrackr tool I've installed on the monitor account?

Here's the thing, on my nightly stargazing adventures I started noticing the same satellite above Geese Islands.

I wrote that satellite tracker tool to collect some additional data and sure enough, it's in a geostationary orbit above us.

No idea what that means yet, but I'm keeping a close eye on that thing!