Files
Tajna-tretej-stolicy/pwn-бортовой-журнал/WRITEUP.md
2026-04-22 10:58:32 +03:00

3.0 KiB
Raw Blame History

Бортовой Журнал

PWN 1000 pts

Сервис принимает JSON-программы и выполняет над буферами операции в стиле мини-VM: alloc, write, read, compute, typeof, free, realloc. Вычислительные функции (xor, rot, rev) лежат внутри C-таблицы указателей dispatch_table — и это уже подозрительно, потому что в бинарнике есть скрытая функция победы win_fn, читающая /tmp/flag. Нужно подложить её адрес в dispatch_table и вызвать обычным compute.

Решение

Атака склеивается из двух багов:

Баг Что делает
typeof сливает адреса Возвращает data_ptr буфера, адрес dispatch_table и адрес _emergency_nav (= win_fn)
write не проверяет offset dest = buffer.DataPtr + offset — можно писать куда угодно относительно буфера

Подбираем offset = dispatch_table - data_ptr, и запись в буфер улетает прямиком в таблицу указателей. По сути, воспроизводится тот же принцип, что и классический GOT overwrite, просто вместо Global Offset Table — user-space jump table.

Эксплуатация в два раунда. В первом — выделяем два буфера и снимаем адреса через typeof:

{
  "program": [
    {"op": "alloc", "id": "a", "size": 256},
    {"op": "alloc", "id": "b", "size": 256},
    {"op": "typeof", "id": "a"}
  ]
}

Из ответа забираем три адреса:

data_ptr        — адрес буфера a
dispatch        — адрес dispatch_table
_emergency_nav  — адрес win_fn

Во втором раунде считаем offset = dispatch - data_ptr, пишем в буфер a по этому смещению p64(win_addr) — и переписываем dispatch_table[0] (слот xor) адресом win_fn. Дальше compute("b", "xor") вместо честной xor-функции вызывает win_fn, та кладёт флаг в буфер b, и обычный read с base64-декодом выдаёт результат:

{
  "program": [
    {"op": "write", "id": "a", "data": "<p64(win)>", "offset": "<dispatch-data_ptr>"},
    {"op": "compute", "id": "b", "func": "xor"},
    {"op": "read", "id": "b", "count": 256}
  ]
}

Флаг

caplag{p3g4s_d1sp4tch_t4bl3_3xpl01t3d}