Init. import
This commit is contained in:
78
MEGA-router/writeup_tasks_1_2.md
Normal file
78
MEGA-router/writeup_tasks_1_2.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Разбор решения MEGA-router: задачи 1 и 2
|
||||
|
||||
Ниже разбор решения первых двух задач. Сначала общий вход (как получить бинарник), затем отдельно по каждому флагу.
|
||||
|
||||
## Общий вход: утечка бинарника через /ping
|
||||
|
||||
- Авторизация не нужна: `logged_in()` просто проверяет, что в Cookie есть и `username=`, и `password=`; значения не важны (`challenge/src/server_http.hpp`). Альтернатива — дефолтные креды `admin/admin` или `admin/admin888` (`challenge/src/server.cpp`).
|
||||
- `/ping?id=...` читает 4096 байт из `Global.BUFFER + offset*4096` без проверки границ и отдает base64 (`challenge/src/server.cpp`). Падение дочернего процесса дает пустой `result`, сервер не падает.
|
||||
- Зацепка: зайти на `/portal` с любыми Cookie `username=...; password=...` и открыть `main.js` — там видно, что клиент делает `POST /ping` и затем многократные `GET /ping?id=...`, то есть это ключевая точка.
|
||||
- Так как `offset` — беззнаковый и `-` запрещен, читаем «назад» через переполнение: `4096 = 2^12`, значит `2^64/4096 = 2^52`. Берем `offset = 2^52 - N`, получаем адрес `BUFFER - N*4096`. Этим выходим на `.text`/`.rodata` и находим ELF.
|
||||
- Минимальный запрос, который дает первую зацепку в ответе (base64-кусок памяти) и позволяет начать сканировать ELF:
|
||||
|
||||
```
|
||||
GET /ping?id=4503599627370495 HTTP/1.1
|
||||
Host: <host>:31337
|
||||
Cookie: username=a; password=b
|
||||
```
|
||||
- Дальше — обычный дамп страниц и склейка в файл; можно искать строку `ELF` или специфичные строки вида `/giv_me_please_flag_...`.
|
||||
|
||||
## Задача 1 (Flag 1)
|
||||
|
||||
- В бинарнике виден скрытый эндпоинт `"/giv_me_please_flag_nu_ochen_nado"` (`challenge/src/server.cpp`).
|
||||
- Делаем GET на него, ответ — редирект на `/index` с заголовком `Flag: <base64>`. Декодируем base64.
|
||||
- Дешифрование: байты зашифрованы `ROTR3` после XOR с `(i*4 + 0xc0)`. Значит, для каждого байта: `ROTL3`, затем XOR.
|
||||
|
||||
```python
|
||||
import base64
|
||||
|
||||
def rotl8(x, n):
|
||||
return ((x << n) | (x >> (8 - n))) & 0xff
|
||||
|
||||
cipher = base64.b64decode(flag_header)
|
||||
plain = bytes(
|
||||
rotl8(b, 3) ^ ((i * 4 + 0xC0) & 0xff)
|
||||
for i, b in enumerate(cipher)
|
||||
)
|
||||
print(plain.decode())
|
||||
```
|
||||
|
||||
- Итоговый флаг: `caplag{r0ut3r_p0rtals_ar3_ult1mat3ly_imp3n3trabl3_b3caus3_th3y_ar3_r3al_w3bapp}`.
|
||||
|
||||
## Задача 2 (Flag 2)
|
||||
|
||||
- В логике `/login` видно, что для юзера `hoEjB9OtHLCuDibAT6Ag` вызывается `gen_flag`, но он защищен длинной подстрокой и MD5 (прямой вызов нецелесообразен) (`challenge/src/server.cpp`).
|
||||
- В `gen_flag` видно массив `flag_byte_offsets[]` и схему: берется `pi_bytes.bin` (2048 байт, соответствуют позициям 1_000_000..1_002_047), а флаг строится как `bytes[offset - 1_000_000]`.
|
||||
- Поэтому нужно: (1) вытащить `flag_byte_offsets[]` из слитого бинарника; (2) сгенерировать байты π для диапазона 1_000_000..1_002_047. Функция `get_byte` — это две hex‑цифры π подряд. Быстро считается через BBP (как в `#ifdef DEBUG` части, `challenge/src/server.cpp`).
|
||||
|
||||
```python
|
||||
def pi_hex_digit(n):
|
||||
n -= 1
|
||||
def series(m):
|
||||
s = 0.0
|
||||
for k in range(n + 1):
|
||||
ak = 8 * k + m
|
||||
s = (s + pow(16, n - k, ak) / ak) % 1.0
|
||||
k = n + 1
|
||||
t = 1.0
|
||||
while True:
|
||||
ak = 8 * k + m
|
||||
t /= 16.0
|
||||
term = t / ak
|
||||
if term < 1e-17:
|
||||
break
|
||||
s = (s + term) % 1.0
|
||||
k += 1
|
||||
return s
|
||||
x = (4*series(1) - 2*series(4) - series(5) - series(6)) % 1.0
|
||||
return int(x * 16)
|
||||
|
||||
def get_byte(pos):
|
||||
return (pi_hex_digit(pos) << 4) | pi_hex_digit(pos + 1)
|
||||
|
||||
pi_bytes = [get_byte(p) for p in range(1_000_000, 1_002_048)]
|
||||
flag = ''.join(chr(pi_bytes[o - 1_000_000]) for o in offsets)
|
||||
print(flag)
|
||||
```
|
||||
|
||||
- Итоговый флаг: `caplag{leibniz_david_bailey_peter_b0rwein_and_sim0n_pl0uffe_good_idea_guys_00}`.
|
||||
Reference in New Issue
Block a user