Codify

Gaining Access

Nmap scan:

$ nmap -p- --min-rate 3000 10.129.48.74                         
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-04 23:06 EDT
Nmap scan report for 10.129.48.74
Host is up (0.016s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
3000/tcp open  ppp

Did a detailed scan as well:

$ nmap -p 80,3000 -sC -sV --min-rate 3000 10.129.48.74          
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-04 23:07 EDT
Nmap scan report for 10.129.48.74
Host is up (0.011s latency).

PORT     STATE SERVICE VERSION
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

I added codify.htb to the /etc/hosts file.

Web Enum -> Node.js RCE

The web application ran an application to allow for Node.js sandboxing:

There are some 'Limitations' set by the creator, and it includes the following:

So the obvious methods of achieving RCE are not allowed. When I tested it with child_process, it got blocked:

However, this does not mean that it blocks node:child_process:

child_process is an outdated module, whereas node:child_process is an entirely different module that is more efficient and runs with less overhead.

Using this, I ran this code to get a shell as the user svc:

Privilege Escalation

Did some basic enumeration of the machine. First I checked out the /var/www/html folder:

Viewing RCE Vuln

Took a detour and looked at the JS code that was responsible for the initial RCE:

There's a check to see what modules are used via checking for require, and it also explains why node:child_process was allowed since it only checks for whether child_process is required.

Tickets -> User Password

Within the /var/www/tickets directory, there's a tickets.db file:

I transferred this back to my machine via nc, and then opened it up with sqlite3:

This hash can be cracked using john:

Afterwards, I could su to the user joshua.

Sudo Privileges -> Wildcard Bypass

joshua could run a script as root:

Here's the contents of the script:

There's no PATH hijacking since all the commands use the full PATH. pspy64 could allow me to read the root password since it is directly passed into the mysqldump command. However, I needed to somehow bypass the if [[$DB_PASS == $USER_PASS]] check first.

I know that my input is directly passed into it, and it is not sanitised at all, and there was no way for me to read the actual password. The question here is, how do I always force a true condition for a string comparison?

During my testing, I realised I could enter special characters. Using the wildcard * character, the if condition is always true, because * matches all characters and spaces.

As such, in a second shell as joshua, I ran pspy64. In my initial shell, I ran the script as root, and was able to capture the password:

Using this, I could su to root:

Rooted! Learnt something new here.

Last updated