[hw] hackerswar v3.0
~ p / ds-store-trail
search ⌘K
dark

Trail of Breadcrumbs

How a forgotten .DS_Store file unraveled an entire HTB box.

Most boxes punish you for not enumerating. This one rewards you for being patient enough to read the manual that nobody published.

The box presented a single open port: 80. A ten-line landing page, a contact form that 404'd on submit, and an HR department that apparently no longer exists. Standard fare.

ffuf found nothing interesting in the first wordlist. Or the second. The third one — raft-large-files.txt — turned up a single result, and it was the result that does it every time.

bash ffuf, third pass
ffuf -u http://target/FUZZ -w raft-large-files.txt \
-mc 200 -fs 0 -t 80
 
# .DS_Store [Status: 200, Size: 6148]

Pivoting through the admin portal

The portal at /admin-portal-v2/ presented a login. Default credentials failed. SQLi failed. The session cookie, however, was a JWT signed with HS256 and a 6-character key. We have all been here before.

python key recovery
import jwt, itertools, string
token = open('cookie.txt').read().strip()
alpha = string.ascii_lowercase + string.digits
for combo in itertools.product(alpha, repeat=6):
key = ''.join(combo)
try:
jwt.decode(token, key, algorithms=['HS256'])
print('found:', key); break
except jwt.InvalidSignatureError:
continue

Twenty-three minutes later, on a laptop, with no GPU: hackme. The portal was ours. The portal had an LFI. The LFI read /etc/passwd. /etc/passwd had a service account. The service account's home directory had an SSH key.

Root, and the lesson

Privilege escalation was a misconfigured sudo rule on tar — old, unfashionable, devastating.

"Recon isn't a phase. It's the entire engagement, told in chronological order."

— Anonymous, allegedly

The takeaway isn't clean up your .DS_Store files. It's that the difference between a Hard box and a Medium box is often a single forgotten artifact.

blog.hackerswar.com 7 posts indexed
php 8.3.30 rendered 4.2ms