# NarodUslugi - полный разбор (пошагово) Этот разбор объясняет, как устроен сервис и как решатель получает флаг. Ссылки идут на локальные файлы задачи в этой директории. ## 1) Входные данные и их источники - URL цели, partA и user можно читать из `target.txt` или передать через CLI. - Поведение сервера описано в `files/server.js`. - Логика решателя находится в `solver.py`. - Значения окружения указаны в `web_naroduslugi_6.yml`. ## 2) Формула пароля (на сервере) В `files/server.js` сервер считает пароль так: - `PASS = sha1(f"{PWD_PART_A}:{PWD_PART_B}").hexdigest()[:12]` `partA` у нас есть, но `partB` скрыт. ## 3) Где спрятан partB Эндпоинт `/assets/app.js.map` отдает sourcemap со строкой: - `pepper_xor_hex` (hex-строка) Она вычисляется так: - `pepper_xor_hex = xorHex(PWD_PART_B, sha1(user)[:6])` Значит `partB` можно восстановить, если известен `user`. ## 4) Как восстановить partB Шаги, которые делает `solver.py`: 1. `mask = sha1(user).digest()[:6]` 2. Преобразовать `pepper_xor_hex` в байты. 3. XOR-нуть каждый байт с `mask` (по кругу). 4. Декодировать результат как UTF-8 и получить `partB`. После этого вычисляется пароль: - `password = sha1(f"{partA}:{partB}").hexdigest()[:12]` ## 5) Trusted-device логин для доступа к экспорту профиля Есть альтернативная авторизация, описанная в `/.well-known/`: - Заголовки: `X-TS` и `X-Trusted-Device` - `X-Trusted-Device = hex(hmac_sha1(pass, ts))` - `ts` должен быть в окне 120 секунд Если заголовки валидны, сессия помечается как `mfa=true`, но `mfaOtp=false`. Это дает доступ к `/profile` и `/profile/export`. ## 6) Экспорт OTP-секрета отдается с маской `/profile/export?fmt=ini` возвращает: - `otp_secret` с заменой последних 2 base32-символов на `??` Есть CSRF-проверка: нужен `Referer: /profile`. Решатель выставляет этот заголовок. ## 7) Брут последних 2 base32-символов Алфавит base32 длиной 32, значит всего 32 * 32 = 1024 вариантов. Решатель перебирает все кандидаты: 1. Логинится обычным способом (без trusted заголовков). 2. Считает TOTP для кандидата. 3. POST на `/mfa` с `otp`. 4. При успехе открывает `/wallet` и `/wallet/drain`. ## 8) Синхронизация времени Решатель читает `/__status__`, чтобы получить смещение времени сервера и учитывать его при генерации TOTP (защита от дрейфа часов). ## 9) Получение флага Если OTP верный, сессия получает `mfaOtp=true`, и `/wallet/drain` возвращает флаг. ## 10) Важные ловушки - Повторный trusted-логин во время активного окна доверия вызывает бан. - Если trusted-сессия протухла без OTP, при следующем запросе будет бан. - Решатель использует отдельные cookie-jar и лимит попыток на сессию.