Description
A server log file has a flag fragmented across multiple lines. Find and reassemble the pieces.
Setup
Download the log file from the challenge page.
Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Search for flag fragments
ObservationThe description says the flag is fragmented across many lines of a large log file. grep narrows that down to just the lines carrying the picoCTF label, before any reassembly starts.Use grep to find all lines containing picoCTF. Some lines may contain only partial fragments of the flag spread across multiple log entries.bashgrep -i 'picoCTF' server.logWhat didn't work first
Tried: Run grep without -i so the search is case-sensitive
If any line writes 'picoctf' or 'PICOCTF' in a different case, the match silently fails and those lines drop out. The -i flag folds every case variant into one pass, which is the safe default when the log format is unknown.
Tried: Anchor the grep pattern on the full flag prefix: grep 'picoCTF{' server.log
Only the first fragment line carries the opening brace, so the middle and closing fragments never match. Anchor the pattern on something present on every fragment line: 'picoCTF' without the brace, or better, the 'FLAGPART:' label from step 2.
Learn more
grep scans a file line by line and prints every line that matches a pattern. The
-iflag makes the match case-insensitive, catching variations likePICOCTF,picoctf, or mixed case. In large log files with thousands of lines, grep reduces the search space from the full file to only the relevant matches in milliseconds.Log files are structured text files where each line typically represents one event: a timestamp, severity level, source, and message. CTF challenges use log files as a forensic artifact - the flag may appear as part of a simulated HTTP request, an error message, a database query result, or split across multiple events. Understanding the log format first helps determine how fragments are separated.
For more complex log analysis, tools like
awk,sed,jq(for JSON logs), or dedicated log analysis platforms (Splunk, Elasticsearch) provide richer filtering and transformation capabilities. In security operations, log analysis is the primary method for detecting intrusions and reconstructing attacker activity.Step 2Extract and join all fragments
ObservationEach matching line carries a 'FLAGPART:' label followed by one piece of the flag. Anchoring a regex on that stable label captures every fragment in document order, ready to be joined.Use Python's re.findall to capture the value after each 'FLAGPART:' label. The fragments appear in order in the log, so joining them directly reassembles the complete flag.pythonpython3 -c " import re data = open('server.log').read() frags = re.findall(r'FLAGPART:\s*([^\n]+)', data) print(frags) print(''.join(f.strip() for f in frags)) "What didn't work first
Tried: Anchor the regex on the flag prefix instead: re.findall(r'picoCTF\{([^}]+)\}', data)
This pattern needs the opening brace, the body, and the closing brace all on one line. The flag is split across lines, so only the first fragment matches and the rest are dropped without a word, leaving a truncated or empty result. Anchoring on the stable 'FLAGPART:' label catches every fragment whatever it contains.
Tried: Use grep output piped to cut or awk to extract the fragment value, skipping Python entirely
cut -d':' -f2 splits on the first colon only, which breaks the moment a fragment value contains a colon itself, and URLs in HTTP access logs are full of them. A Python regex with a non-greedy capture group handles arbitrary fragment content and joins duplicates in one pass, with no separate dedup step.
Learn more
Each relevant log line follows the format
[timestamp] INFO FLAGPART: <fragment>. Only the first fragment starts withpicoCTF{; the remaining fragments contain the rest of the flag body and closing brace. A pattern that anchors onpicoCTF{would therefore only capture the first piece and silently drop everything else.re.findall(pattern, string) returns a list of all non-overlapping matches in document order. The pattern
FLAGPART:\s*([^\n]+)matches the literal labelFLAGPART:, skips any whitespace with\s*, then captures everything up to the end of the line with([^\n]+). The parentheses form a capturing group, so findall returns the captured fragment values rather than the full matched strings.The
join()step concatenates the list of fragments into a single string. Because the log repeats each FLAGPART entry many times, you may see duplicates in the printed list - that is expected. The deduplication is not necessary if you only need the unique ordered sequence; reading unique fragments in document order (e.g. withdict.fromkeys(frags)) also works. Always verify the reassembled result starts withpicoCTF{and ends with}before submitting.
Interactive tools
- Regex TesterTest regular expressions against a string with live match highlighting, flag toggles, and common CTF pattern shortcuts.
- Timestamp ConverterConvert Unix timestamps (seconds or milliseconds), hex timestamps, and date strings to every common format.
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
Flag
Reveal flag
picoCTF{us3_y0urlinux_sk1lls_...}
Fixed flag, confirmed consistent across multiple independent verified solutions.