ctf-agent 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/AGENTS.md +131 -0
  2. package/Dockerfile +192 -0
  3. package/README.md +522 -0
  4. package/agents/ctf-analyzer.md +58 -0
  5. package/agents/ctf-controller.md +151 -0
  6. package/agents/ctf-speedrun.md +74 -0
  7. package/bin/ctf-agent.js +119 -0
  8. package/docker-compose.yml +13 -0
  9. package/mcp_config.json +19 -0
  10. package/package.json +44 -0
  11. package/references/ctf-triage-ladder.md +68 -0
  12. package/references/exploit-databases.md +575 -0
  13. package/references/llm-safety-and-policy-compliance.md +173 -0
  14. package/references/multi-agent-orchestration-and-policy-routing.md +278 -0
  15. package/references/security-events-and-intelligence.md +566 -0
  16. package/references/version-matrix.md +59 -0
  17. package/rules/ctf-execution-rules.md +44 -0
  18. package/rules/ctf-safety-framing-rules.md +140 -0
  19. package/rules/flag-validation-rules.md +25 -0
  20. package/scripts/__init__.py +1 -0
  21. package/scripts/ctf-tools.lock +205 -0
  22. package/scripts/ctf_init.py +1026 -0
  23. package/scripts/ctf_update.py +583 -0
  24. package/scripts/ctfd_client.py +81 -0
  25. package/scripts/cve_lookup.py +453 -0
  26. package/scripts/extract_flags.py +155 -0
  27. package/scripts/install_as_agent.py +278 -0
  28. package/scripts/install_ctf_tools.sh +603 -0
  29. package/scripts/parallel_triage.py +395 -0
  30. package/scripts/prompt_policy_sanitizer.py +283 -0
  31. package/scripts/scope_guard.py +444 -0
  32. package/scripts/skill_validator.py +504 -0
  33. package/scripts/workspace_cleaner.py +141 -0
  34. package/skills/ctf-ai-ml/SKILL.md +120 -0
  35. package/skills/ctf-ai-ml/adversarial-ml.md +623 -0
  36. package/skills/ctf-ai-ml/llm-attacks.md +487 -0
  37. package/skills/ctf-ai-ml/model-attacks.md +422 -0
  38. package/skills/ctf-crypto/SKILL.md +320 -0
  39. package/skills/ctf-crypto/advanced-math.md +798 -0
  40. package/skills/ctf-crypto/classic-ciphers.md +651 -0
  41. package/skills/ctf-crypto/ecc-attacks.md +347 -0
  42. package/skills/ctf-crypto/exotic-crypto-2.md +380 -0
  43. package/skills/ctf-crypto/exotic-crypto.md +528 -0
  44. package/skills/ctf-crypto/historical.md +113 -0
  45. package/skills/ctf-crypto/lattice-and-lwe.md +524 -0
  46. package/skills/ctf-crypto/modern-ciphers-2.md +563 -0
  47. package/skills/ctf-crypto/modern-ciphers-3.md +453 -0
  48. package/skills/ctf-crypto/modern-ciphers.md +649 -0
  49. package/skills/ctf-crypto/prng-attacks.md +257 -0
  50. package/skills/ctf-crypto/prng.md +664 -0
  51. package/skills/ctf-crypto/rsa-attacks-2.md +792 -0
  52. package/skills/ctf-crypto/rsa-attacks.md +487 -0
  53. package/skills/ctf-crypto/stream-ciphers.md +390 -0
  54. package/skills/ctf-crypto/zkp-and-advanced.md +456 -0
  55. package/skills/ctf-forensics/3d-printing.md +121 -0
  56. package/skills/ctf-forensics/SKILL.md +379 -0
  57. package/skills/ctf-forensics/disk-advanced.md +497 -0
  58. package/skills/ctf-forensics/disk-and-memory.md +491 -0
  59. package/skills/ctf-forensics/disk-recovery.md +699 -0
  60. package/skills/ctf-forensics/linux-forensics.md +511 -0
  61. package/skills/ctf-forensics/network-advanced.md +583 -0
  62. package/skills/ctf-forensics/network.md +645 -0
  63. package/skills/ctf-forensics/peripheral-capture.md +287 -0
  64. package/skills/ctf-forensics/signals-and-hardware.md +713 -0
  65. package/skills/ctf-forensics/steganography.md +694 -0
  66. package/skills/ctf-forensics/stego-advanced-2.md +475 -0
  67. package/skills/ctf-forensics/stego-advanced.md +481 -0
  68. package/skills/ctf-forensics/stego-image.md +691 -0
  69. package/skills/ctf-forensics/windows.md +625 -0
  70. package/skills/ctf-malware/SKILL.md +181 -0
  71. package/skills/ctf-malware/c2-and-protocols.md +274 -0
  72. package/skills/ctf-malware/pe-and-dotnet.md +108 -0
  73. package/skills/ctf-malware/scripts-and-obfuscation.md +449 -0
  74. package/skills/ctf-misc/SKILL.md +498 -0
  75. package/skills/ctf-misc/bashjails.md +323 -0
  76. package/skills/ctf-misc/ctfd-navigation.md +465 -0
  77. package/skills/ctf-misc/dns.md +255 -0
  78. package/skills/ctf-misc/encodings-advanced.md +504 -0
  79. package/skills/ctf-misc/encodings.md +431 -0
  80. package/skills/ctf-misc/games-and-vms-2.md +254 -0
  81. package/skills/ctf-misc/games-and-vms-3.md +690 -0
  82. package/skills/ctf-misc/games-and-vms-4.md +229 -0
  83. package/skills/ctf-misc/games-and-vms.md +529 -0
  84. package/skills/ctf-misc/linux-privesc.md +333 -0
  85. package/skills/ctf-misc/pyjails.md +671 -0
  86. package/skills/ctf-misc/rf-sdr.md +91 -0
  87. package/skills/ctf-osint/SKILL.md +198 -0
  88. package/skills/ctf-osint/geolocation-and-media.md +464 -0
  89. package/skills/ctf-osint/social-media.md +312 -0
  90. package/skills/ctf-osint/web-and-dns.md +341 -0
  91. package/skills/ctf-pwn/SKILL.md +214 -0
  92. package/skills/ctf-pwn/advanced-exploits-2.md +579 -0
  93. package/skills/ctf-pwn/advanced-exploits-3.md +598 -0
  94. package/skills/ctf-pwn/advanced-exploits-4.md +590 -0
  95. package/skills/ctf-pwn/advanced-exploits-5.md +119 -0
  96. package/skills/ctf-pwn/advanced-exploits.md +773 -0
  97. package/skills/ctf-pwn/advanced.md +326 -0
  98. package/skills/ctf-pwn/field-notes.md +245 -0
  99. package/skills/ctf-pwn/format-string.md +694 -0
  100. package/skills/ctf-pwn/heap-fsop.md +285 -0
  101. package/skills/ctf-pwn/heap-techniques-2.md +333 -0
  102. package/skills/ctf-pwn/heap-techniques.md +513 -0
  103. package/skills/ctf-pwn/kernel-bypass.md +421 -0
  104. package/skills/ctf-pwn/kernel-techniques.md +366 -0
  105. package/skills/ctf-pwn/kernel.md +636 -0
  106. package/skills/ctf-pwn/overflow-basics.md +611 -0
  107. package/skills/ctf-pwn/rop-advanced.md +725 -0
  108. package/skills/ctf-pwn/rop-and-shellcode.md +659 -0
  109. package/skills/ctf-pwn/sandbox-escape.md +313 -0
  110. package/skills/ctf-reverse/SKILL.md +163 -0
  111. package/skills/ctf-reverse/anti-analysis-ctf.md +204 -0
  112. package/skills/ctf-reverse/anti-analysis.md +693 -0
  113. package/skills/ctf-reverse/field-notes.md +376 -0
  114. package/skills/ctf-reverse/languages-compiled.md +666 -0
  115. package/skills/ctf-reverse/languages-platforms.md +592 -0
  116. package/skills/ctf-reverse/languages.md +553 -0
  117. package/skills/ctf-reverse/patterns-ctf-2.md +397 -0
  118. package/skills/ctf-reverse/patterns-ctf-3.md +797 -0
  119. package/skills/ctf-reverse/patterns-ctf.md +670 -0
  120. package/skills/ctf-reverse/patterns-runtime.md +274 -0
  121. package/skills/ctf-reverse/patterns.md +572 -0
  122. package/skills/ctf-reverse/platforms-hardware.md +387 -0
  123. package/skills/ctf-reverse/platforms.md +664 -0
  124. package/skills/ctf-reverse/tools-advanced-2.md +421 -0
  125. package/skills/ctf-reverse/tools-advanced.md +407 -0
  126. package/skills/ctf-reverse/tools-dynamic.md +679 -0
  127. package/skills/ctf-reverse/tools-emulation.md +319 -0
  128. package/skills/ctf-reverse/tools.md +573 -0
  129. package/skills/ctf-web/SKILL.md +153 -0
  130. package/skills/ctf-web/auth-and-access-2.md +82 -0
  131. package/skills/ctf-web/auth-and-access.md +783 -0
  132. package/skills/ctf-web/auth-infra.md +321 -0
  133. package/skills/ctf-web/auth-jwt.md +186 -0
  134. package/skills/ctf-web/client-side-advanced.md +739 -0
  135. package/skills/ctf-web/client-side.md +529 -0
  136. package/skills/ctf-web/cves.md +373 -0
  137. package/skills/ctf-web/field-notes.md +482 -0
  138. package/skills/ctf-web/node-and-prototype.md +200 -0
  139. package/skills/ctf-web/server-side-2.md +337 -0
  140. package/skills/ctf-web/server-side-advanced-2.md +559 -0
  141. package/skills/ctf-web/server-side-advanced-3.md +125 -0
  142. package/skills/ctf-web/server-side-advanced-4.md +480 -0
  143. package/skills/ctf-web/server-side-advanced.md +378 -0
  144. package/skills/ctf-web/server-side-deser.md +443 -0
  145. package/skills/ctf-web/server-side-exec-2.md +799 -0
  146. package/skills/ctf-web/server-side-exec.md +457 -0
  147. package/skills/ctf-web/server-side.md +629 -0
  148. package/skills/ctf-web/sql-injection.md +790 -0
  149. package/skills/ctf-web/web3.md +374 -0
  150. package/skills/ctf-writeup/SKILL.md +90 -0
  151. package/skills/solve-challenge/SKILL.md +269 -0
  152. package/skills.json +16 -0
