Lightweight Directory
150 points. The brief reads: travel light, leave room for discovery. The framing is literal.
The front page is titled ROSTER HQ and presents esports team content: "Manage your player identity and explore the team operations directory." A single login form and nothing else.
Requesting the root redirects directly to /connect, which serves the same form. Response
headers indicate Python and Werkzeug 3.1.9, so the application is Flask-based. The page
source holds no additional links, comments or hidden fields, only username and password
fields posting back to the same location.
Ordinary credential guesses fail in the expected way. admin / admin returns:
Log in to Directory Failed
The recurring term is directory: team operations directory, Lightweight Directory. LDAP is the natural hypothesis on wording alone, with no supporting evidence yet.
A subsequent test with * / * returns a different error:
Password length not acceptable
The two distinct responses establish ordering: a length check precedes the directory lookup. Passwords of length 1, 2 and 3 return the length message; length 4 and above return the directory failure. The field is validated first, and the lookup follows.
Guessing usernames produced nothing. guest, user, admin, player and roster all
failed identically, with the same response size and no observable timing difference or other
leak.
Filter injection is the next step. Where the filter is constructed by inserting the username
directly, a * in the correct position matches every entry. Most closing variants had no
effect and returned the standard failure line. One payload behaved differently:
*)(uid=*))(|(uid=*supplied as the username with an ordinary four-character password. The response was not the
login page at all: a 302 redirect to / plus a session cookie for admin. The response size
change is the clearest indicator, 4869 bytes on failure against 189 bytes on this attempt.
The request was replayed to confirm, the cookie retained, and / opened with it, yielding a
different page entirely:
Welcome, admin Edit player profile Open team report Open team report Logout
Two links to the same report are listed twice, which is untidy but incidental. The report returns the flag as plain text with no HTML wrapper:
safctf{ef30111b835006ade7f00a9a4526d453}A second authenticated page was also retrieved. /config-update presents "Update Your
Access ID" with a single field for a new identifier; posting a test value returns a redirect
to the home page. That path was not pursued further, since the report already contained the
flag.
The likely mechanism is filter construction of the form (uid=<input>), where the closing
parentheses plus the (|(uid=* segment convert the expression into an OR matching the first
directory entry, which is admin. Either the password was not checked against the directory
at all, or it accepted any value once the user matched; this cannot be determined from the
outside. The session asserted admin and the server acted on that assertion.
A more efficient ordering would place filter breakout tests before extended username guessing, given two separate indications that a directory was involved. The duplicated report link is also unexplained. It is plausibly a defect, and on a repeat run the two link targets would be compared for differing parameters.
Flag:
safctf{ef30111b835006ade7f00a9a4526d453}