Cyber security from several angles in one place: attack a practice target as the red team, investigate an incident as the blue team, and piece together clues from open sources with OSINT. Every challenge comes with step-by-step hints and the tools you can use.
0/6 solved · 0 pts
Red Team
Think like an attacker: recon, find the gap, exploit.
red-01Easy100 pts
The Staging Server Nobody Cleaned Up
Scenario
You've been hired to pentest PT NusaLogistik (fictional). The only in-scope entry point is the staging employee portal. Its login form is disabled, but the developers are known for leaving traces.
Mission
Recon the portal, find the leaked configuration file, then extract the flag hidden inside the service token.
The SOC got an alert from PT NusaLogistik's (fictional) portal server in the early hours of 12 October 2026: a spike in requests and a strange file in the upload folder. You've been handed a copy of the web server's access log.
Mission
Reconstruct the attack: which attacker got in, which webshell they uploaded, and which server the data was exfiltrated to.
Hints Open them one at a time, only when you're stuck.
Hint 1 — Who's the loudest?
Count requests per IP and per status code. A run of 401s on /login followed by a single 302 is a successful brute force. Careful: not every noisy IP got in.
GoAccess — quick dashboard from an access log (goaccess access.log --log-format=COMBINED)
Hint 2 — Follow the trail after login
Filter every request from the attacker's IP and read it in order. An avatar upload that accepts a .php file is a red flag.
Tools
grep — grep '^<ip> ' access.log for a single attacker's timeline
Splunk / Elastic (Kibana) — query by IP and sort by time
User-Agent — watch the last column: a UA change marks a change of tooling
Hint 3 — Disguised commands
The webshell's ?c= parameter holds commands that were Base64-encoded, then URL-encoded. Decode them one by one; one of them ships an archive to an outside server.
Tools
CyberChef — URL Decode → From Base64 recipe
base64 -d — grep -o 'c=[^ ]*' access.log | cut -d= -f2 | sed 's/%3D/=/g' | while read x; do echo "$x" | base64 -d; echo; done
Python — urllib.parse.unquote + base64.b64decode to automate it
blue-02Medium150 pts
Whispers Over DNS
Scenario
Two days after the portal incident, the IDS flagged workstation 10.10.5.23, used by PT NusaLogistik's (fictional) finance team, for contacting the same IP as the earlier exfiltration server. The network team managed to record a minute of its traffic.
Mission
Open the capture in Wireshark, find out what command the malware got from its C2 server, then reconstruct the stolen data. That data is the flag.
Hints Open them one at a time, only when you're stuck.
Hint 1 — Get the big picture first
Don't read packets one by one yet. Find out which protocols are present and who this workstation talks to. One IP isn't on the internal 10.x network.
Tools
Wireshark → Statistics → Protocol Hierarchy — see the protocol mix (DNS, HTTP, TCP)
Wireshark → Statistics → Conversations — the IPv4 tab lists which IPs talk to each other
tshark — tshark -r capture.pcap -q -z conv,ip
Hint 2 — Listen in on the C2 conversation
The malware fetches its task over plain HTTP. Reassemble the TCP packets into one conversation and read the server's reply. Watch out: a FLAG{...} string you find with strings/grep isn't necessarily the right one.
Tools
Display filter — http.request or ip.addr == <outside-ip>
Follow → TCP Stream / HTTP Stream — right-click an HTTP packet, then Follow to read the request & response
File → Export Objects → HTTP — save every file that went over HTTP
NetworkMiner — an alternative for extracting files & hosts from a pcap
Hint 3 — Data disguised as domain names
The C2 task names a DNS zone and a <seq>-<hex> label format, sent out of order. Grab every query to that zone, sort by seq number, join the hex parts, then decode.
CyberChef — From Hex recipe for the joined hex chunks
OSINT
Think like an investigator: collect, connect, and verify information from open sources without touching the target.
osint-01Easy100 pts
A Weekend in Bandung, Supposedly
Scenario
An employee of PT NusaLogistik (fictional) posted a "weekend getaway in Bandung" photo on the same day they called in sick. HR asked for help verifying it, and all you've got is the original photo file.
Mission
Work out when the photo was actually taken and where. Don't trust the caption; trust the data.
Hints Open them one at a time, only when you're stuck.
Hint 1 — A photo holds more than pixels
Phone photos usually carry EXIF metadata: camera make, editing app, timestamps, even GPS. Download the original file, not a screenshot.
Tools
exiftool — exiftool -a -G1 liburan.jpg to list every tag with its group
Jeffrey's Image Metadata Viewer / exif.tools — web alternatives (for practice photos only, never personal ones)
File → Properties (Windows) / Get Info (macOS) — a quick look at some of the metadata
Hint 2 — Not every date is the same
There are several time tags. ModifyDate changes when the photo is edited, while DateTimeOriginal records when the shutter fired. The caption (ImageDescription) can say anything.
Tools
exiftool — exiftool -time:all -G1 liburan.jpg
CyberChef — Extract EXIF recipe, right in the browser
Hint 3 — From degrees to a map
EXIF GPS is stored as degrees, minutes, seconds (DMS) plus a direction. Decimal = degrees + minutes/60 + seconds/3600, negative for South or West. Paste the result into a map to confirm.
Google Maps / OpenStreetMap — paste "lat, lon" into the search box
Google Earth / Street View — compare the landmark in the photo with the location
osint-02Medium150 pts
The Server That Isn't on the List
Scenario
PT NusaLogistik (fictional) asked for a passive attack-surface assessment. According to their IT team, every service lives in a single official IP block. You've exported certificate history from Certificate Transparency logs and passive DNS data for their domain.
Mission
Read the scope document, then find the one subdomain that's still live but hosted outside the official IP block (shadow IT).
FLAG{subdomainlabel_ip} (leftmost label only, e.g. FLAG{www_192.0.2.10})
Hints Open them one at a time, only when you're stuck.
Hint 1 — List every name first
Certificate Transparency logs record every TLS certificate ever issued, so even hostnames that were never published show up. Pull every unique name_value. Wildcard certificates don't name a host, so skip them.
Tools
jq — jq -r '.[].name_value' crtsh.json | sort -u
crt.sh — in the real world: https://crt.sh/?q=%25.domain.com&output=json
subfinder / amass (passive mode) — collect subdomains from many open sources at once
Hint 2 — Where does each name point?
Passive DNS keeps a history of DNS answers along with when they were first and last seen. Filter A records whose IP isn't 192.0.2.x.
csvkit / Excel / LibreOffice — filter the rrtype and rdata columns
SecurityTrails / VirusTotal — real-world passive DNS sources
Hint 3 — Alive or dead?
More than one host sits outside the official block, but some haven't been seen in years. Compare last_seen with the date on the scope document; the one still seen this week is your answer.
Tools
sort — sort -t, -k5 passive-dns.csv to order by last_seen
jq — jq '.[] | select(.name_value|test("<label>")) | {not_before, not_after}' crtsh.json to see its latest certificate
osint-03Medium150 pts
The Internet Never Forgets
Scenario
As part of a security awareness programme approved by PT NusaLogistik (fictional) and its staff, you've been asked to assess the digital footprint of their sysadmin, Raka Pratama. Details like an old handle and a personal email are exactly what attackers use for highly targeted phishing.
Mission
Starting from his current social media profile, find Raka's old handle and then the personal email he once published.
Hints Open them one at a time, only when you're stuck.
Hint 1 — Read what isn't displayed
Social profiles often carry a verified link to the owner's website. It isn't always visible on the page, but it's in the source.
Tools
View Source (Ctrl+U) — look at the <link> and <meta> tags in <head>
rel="me" — the attribute Mastodon and others use to verify site ownership
curl + grep — curl -s <url> | grep -i 'rel="me"'
Hint 2 — A dead domain isn't a gone domain
Sites that were shut down often still have copies in a web archive. Look up Raka's old domain in the archive index.
Tools
Wayback Machine — in the real world: web.archive.org/web/*/domain.com/*
archive.today — an alternative archive that sometimes keeps pages Wayback doesn't
Sherlock / WhatsMyName — in the real world: check the same handle across hundreds of sites
Hint 3 — Deleted means it once existed
The latest capture says the email was removed. Open the older captures one by one.
Tools
Comparing captures — the Wayback Machine's Changes feature diffs two dates
grep — grep -rEo '[[:alnum:]._-]+@[[:alnum:].-]+' over downloaded copies of the pages
Rules
Every target lives in this site's /ctf/ folder and is static. Don't attack any other part of the site, the hosting server, or anyone else.
The companies, people, accounts, domains (.invalid), and IPs in the scenarios are fictional (IPs from the RFC 5737 documentation blocks).
Flags are checked in your browser by comparing SHA-256 hashes; nothing is sent to the server. Progress is stored in this browser only.
The techniques here are for practice and for systems you have written permission to test. OSINT on real people needs consent and a lawful basis; never use it to stalk or dox anyone.