3.4 KiB
LeaseMesh
LeaseMesh позволяет создавать, просматривать, закрывать и пересылать «аренды» маршрутов. В раздатке есть ELF lease-mesh с PIE и сохранёнными символами. Для получения флага нужно узнать адрес flag_export и подменить обработчик маршрута.
Решение
У маршрута размер 144 байта. Для атаки важны следующие поля:
| Смещение | Поле | Назначение |
|---|---|---|
| 0 | magic, 8 байт |
0x4c454153454d4553 |
| 8 | name[24] |
Имя маршрута |
| 32 | generation, 8 байт |
Поколение объекта |
| 40 | handler, 8 байт |
Указатель на обработчик |
| 48 | approved, 4 байта |
Для экспорта нужно 0x51524f4b |
| 52 | memo_len, 4 байта |
Длина заметки |
| 56 | memo[88] |
Сама заметка |
Открываем маршрут в слоте 0 через 1) open route lease, имя и заметка любые. В пункте 4) inspect route выбираем слот 0. Из handler=%p получаем адрес route_status в запущенном процессе и сохраняем его числом в leaked_handler. Через readelf -sW public/lease-mesh находим значения символов route_status и flag_export. Смещения относительно базы PIE обозначим offset_route_status и offset_flag_export. Вычитаем первое из утечки и прибавляем второе:
pie_base = leaked_handler - offset_route_status
target = pie_base + offset_flag_export
Теперь освобождаем маршрут через 2) close route lease, указывая слот 0. В close_route есть free(routes[idx]), но нет обнуления routes[idx]. Значит, слот продолжает ссылаться на освобождённую память.
Пункт 3) import raw decoder packet выделяет ровно sizeof(struct route) и заполняет блок переданными байтами. Собираем подделку:
import struct
payload = struct.pack("<Q", 0x4c454153454d4553)
payload += b"export-reclaim".ljust(24, b"\x00")
payload += struct.pack("<QQII", 0x2605061337, target, 0x51524f4b, 0)
payload = payload.ljust(144, b"\x00")
Выбираем 3) import raw decoder packet. На запрос raw packet bytes: отправляем строку 144, затем на packet payload: передаём 144 байта payload без добавленного перевода строки.
После переиспользования блока routes[0] указывает на этот пакет как на настоящий маршрут. Вызываем 5) dispatch route, слот 0. Поля magic и approved содержат ожидаемые значения, а handler указывает на flag_export.
Флаг
caplag{stale_handle_reclaimed_the_route}