Files
2026-04-22 10:58:32 +03:00

73 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<h1 align="center">Пропавший коллега</h1>
<p align="center">
<img src="https://img.shields.io/badge/category-Forensic-blueviolet" alt="Forensic"/>
<img src="https://img.shields.io/badge/points-916-orange" alt="916 pts"/>
</p>
В руках — пачка артефактов сотрудника компании NordTech:
| Артефакт | Что содержит |
|---|---|
| `resume.pdf` | Резюме, ID сотрудника `NT-3893` |
| `business_card.png` | Визитка с ИНН |
| `commits.log` | Лог коммитов внутреннего репозитория |
| `profile_photo.jpg` | Фото с EXIF |
| `postal_codes.csv` | База почтовых индексов с координатами |
| `repo_snapshot.txt` | Снимок внешнего репозитория |
| `browser_render.png` | Скриншот из браузера |
Флаг собирается из четырёх частей, и каждая спрятана в своей цепочке.
## Решение
**Часть 1 — `br34d`.** В `resume.pdf` в профиле сотрудника указан ID `NT-3893`. В `business_card.png` — ИНН `7707083893`, и последние четыре цифры совпадают с ID. Сотрудник привязан к NordTech. Лезем в `commits.log`:
```text
feat(NT-3893): integrate module-br34d
```
Регуляркой `feat\(NT-3893\): integrate module-(\w+)` выдёргиваем кодовое слово — `br34d`.
**Часть 2 — `crumbs`.** Из EXIF `profile_photo.jpg` вытаскиваем GPS, конвертируем DMS в десятичные:
```text
55.7616 N, 37.6385 E → район Чистопрудного бульвара, Москва
```
Идём в `postal_codes.csv` и ищем ближайшую точку по манхэттенскому расстоянию. Находится запись:
```text
postal_code = 101000
sector_code = 6372756d6273
```
Декодируем hex → ASCII:
```text
63 72 75 6d 62 73 → c r u m b s
```
Вторая часть — `crumbs`.
**Часть 3 — `l34d` .** В `commits.log` кроме «нашего» коммита торчит отсылка на внешний репо вида `See commit <sha> in <repo>`. Вытаскиваем короткий SHA (7 символов) и имя репо регуляркой `See commit\s+(\w+)\s+in\s+([\w\-\.\/]+)`. Идём в `repo_snapshot.txt` и находим блок именно этого коммита (от нашего SHA до следующего полного 40-символьного). Внутри блока ищем base64-строки длиной от 20 символов — одна декодируется в:
```text
module-l34d-integration-v2.1.0
```
Первый сегмент после `module-` до дефиса — `l34d`.
**Часть 4 — `h0m3`.** Открываем картинку в RGBA через PIL, разворачиваем красный канал в одномерный массив, идём по пикселям и забираем младшие биты. Каждые 8 подряд складываются в байт (MSB первым). Нулевой байт — маркер конца. *Есть один мелкий нюанс*: сырой вывод начинается с трассировочного префикса вида `[N/4]`его срезаем регуляркой `\[\d/\d\](.*)`. Остаётся `h0m3`.
Склеиваем через `_`:
```text
br34d + crumbs + l34d + h0m3 = br34d_crumbs_l34d_h0m3
```
Готовый солвер — [`solve/solver.py`](solve/solver.py).
## Флаг
`caplag{br34d_crumbs_l34d_h0m3}`