@@ -0,0 +1,464 @@
1
+ # Geolocation and Media Analysis
2
+
3
+ ## Table of Contents
4
+
5
+ - [Image Analysis](#image-analysis)
6
+ - [Reverse Image Search](#reverse-image-search)
7
+ - [Geolocation Techniques](#geolocation-techniques)
8
+ - [MGRS (Military Grid Reference System)](#mgrs-military-grid-reference-system)
9
+ - [Google Plus Codes / Open Location Codes (MidnightCTF 2026)](#google-plus-codes--open-location-codes-midnightctf-2026)
10
+ - [Metadata Extraction](#metadata-extraction)
11
+ - [Hardware/Product Identification](#hardwareproduct-identification)
12
+ - [Newspaper Archives and Historical Research](#newspaper-archives-and-historical-research)
13
+ - [Google Street View Panorama Matching (EHAX 2026)](#google-street-view-panorama-matching-ehax-2026)
14
+ - [Road Sign Language and Driving Side Analysis (EHAX 2026)](#road-sign-language-and-driving-side-analysis-ehax-2026)
15
+ - [Post-Soviet Architecture and Brand Identification (EHAX 2026)](#post-soviet-architecture-and-brand-identification-ehax-2026)
16
+ - [IP Geolocation and Attribution](#ip-geolocation-and-attribution)
17
+ - [Google Lens Cropped Region Search (UTCTF 2026)](#google-lens-cropped-region-search-utctf-2026)
18
+ - [Reflected and Mirrored Text Reading (UTCTF 2026)](#reflected-and-mirrored-text-reading-utctf-2026)
19
+ - [What3Words (W3W) Geolocation (UTCTF 2026)](#what3words-w3w-geolocation-utctf-2026)
20
+ - [Monumental Letters / Letreiro Identification (UTCTF 2026)](#monumental-letters--letreiro-identification-utctf-2026)
21
+ - [Google Maps Crowd-Sourced Photo Verification (MidnightCTF 2026)](#google-maps-crowd-sourced-photo-verification-midnightctf-2026)
22
+ - [Overpass Turbo Spatial Queries (LAB'OSINT 2025)](#overpass-turbo-spatial-queries-labosint-2025)
23
+ - [Music-Themed Landmark Geolocation with Key Encoding (BSidesSF 2026)](#music-themed-landmark-geolocation-with-key-encoding-bsidessf-2026)
24
+
25
+ ---
26
+
27
+ ## Image Analysis
28
+
29
+ - Discord avatars: Screenshot and reverse image search
30
+ - Identify objects in images (weapons, equipment) -> find character/faction
31
+ - No EXIF? Use visual features (buildings, signs, landmarks)
32
+ - **Visual steganography**: Flags hidden as tiny/low-contrast text in images (not binary stego)
33
+ - Always view images at full resolution and check ALL corners/edges
34
+ - Black-on-dark or white-on-light text, progressively smaller fonts
35
+ - Profile pictures/avatars are common hiding spots
36
+ - **Twitter strips EXIF** on upload - don't waste time on stego for Twitter-served images
37
+ - **Tumblr preserves more metadata** in avatars than in post images
38
+
39
+ ## Reverse Image Search
40
+
41
+ - Google Lens (crop to specific region, best for identifying landmarks/shops/signs)
42
+ - Google Images (most comprehensive)
43
+ - TinEye (exact match)
44
+ - Yandex (good for faces, Eastern Europe)
45
+ - Baidu Images / `graph.baidu.com` (best for Chinese locations — use when visual cues suggest China: blue license plates, simplified Chinese text, menlou gate architecture)
46
+ - Bing Visual Search
47
+
48
+ ## Geolocation Techniques
49
+
50
+ - Railroad crossing signs: white X with red border = Canada
51
+ - Use infrastructure maps:
52
+ - [Open Infrastructure Map](https://openinframap.org) - power lines
53
+ - [OpenRailwayMap](https://www.openrailwaymap.org/) - rail tracks
54
+ - High-voltage transmission line maps
55
+ - Process of elimination: narrow by country first, then region
56
+ - Cross-reference multiple features (rail + power lines + mountains)
57
+ - MGRS coordinates: grid-based military system (e.g., "4V FH 246 677") -> convert online
58
+
59
+ ## MGRS (Military Grid Reference System)
60
+
61
+ **Pattern (On The Grid):** Encoded coordinates like "4V FH 246 677".
62
+
63
+ **Identification:** Challenge title mentions "grid", code format matches MGRS pattern.
64
+
65
+ **Conversion:** Use online MGRS converter -> lat/long -> Google Maps for location name.
66
+
67
+ ## Google Plus Codes / Open Location Codes (MidnightCTF 2026)
68
+
69
+ **Pattern (Chine Zhao):** Flag format requires a Google Plus Code (e.g., `H9G2+47X`) instead of coordinates or W3W. Plus Codes are Google's open-source alternative to street addresses.
70
+
71
+ **Format:** `XXXX+XX` (short/local) or `8FVC9G8F+6W` (full/global). Characters from the set `23456789CFGHJMPQRVWX`. The `+` separator is always present.
72
+
73
+ **Generating a Plus Code:**
74
+ 1. Find the exact location on Google Maps
75
+ 2. Click the map to drop a pin at the precise spot
76
+ 3. The Plus Code appears in the location details panel (e.g., `H9G2+47X Handan, Hebei, China`)
77
+ 4. Or enter coordinates in the Google Maps search bar — the Plus Code shows in results
78
+
79
+ **Precision:** Standard Plus Codes resolve to ~14m x 14m areas (vs. W3W's 3m x 3m). Adding extra characters increases precision. Meter-level position changes can alter the code.
80
+
81
+ **Key insight:** Unlike W3W (proprietary, requires API key), Plus Codes are free and built into Google Maps. When a flag format shows `{XXXX+XXX}`, recognize it as a Plus Code. Position the Street View camera at the exact photo capture location, then read the Plus Code from the map pin.
82
+
83
+ **Reference:** https://maps.google.com/pluscodes/
84
+
85
+ ---
86
+
87
+ ## Metadata Extraction
88
+
89
+ ```bash
90
+ exiftool image.jpg # EXIF data
91
+ pdfinfo document.pdf # PDF metadata
92
+ mediainfo video.mp4 # Video metadata
93
+ ```
94
+
95
+ ## Hardware/Product Identification
96
+
97
+ **Pattern (Computneter, VuwCTF 2025):** Battery specifications -> manufacturer identification. Cross-reference specs (voltage, capacity, form factor) with manufacturer databases.
98
+
99
+ ## Newspaper Archives and Historical Research
100
+
101
+ - Scout Life magazine archive: https://scoutlife.org/wayback/
102
+ - Library of Congress: https://www.loc.gov/ (newspaper search)
103
+ - Use advanced search with date ranges
104
+
105
+ **Pattern (It's News, VuwCTF 2025):** Combine newspaper archive date search with EXIF GPS coordinates for location-specific identification.
106
+
107
+ **Tools:** Library of Congress newspaper archive, Google Maps for GPS coordinate lookup.
108
+
109
+ ## Google Street View Panorama Matching (EHAX 2026)
110
+
111
+ **Pattern (amnothappyanymore):** Challenge image is a cropped section of a Google Street View panorama. Must identify the exact panorama ID and coordinates.
112
+
113
+ **Approach:**
114
+ 1. **Extract visual features:** Identify distinctive landmarks (road type, vehicles, containers, mountain shapes, building styles, vegetation)
115
+ 2. **Narrow the region:** Use visual clues to identify country/region (e.g., Greenland landscape, specific road infrastructure)
116
+ 3. **Compile candidate panoramas:** Use Google Street View coverage maps to find panoramas in the identified region
117
+ 4. **Feature matching:** Compare challenge image features against candidate panoramas:
118
+ ```python
119
+ import cv2
120
+ import numpy as np
121
+
122
+ # Load challenge image and candidate panorama
123
+ challenge = cv2.imread('challenge.jpg')
124
+ candidate = cv2.imread('panorama.jpg')
125
+
126
+ # ORB feature detection and matching
127
+ orb = cv2.ORB_create(nfeatures=5000)
128
+ kp1, des1 = orb.detectAndCompute(challenge, None)
129
+ kp2, des2 = orb.detectAndCompute(candidate, None)
130
+
131
+ bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
132
+ matches = bf.match(des1, des2)
133
+ score = sum(1 for m in matches if m.distance < 50)
134
+ ```
135
+ 5. **Ranking systems:** Use multiple scoring methods (global feature match, local patch comparison, color histogram analysis) and combine rankings
136
+ 6. **API submission:** Submit panorama ID with coordinates in required format (e.g., `lat/lng/sessionId/nonce`)
137
+
138
+ **Google Street View API patterns:**
139
+ ```python
140
+ # Street View metadata API (check if coverage exists)
141
+ # GET https://maps.googleapis.com/maps/api/streetview/metadata?location=LAT,LNG&key=KEY
142
+
143
+ # Street View image API
144
+ # GET https://maps.googleapis.com/maps/api/streetview?size=640x480&location=LAT,LNG&heading=90&key=KEY
145
+
146
+ # Panorama ID from page source (parsed from JavaScript):
147
+ # Look for panoId in page data structures
148
+ ```
149
+
150
+ **Key insights:**
151
+ - Challenge images are often crops of panoramas — the crop region may not include horizon or sky, making geolocation harder
152
+ - Distinctive elements: road surface type, vehicle makes, signage language, utility poles, container colors
153
+ - Greenland, Iceland, Faroe Islands have limited Street View coverage — enumerate all panoramas in the region
154
+ - Image similarity ranking with multiple metrics (feature matching + color analysis + patch comparison) is more robust than any single method
155
+
156
+ ---
157
+
158
+ ## Road Sign Language and Driving Side Analysis (EHAX 2026)
159
+
160
+ **Pattern (date_spot):** Street view image of a coastal location. Identify exact coordinates from road infrastructure.
161
+
162
+ **Systematic approach:**
163
+ 1. **Driving side:** Left-hand traffic → right-hand drive countries (Japan, UK, Australia, etc.)
164
+ 2. **Sign language/script:** Kanji → Japan; Cyrillic → Russia/CIS; Arabic → Middle East/North Africa
165
+ 3. **Road sign style:** Blue directional signs with white text and route numbers → Japanese expressways
166
+ 4. **Sign OCR:** Extract text from directional signs to identify town/city names and route designations
167
+ 5. **Route tracing:** Search identified route number + town names to find the road corridor
168
+ 6. **Terrain matching:** Match coastline, harbors, lighthouses, bridges against satellite view
169
+
170
+ **Japanese infrastructure clues:**
171
+ - Blue highway signs with white Kanji + route numbers (e.g., E59)
172
+ - Distinctive guardrail style (galvanized steel, wavy profile)
173
+ - Concrete seawalls on coastal roads
174
+ - Small fishing harbors with white lighthouse structures
175
+
176
+ **General country identification shortcuts:**
177
+ | Feature | Country/Region |
178
+ |---------|---------------|
179
+ | Kanji + blue highway signs | Japan |
180
+ | Cyrillic + wide boulevards | Russia/CIS |
181
+ | White X-shape crossing signs | Canada |
182
+ | Yellow diamond warning signs | USA/Canada |
183
+ | Green autobahn signs | Germany |
184
+ | Brown tourist signs | France |
185
+ | Bollards with red reflectors | Netherlands |
186
+
187
+ ---
188
+
189
+ ## Post-Soviet Architecture and Brand Identification (EHAX 2026)
190
+
191
+ **Pattern (idinahui):** Coastal parking lot image. Identify location from architectural style, vehicle types, signage, and local brands.
192
+
193
+ **Recognition chain:**
194
+ 1. **Architecture:** Brutalist concrete buildings → post-Soviet region
195
+ 2. **Vehicles:** Reverse image search vehicle models to narrow to Russian/CIS market cars
196
+ 3. **Script:** Cyrillic signage confirms Russian-language region
197
+ 4. **Flags:** Regional government flags alongside national tricolor → identify specific federal subject
198
+ 5. **Brands:** Named restaurants/chains (e.g., "Mimino" — Georgian-themed chain popular across Russia) → search for geographic distribution
199
+ 6. **Coastal features:** Caspian Sea coastline + North Caucasus architecture → Dagestan/Makhachkala
200
+
201
+ **Key technique — restaurant/brand geolocation:**
202
+ - Identify any readable business name or brand logo
203
+ - Search for that business + "locations" or "branches"
204
+ - Cross-reference with other visual clues (coastline, terrain) to pinpoint exact branch
205
+ - Google Maps business search is highly effective for named establishments
206
+
207
+ **Post-Soviet visual markers:**
208
+ - Panel apartment blocks (khrushchyovka/brezhnevka)
209
+ - Wide boulevards with central medians
210
+ - Concrete bus stops
211
+ - Distinctive utility pole designs
212
+ - Soviet-era monuments and mosaics
213
+
214
+ ---
215
+
216
+ ## IP Geolocation and Attribution
217
+
218
+ **Free geolocation services:**
219
+ ```bash
220
+ # IP-API (no key required)
221
+ curl "http://ip-api.com/json/103.150.68.150"
222
+
223
+ # ipinfo.io
224
+ curl "https://ipinfo.io/103.150.68.150/json"
225
+ ```
226
+
227
+ **Bangladesh IP ranges (common in KCTF):**
228
+ - `103.150.x.x` - Bangladesh ISPs
229
+ - Mobile prefixes: +880 13/14/15/16/17/18/19
230
+
231
+ **Correlating location with evidence:**
232
+ - Windows telemetry (imprbeacons.dat) contains `CIP` field
233
+ - Login history APIs may show IP + OS correlation
234
+ - VPN/proxy detection via ASN lookup
235
+
236
+ ---
237
+
238
+ ## Google Lens Cropped Region Search (UTCTF 2026)
239
+
240
+ **Pattern (W3W1/W3W2):** Challenge image contains multiple elements but only one is useful for identification. Crop to just the relevant portion before searching.
241
+
242
+ **Technique:**
243
+ 1. Identify the most distinctive element in the image (shop sign, building facade, landmark)
244
+ 2. Crop the image to isolate that element — remove surrounding context that adds noise
245
+ 3. Search the cropped region using Google Lens (`lens.google.com` or right-click → "Search image with Google Lens" in Chrome)
246
+ 4. Review visually similar results to identify the specific location or business
247
+
248
+ **When to crop:**
249
+ - Shop fronts: crop to just the storefront and signage
250
+ - Landmarks: crop to the distinctive architectural feature
251
+ - Signs: crop to just the sign text
252
+ - Churches/buildings: crop to the unique facade
253
+
254
+ **Key insight:** Google Lens performs significantly better on cropped regions than full scene images. A full scene may return generic landscape results, while a cropped shop sign returns the exact business with its address.
255
+
256
+ **Example workflow (W3W2):**
257
+ 1. Challenge image shows a street scene with a shop
258
+ 2. Crop to just the shop portion
259
+ 3. Google Lens identifies the shop and its location
260
+ 4. Verify on Google Maps Street View
261
+ 5. Convert coordinates to What3Words
262
+
263
+ ---
264
+
265
+ ## Reflected and Mirrored Text Reading (UTCTF 2026)
266
+
267
+ **Pattern (W3W3):** Text visible in the image is reflected/mirrored (e.g., sign reflected in water or glass). Must read the text in reverse to identify the location.
268
+
269
+ **Technique:**
270
+ 1. Identify reflected text in the image (common in water reflections, glass surfaces, mirrors)
271
+ 2. Flip the image horizontally to read the text normally
272
+ 3. If text is partially obscured, search for the readable portion as a prefix/suffix:
273
+ - "Aguas de Lind..." → search `"Aguas de Lind"` → find "Aguas de Lindoia"
274
+ 4. Use the identified text to locate the place on Google Maps
275
+
276
+ **Partial text search strategies:**
277
+ ```text
278
+ # Search with wildcards/partial terms
279
+ "Aguas de Lind" # Quoted partial match
280
+ "Aguas de Lind" city # Add context keyword
281
+ "Aguas de Lind*" brazil # Add country if identifiable from image
282
+ ```
283
+
284
+ **Image flipping for reflected text:**
285
+ ```bash
286
+ # Flip image horizontally with ImageMagick
287
+ convert input.jpg -flop flipped.jpg
288
+
289
+ # Or with Python/PIL
290
+ python3 -c "
291
+ from PIL import Image
292
+ img = Image.open('input.jpg')
293
+ img.transpose(Image.FLIP_LEFT_RIGHT).save('flipped.jpg')
294
+ "
295
+ ```
296
+
297
+ **Key insight:** When a letter in reflected text is ambiguous (e.g., "T" vs "I"), try both variants as separate searches. Partial text searches with quoted strings are effective for identifying place names even with only 60-70% of the text readable.
298
+
299
+ ---
300
+
301
+ ## What3Words (W3W) Geolocation (UTCTF 2026)
302
+
303
+ **Pattern (W3W1/W3W2/W3W3):** Photo of a location. Find the exact What3Words address (3-meter precision grid). Flag format: `utflag{word1.word2.word3}`.
304
+
305
+ **What3Words basics:**
306
+ - Divides entire world into 3m x 3m squares, each with a unique 3-word address
307
+ - Words are in a SPECIFIC language (English by default)
308
+ - Adjacent squares have COMPLETELY different addresses (no spatial correlation)
309
+ - Website: https://what3words.com/
310
+
311
+ **Workflow:**
312
+ 1. **Identify the location** using standard geolocation techniques (reverse image search, landmarks, signs, architecture)
313
+ 2. **Get precise GPS coordinates** from Google Maps satellite view
314
+ 3. **Convert coordinates to W3W** using the website (enter coordinates in search bar)
315
+ 4. **Fine-tune:** The exact 3m square matters — shift coordinates by small amounts to check adjacent squares
316
+
317
+ **Coordinate-to-W3W conversion:**
318
+ ```text
319
+ # Navigate to what3words.com and enter coordinates:
320
+ # Format: latitude, longitude (e.g., 30.2870, -97.7415)
321
+ # Or click on the map at the exact location
322
+
323
+ # The W3W API requires an API key (not always available in CTF):
324
+ # GET https://api.what3words.com/v3/convert-to-3wa?coordinates=30.2870,-97.7415&key=API_KEY
325
+ ```
326
+
327
+ **Common pitfalls:**
328
+ - **3m precision matters:** A building entrance vs. its parking lot may have different W3W addresses. Match the EXACT viewpoint of the photo.
329
+ - **Camera position vs. subject:** The W3W address may refer to where the camera IS, not what it's pointed at.
330
+ - **Satellite vs. street-level:** Google Maps pin may not perfectly align with the actual W3W grid.
331
+ - **Multiple buildings nearby:** Churches, shops, and landmarks may have several candidate squares.
332
+
333
+ **Tips for accurate pinpointing:**
334
+ - Use Google Street View to match the exact camera angle
335
+ - Cross-reference with OpenStreetMap (OSM) for precise building footprints
336
+ - Try 5-10 adjacent W3W addresses around your best guess
337
+ - The challenge image often shows a specific feature (entrance, sign, landmark) — find THAT exact spot
338
+ - **Micro-landmark matching:** Identify small distinctive features in the challenge image (utility poles, pathway rocks, bollards, planters) and locate the same features in Street View to pinpoint the exact 3m square
339
+ - **Background building triangulation:** Match buildings visible in the background from the challenge image angle. Find those same buildings in Street View, then determine where the camera must be positioned to produce the same perspective
340
+ - **Geographic feature narrowing:** When you know the city but not the exact spot, use distinctive geographic features (lakes, rivers, coastline) visible in the image to narrow the search area before switching to Street View
341
+
342
+ ---
343
+
344
+ ## Monumental Letters / Letreiro Identification (UTCTF 2026)
345
+
346
+ **Pattern (W3W3):** Photo of large 3D letters spelling a city/location name, often reflected in a pool of water. Common in Latin American cities as tourist landmarks.
347
+
348
+ **Identification clues:**
349
+ - Large colorful 3D block letters
350
+ - Often located in main plaza (praça) or tourist area
351
+ - May include city name in local language
352
+ - Reflection in decorative water pool is a common design
353
+
354
+ **Search strategy:**
355
+ - Google: `"letras monumentales" [city name]` or `"letreiro turistico" [city]`
356
+ - OpenStreetMap: search for nodes tagged as `tourism=attraction` near the city center
357
+ - Google Maps: search `[city name] sign` or `[city name] letters` and check photos
358
+
359
+ **Key insight:** These monumental letter installations ("letras monumentales" in Spanish, "letreiro turistico" in Portuguese) are extremely common in Latin American cities. The exact GPS coordinates of the installation can be found on OpenStreetMap or Google Maps photo pins.
360
+
361
+ ---
362
+
363
+ ## Google Maps Crowd-Sourced Photo Verification (MidnightCTF 2026)
364
+
365
+ **Pattern (Where was Chine):** Verify a candidate location by matching a challenge image against user-submitted Google Maps photos for that place.
366
+
367
+ **Workflow:**
368
+ 1. Identify a candidate location name from other OSINT clues (Strava GPS routes, address research, social media posts)
369
+ 2. Search the location name on Google Maps
370
+ 3. Click the location pin and browse the **Photos** tab (user-submitted images)
371
+ 4. Compare scene elements (buildings, trees, paths, water features, signage) against the challenge image
372
+ 5. Match confirms the location — the place name is typically the flag
373
+
374
+ **When to use:** After narrowing to a candidate location through non-visual OSINT (fitness routes, addresses, social connections), use Google Maps photos as final visual confirmation. Especially useful for parks, plazas, and landmarks where many tourists upload photos.
375
+
376
+ **Key insight:** Google Maps aggregates crowd-sourced photos tagged to specific locations. Even when reverse image search fails (because the challenge image is original, not scraped), the same physical scene appears in tourist photos. Search by place name, not by image.
377
+
378
+ ---
379
+
380
+ ## Overpass Turbo Spatial Queries (LAB'OSINT 2025)
381
+
382
+ **Pattern (Portrait robot):** Find a specific business (newsagent) near a metro entrance in a known city. Overpass Turbo queries OpenStreetMap data to locate POIs by type within a radius of other POIs.
383
+
384
+ **Tool:** https://overpass-turbo.eu/
385
+
386
+ **Example — find newsagents within 10m of metro entrances in Barcelona:**
387
+ ```text
388
+ [out:json][timeout:25];
389
+ {{geocodeArea:Barcelona}}->.searchArea;
390
+
391
+ (
392
+ node["railway"="subway_entrance"](area.searchArea);
393
+ )->.metros;
394
+
395
+ (
396
+ node(around.metros:10)["shop"~"newsagent|kiosk"];
397
+ way(around.metros:10)["shop"~"newsagent|kiosk"];
398
+ );
399
+
400
+ out body;
401
+ >;
402
+ out skel qt;
403
+ ```
404
+
405
+ **Common query patterns for OSINT:**
406
+ ```text
407
+ # All cafes near train stations in a city
408
+ {{geocodeArea:CityName}}->.a;
409
+ node["railway"="station"](area.a)->.stations;
410
+ node(around.stations:50)["amenity"="cafe"];
411
+
412
+ # All ATMs in a neighborhood
413
+ node["amenity"="atm"]({{bbox}});
414
+
415
+ # Hotels near a specific coordinate (lat,lon)
416
+ node(around:200,48.8566,2.3522)["tourism"="hotel"];
417
+ ```
418
+
419
+ **Key OSM tags for OSINT challenges:**
420
+
421
+ | Tag | Values |
422
+ |-----|--------|
423
+ | `shop` | `newsagent`, `kiosk`, `bakery`, `supermarket` |
424
+ | `amenity` | `cafe`, `restaurant`, `bank`, `atm`, `pharmacy` |
425
+ | `tourism` | `hotel`, `attraction`, `museum`, `viewpoint` |
426
+ | `railway` | `station`, `subway_entrance`, `halt` |
427
+
428
+ **Key insight:** When a challenge image shows a business near a transit stop in a known city, Overpass Turbo can narrow candidates to a handful of locations by querying for the business type within a small radius of transit nodes. Verify each result with Google Street View. The `around` operator (proximity filter) is the most useful feature — it replaces hours of manual map browsing.
429
+
430
+ ---
431
+
432
+ ## Music-Themed Landmark Geolocation with Key Encoding (BSidesSF 2026)
433
+
434
+ **Pattern (strike-a-coord):** 14 images of music-themed landmarks worldwide. For each location:
435
+ 1. Identify the landmark via visual clues (signage, architecture, flags, distinctive features)
436
+ 2. Each landmark has a musical connection (composer birthplace, concert hall, music museum)
437
+ 3. A visual element at each location maps to a specific piano key number
438
+ 4. The sequence of piano key numbers encodes the flag
439
+
440
+ Geolocation techniques used:
441
+ - **Signage/text:** Readable signs narrow to city/country (e.g., "BTHVN" = Beethoven birthplace in Bonn)
442
+ - **Architecture style:** Building materials, roof shapes, window designs identify regions
443
+ - **National flags/emblems:** Visible flags or government buildings identify country
444
+ - **Google Lens/reverse image search:** Match distinctive building facades
445
+ - **Street View confirmation:** Verify candidate locations via Google Street View
446
+
447
+ ```python
448
+ # Piano key encoding: each landmark yields a key number (1-88)
449
+ # Key numbers map to characters
450
+ piano_keys = [35, 67, 42, ...] # Recovered from each landmark
451
+
452
+ # Common encodings: direct ASCII, MIDI note numbers, or custom mapping
453
+ flag = ""
454
+ for key in piano_keys:
455
+ # If keys map to ASCII: key + offset
456
+ flag += chr(key + 32) # Example offset
457
+ print(flag)
458
+ ```
459
+
460
+ **Key insight:** Multi-location OSINT challenges combine traditional geolocation (landmark identification) with a secondary encoding layer. The "piano key" or "musical note" at each location extracts one character of the flag. Solve strategy: identify all locations first (the easier part), then determine the encoding scheme from the per-location data points.
461
+
462
+ **When to recognize:** Challenge provides multiple images with a musical or thematic thread. Each image requires individual geolocation. The flag isn't at any single location — it's encoded across all of them.
463
+
464
+ **References:** BSidesSF 2026 "strike-a-coord"