Init. commit
This commit is contained in:
133
forensic-needle-harbor-lab/WRITEUP.md
Normal file
133
forensic-needle-harbor-lab/WRITEUP.md
Normal file
@@ -0,0 +1,133 @@
|
||||
<h1 align="center">Needle Harbor</h1>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/category-Forensic-blueviolet" alt="Forensic"/>
|
||||
<img src="https://img.shields.io/badge/points-Σ_5520-orange" alt="Σ 5520 pts"/>
|
||||
</p>
|
||||
|
||||
<p align="center"><sub><b>этапы:</b> 888 · 919 · 923 · 927 · 930 · 933</sub></p>
|
||||
|
||||
У нас в руках два артефакта:
|
||||
|
||||
| Файл | Назначение |
|
||||
|---|---|
|
||||
| `needleharbor_mem.elf.zst` | Дамп памяти живой Tails-сессии |
|
||||
| `needleharbor_usb.img` | ext4-образ съёмного носителя, label `INCIDENTUSB` |
|
||||
|
||||
На первые четыре вопроса ответы вытаскиваются из строк и ext4-структур, на два hard-уровня — через deleted-file recovery и расшифровку OpenSSL-контейнера.
|
||||
|
||||
## Решение
|
||||
|
||||
Перед стартом распаковываем дамп и смотрим на типы:
|
||||
|
||||
```bash
|
||||
zstd -d public/needleharbor_mem.elf.zst -o needleharbor_mem.elf
|
||||
file needleharbor_mem.elf # ELF 64-bit LSB core file
|
||||
file public/needleharbor_usb.img # Linux ext4 filesystem, label "INCIDENTUSB"
|
||||
```
|
||||
|
||||
**Easy 1 — label съёмного носителя.** `file` прямо по образу честно пишет `volume name "INCIDENTUSB"`. Подтверждаем:
|
||||
|
||||
```bash
|
||||
strings -a needleharbor_mem.elf | grep "by-label/"
|
||||
# → /dev/disk/by-label/INCIDENTUSB
|
||||
```
|
||||
|
||||
Флаг: `caplag{INCIDENTUSB}`.
|
||||
|
||||
**Easy 2 — active operator handle.** Выполняем атрибуцию через HTML интерфейса:
|
||||
|
||||
```bash
|
||||
strings -a needleharbor_mem.elf | grep -i "Restricted Logistics"
|
||||
# → <title>Needle Harbor // Restricted Logistics Console</title>
|
||||
strings -a needleharbor_mem.elf | grep "ebb_"
|
||||
```
|
||||
|
||||
Находятся два кандидата:
|
||||
|
||||
| Handle | Местоположение | Статус |
|
||||
|---|---|---|
|
||||
| `ebb_tide_77` | `<div class="value">` в live dashboard | active |
|
||||
| `ebb_drift_12` | `<!-- archive handle: -->` | archived |
|
||||
|
||||
Рядом с `ebb_tide_77` — `Credential Alias: needle_harbor` и `Export Queue: 3 ready`. Флаг: `caplag{ebb_tide_77}`.
|
||||
|
||||
**Medium 1 — имя удалённого auth-файла.** Переходим к USB-образу:
|
||||
|
||||
```bash
|
||||
debugfs -R "ls /" public/needleharbor_usb.img
|
||||
# → creds exports lost+found notes ops
|
||||
debugfs -R "cat /ops/import_checklist.txt" public/needleharbor_usb.img
|
||||
```
|
||||
|
||||
В `import_checklist.txt` прямым текстом расписана процедура:
|
||||
|
||||
1. Импортировать `creds/needle_harbor.auth_private` в client authorization store.
|
||||
2. Удалить `creds/needle_harbor.auth_private` с носителя после импорта.
|
||||
3. Не трогать `creds/pilot_lamp.auth` — stale public decoy.
|
||||
|
||||
Проверяем текущее состояние:
|
||||
|
||||
```bash
|
||||
debugfs -R "ls /creds" public/needleharbor_usb.img
|
||||
# → needle_harbor.auth pilot_lamp.auth
|
||||
```
|
||||
|
||||
Файла `needle_harbor.auth_private` нет — удалён по инструкции. Флаг: `caplag{needle_harbor.auth_private}`.
|
||||
|
||||
**Medium 2 — FQDN clearnet-хоста в Unsafe Browser.** В Tails два браузера: Tor Browser (всё через Tor) и Unsafe Browser (прямой clearnet). Ищем следы второго:
|
||||
|
||||
```bash
|
||||
strings -a needleharbor_mem.elf | grep -i "unsafe-browser"
|
||||
strings -a needleharbor_mem.elf | grep "Quayside Relay"
|
||||
# → <title>mail.quayside-relay.net // Quayside Relay</title>
|
||||
# → <h1>mail.quayside-relay.net</h1>
|
||||
```
|
||||
|
||||
`mail.breakwater-relay.net` тоже мелькает, но только в комментариях и `Previous relay` — decoy. Флаг: `caplag{mail.quayside-relay.net}`.
|
||||
|
||||
**Hard 1 — восстановление x25519 private key.** Файл удалён, идём в deleted-file recovery через ext4 inode. [`debugfs -R "lsdel"`](https://man7.org/linux/man-pages/man8/debugfs.8.html) выдаёт список удалённых inode, перебираем и дампим:
|
||||
|
||||
```bash
|
||||
mkdir -p /tmp/needleharbor_recover
|
||||
for inode in $(debugfs -R "lsdel" public/needleharbor_usb.img 2>/dev/null \
|
||||
| awk 'NR>3 && $1 ~ /^[0-9]+$/ {print $1}'); do
|
||||
debugfs -R "dump <$inode> /tmp/needleharbor_recover/$inode.bin" \
|
||||
public/needleharbor_usb.img >/dev/null 2>&1 || true
|
||||
done
|
||||
grep -ra "descriptor:x25519:" /tmp/needleharbor_recover/
|
||||
```
|
||||
|
||||
Результат — в формате [Tor v3 onion client auth](https://community.torproject.org/onion-services/advanced/client-auth/):
|
||||
|
||||
```text
|
||||
<onion>.onion:descriptor:x25519:QB2WNKDR73DUR2TNUI4HVHJBP4PNOAZU6FUDFT6KRVF5UT4A3FXA
|
||||
```
|
||||
|
||||
Ответ: `caplag{QB2WNKDR73DUR2TNUI4HVHJBP4PNOAZU6FUDFT6KRVF5UT4A3FXA}`.
|
||||
|
||||
**Hard 2 — расшифровка offline-экспорта.** Извлекаем `exports/restricted_drop.enc` — `file` опознаёт его как `openssl enc'd data with salted password`. В качестве пароля отлично подходит credential из hard 1:
|
||||
|
||||
```bash
|
||||
openssl enc -d -aes-256-cbc -pbkdf2 \
|
||||
-in restricted_drop.enc -out restricted_drop.tar \
|
||||
-k QB2WNKDR73DUR2TNUI4HVHJBP4PNOAZU6FUDFT6KRVF5UT4A3FXA
|
||||
tar -xf restricted_drop.tar
|
||||
cat manifest.txt
|
||||
```
|
||||
|
||||
Внутри `manifest.txt` — release token. Флаг: `caplag{tor_did_not_fail_opsec_did}`.
|
||||
|
||||
## Все этапы
|
||||
|
||||
| # | Уровень | Вопрос | Ответ |
|
||||
|---|---|---|---|
|
||||
| 1 | Easy | USB label | `caplag{INCIDENTUSB}` |
|
||||
| 2 | Easy | Active operator handle | `caplag{ebb_tide_77}` |
|
||||
| 3 | Medium | Deleted auth filename | `caplag{needle_harbor.auth_private}` |
|
||||
| 4 | Medium | Unsafe Browser host | `caplag{mail.quayside-relay.net}` |
|
||||
| 5 | Hard | x25519 private key | `caplag{QB2WNKDR73DUR2TNUI4HVHJBP4PNOAZU6FUDFT6KRVF5UT4A3FXA}` |
|
||||
| 6 | Hard | Final flag | `caplag{tor_did_not_fail_opsec_did}` |
|
||||
|
||||
## Итоговый флаг
|
||||
`caplag{tor_did_not_fail_opsec_did}`
|
||||
Reference in New Issue
Block a user