Long-short story about TPRO

Long-short story about TPRO

By Vladislav Shevchenko (@destr4ct)

Из года в год Apple продолжает тихо (или не очень) закручивать гайки, внедряя все новые защиты в iOS. И многие из них уже описаны ресерчерами. Но сегодня мне хотелось бы рассказать про что-то новое – TPRO регионы, которые появились в ещё ~22C152, но все это время почему-то оставались в тени!

TPRO (Trusted Path Read-Only, maybe) – это механизм защиты данных от перезаписи с помощью arbitrary-write, основанный на SPRR. Проще всего представить его как трамплин, что делает память доступной на запись в рамках критической зоны. Идеальный пример для рассмотрения – одна из функций dyld.

_dyld_call_with_writable_tpro_memory (23C5033h)

Первый шаг работы трамплина –  проверка в commpage @0xfffffc10c что у таргета есть хардварная поддержка TPRO. Скорее всего это поле cp_aprr_shadow_supported из OSS-хедеров. Также в commpage @0xfffffc0d0 хранятся два значения для S3_6_C15_C1_5, различающиеся лишь одним битом для девятого атрибута.

x/xg commpage

Совмещая это со знаниями об SPRR (S3_6_C15_C1_5 хранит значение, которое разбивается на 16 атрибутов, каждый из которых отражает пермишены типа страниц для разных EL) получаем, что первое значение представляет RW права (3 = 0011), а второе – RO (2 = 0010).

Value to permissions table

Следующий шаг – это как раз замена S3_6_C15_C1_5 на cp_aprr_shadow_tpro_rw из commpage, что (после выполнения isb) и меняет пермишены у всех TPRO страниц.

С этого момента память становится доступна на запись; запускается callback, после завершения выполнения которого аналогичной процедурой пермишены возвращаются в нормальное состояние – и при попытке записи процесс будет убиваться ядром с OS_REASON_SELF_RESTRICT.

Вот и вся защита! С одной стороны столь примитивная (но явно усложняющая жизнь тем же пывнерам Webkit), а с другой – изящная и большим потенциалом.


PS1: Предвосхищая вопросы любопытных: из EL0 изменить S3_6_C15_C1_5 произвольным образом нельзя. Почти все биты в общем случае для вас будут залочены.

PS2: похожим образом была реализована и логика переключения пермишенов на странице с MAP_JIT из RW в RX.

pthread_jit_write_protect_np













Report Page