OSINT Industries CTF — Writeup
OSINT là một chủ đề rất thú vị ở CTF, nói trắng ra thì nó là kiểu nói hoa mỹ của việc đi Stalk người khác.
Mới đây, OSINT Industries đã tạo một cuộc thi CTF hoàn toàn chỉ có OSINT, không có exploit gì cả, mọi thông tin đều có thể tìm kiếm công khai. Tuy mình không tham gia ngay từ lúc đầu nhưng vẫn có thể trải nghiệm các challenge do họ luôn cập nhật platform liên tục và luôn ở trạng thái hoạt động. Các challenge được chia ra rất đa dạng, từ GEOINT, FSB, GRU, INTERPOL, EUROPOL và đều là từ thế giới thật với các tên tuổi thật. Các bạn có thể trải nghiệm nó ở đây.
Trong bài writeup này, mình sẽ kể lại cách mà mình giải các challenge trong CTF, cách mình suy nghĩ, điều khiển AI. Và mình là một kiểu người enjoyer nên sẽ không quá quan trọng việc AI Slop hay không. À ngoài ra thì, mình cũng refine một số câu chuyện nghe cho nó lọt tai hơn chứ không hoàn toàn những gì xảy ra trong quá trình giải, hơn nữa một số challenge mới đây sẽ không được phép công khai writeup nên là mình sẽ để nó locked nhé (để cho ngầu thôi nhưng thật ra cũng không có gì =)))
Các challenge
Dưới đây là tóm tắt ngắn gọn các challenge
| Challenge | Phân loại | Mục tiêu |
|---|---|---|
| Find the Masked Man | GEOINT | Tìm vị trí subway ở Paris từ bức ảnh |
| Caught in the Act | GEOINT | Tìm vị trí đại học từ bức ảnh |
| Lost in Transit | GEOINT | Tìm vị trí ga tàu từ bức ảnh |
| UK Suspect | GEOINT | Tìm vị trí cụ thể ở UK từ bức ảnh |
| The Suspicious Stop | GEOINT | Tìm vị trí cụ thể từ file log GPS |
| Oops… Wrong Base | GEOINT | Tìm vị trí cụ thể từ bức ảnh |
| DEPIX | OSINT | Recover passenger name, seat and destination IATA code from a heavily pixelated boarding pass. |
| Holehe & The Secret Email | FSB | Trace the first public appearance of the holehe author's email address, and date it. |
| On the Traces of the Silk Road | EUROPOL | Pivot from the Silk Road case record to a specific profile and a review tied to a location. |
| Found the Hacker | OSINT | Identify an individual from the traces left around an intrusion. |
The categories in play were GEOINT, OSINT, FSB, GRU, INTERPOL and EUROPOL. The agency names read as flavour but function as a difficulty ladder: the early categories hand you one strong lead, the later ones hand you three weak ones and expect you to make them agree.
A caveat worth stating plainly: not every challenge has a public writeup, and the platform's scoreboard is behind a login. Where a solution is not already public, I have put mine behind a key rather than publishing it — see below.
Toolkit
Đây là các tool mà tôi đã dùng
Docking site:, filetype:, intitle:, "exact phrase", before:/after:
Search engine Google, Yandex, Bing, DuckDuckGo
Reverse image Google Lens, Yandex, Bing Visual Search
Mapping Google Maps + Street View, OpenStreetMap, Overpass Turbo
Time travel Wayback Machine, archive.today, Google cache
Code history GitHub commit history, `git log --follow`, PyPI release pages
People/handle pivots WhoisXML, holehe, sherlock, Have I Been Pwned
Photo metadata exiftool, sun position calculators
GEOINT — Find the Masked Man
A photograph taken in Paris on 3 December 2023, around 18:00. Name the metro station nearest to where it was taken.
Three constraints come free with the brief, and each one narrows the search before you look at the image at all.
The date and time do real work. Paris on 3 December sunsets around 16:55, so 18:00 is fully dark. Anything in the frame that looks like daylight means you have the wrong photograph or the wrong assumption. Artificial light also tells you about the setting: shopfront light, streetlight colour temperature, and Christmas illuminations, which in early December are already up.
Read the frame before searching it. The habit that pays here is to inventory everything legible and rank it by how unique it is:
- Street furniture — Paris has a distinctive vocabulary of bollards, Morris columns, Wallace fountains, and Guimard metro entrances. A Guimard entrance alone narrows you to a known list of stations.
- Building form — Haussmann facades are everywhere, so they are near-useless. A corner cut at 45°, an unusual roofline, or a non-Haussmann block is worth far more.
- Text — shop names, awnings, street plaques, bus stop names, event posters. A business name plus "Paris" in a search is often the whole challenge.
- Road markings and lane geometry, which pin the exact side of a street once you are close.
Then confirm, do not guess. Reverse image search gives you a candidate. What turns a candidate into an answer is lining up at least two independent fixed features in Street View — a specific balcony ironwork pattern and the angle of a side street, say. One match is a coincidence; two that agree from the same camera position is a location.
Once the position is fixed, the nearest station is a mapping question rather than an OSINT one. Watch for the trap in the wording: nearest means nearest by walking distance, not the station whose name you recognise, and Paris is dense enough that those differ.
Find the Masked Man — my answer
This part is not published. There is no key for it.
FSB — Holehe & The Secret Email
holehe checks whether an email address is registered on a given site. Find the first appearance of its creator's email address online, and the date that address was created.
This is a software-archaeology challenge wearing an OSINT hat, and it splits cleanly in two.
Finding the address. A maintainer's email is rarely written on a page; it is committed. Every git commit carries an author email, so the repository is the primary source:
git clone https://github.com/megadose/holehe
git log --format='%an <%ae>' | sort -u
The oldest commits are the interesting ones. Developers tighten up their public
identity over time — a personal address in a 2019 commit often gets replaced by
a noreply address later, but git never forgets the earlier one. Packaging
metadata is the other reliable place: setup.py, pyproject.toml, and the
PyPI project page all carry an author email, and old PyPI releases preserve
whatever was current when they shipped.
Dating it. "When was this address created" is not answerable directly — no provider publishes that. So the question is really what is the earliest evidence of it existing, and the answer is whatever public artefact carries it with a trustworthy timestamp. Candidates, roughly in order of how much I trust the date:
- A git commit's author date — precise, though rewritable, so sanity-check it against when the repository was actually created.
- A PyPI or npm release page — publication dates are server-side and hard to forge.
- A mailing list or forum archive with the address in a header.
- A Wayback capture of a page containing it — gives you no later than, not created on.
The lesson that generalises: an OSINT answer is a claim plus the artefact that supports it. If you cannot name the artefact, you have a guess.
Holehe & The Secret Email — my answer
This part is not published. There is no key for it.
EUROPOL — On the Traces of the Silk Road
Questions about the Silk Road marketplace and the investigation that ended it.
Everything needed here is in the public record, and the record is unusually good: the case produced a criminal complaint, a full trial, and a large volume of exhibits, most of it online.
The move that matters is to go to primary sources instead of news coverage. Court filings are the highest-quality OSINT source you will ever get for free — they are specific, dated, and adversarially checked. Reporting compresses and occasionally garbles them.
Complaint and indictment the FBI complaint, USAO SDNY filings
Trial exhibits chat logs, server images, seizure records
Contemporaneous forum posts Bitcointalk, and the Shroomery post that
connected an early handle to a real identity
Archived marketplace pages Wayback captures of the .onion mirrors
The single most instructive thread in the whole case is the operational-security failure that started the identification: an early promotional post made under a handle that was, elsewhere and earlier, tied to a real name and a real email. Nothing about that was decrypted or hacked. It was searched.
That is the whole point of the category. The exercise is not to be clever, it is to correlate: one handle, one address, one timestamp, until independent sources say the same thing.
Silk Road — my answers
This part is not published. There is no key for it.
OSINT — DEPIX
A boarding pass, pixelated. Recover the passenger's first and last name, the seat number, and the arrival airport's IATA code.
The name is a nod to depix, which recovers text from pixelated screenshots by searching for the source glyphs that would produce the observed blocks. That works on rendered text of a known font and background — and it is worth trying — but a photographed document usually resists it.
The reliable path on this one is that a boarding pass carries far more than its pixelated text. The barcode is the real payload: PDF417 on most boarding passes, encoding an IATA BCBP string with passenger name, flight, seat and airports in plain text. If the code survived the pixelation at all, decoding it answers all three sub-questions at once and the blurred glyphs never matter.
Failing that, the pass's own layout is a fingerprint — airline branding, fare class positioning, and font choices narrow it to a carrier, and a reverse image search on the unpixelated regions often finds the original.
DEPIX — my solve
This part is not published. There is no key for it.
OSINT — Found the Hacker
Identify an individual from the traces left around an intrusion.
Attribution challenges are handle-pivot challenges. You are given one artefact that carries an identifier — a username, an email, a wallet, a PGP key fingerprint, a domain — and the work is to find where else that identifier appears, then find where the person forgot to keep the personas separate.
The pivot order I default to:
handle -> sherlock / WhatsMyName across platforms
email -> holehe for registrations, HIBP for breach corroboration
domain -> WHOIS history, certificate transparency, passive DNS
PGP key -> keyserver lookups, the email in the UID
wallet -> block explorer -> exchange deposit tags -> forum posts
timestamps -> commit times and post times reveal a working timezone
The last one is underrated. A scatter plot of someone's public activity timestamps usually shows a sleep gap, and that gap is a timezone.
Found the Hacker — my solve
This part is not published. There is no key for it.
What I took away
Read the prompt as a set of constraints. "Paris, 3 December 2023, 18:00" is not scene-setting. It is three filters, and applying them before you search removes most of the wrong answers for free.
Two weak signals beat one strong one. A single reverse-image hit is a hypothesis. It becomes an answer when a second, independent feature agrees.
Timestamps are evidence, and not all of them are equal. A commit date, a package release, and a Wayback capture make very different claims. Knowing which one you have is most of the discipline.
When stuck, re-read your assumptions rather than searching harder. Most of the time I was stuck, the problem was something I had decided early and stopped questioning — that a light source was daylight, that an address was current, that a well-known station was the closest one.
Screenshots for the geolocation steps go in
content/blog/_images/osint-industries-ctf-2025/ and are referenced by bare
filename.