Про­дол­жая оку­чивать пло­дород­ную тему струк­турных исклю­чений, погово­рим о методах скры­той уста­нов­ки SEH-обра­бот­чиков, исполь­зуемых для зат­рудне­ния дизас­сем­бли­рова­ния/отладки подопыт­ного кода, а так­же обсу­дим воз­можные конт­рме­ры анти­анти­отла­доч­ных спо­собов.
 

Постановка проблемы

Струк­турные исклю­чения пред­став­ляют собой мощ­ное анти­отла­доч­ное средс­тво, в чем мы уже убе­дились на при­мере пре­дыду­щих выпус­ков. Там же мы поз­накоми­лись и с тех­никой иссле­дова­ния прог­рамм, игра­ющих­ся исклю­чени­ями, работу с которы­ми дос­таточ­но труд­но замас­кировать.

Вся­кий раз, ког­да в тек­сте прог­раммы встре­чает­ся конс­трук­ция MOV FS:[0], xxx, хакер сра­зу вста­ет тор­чком — раз это FS:[0], зна­чит, прог­рамма уста­нав­лива­ет собс­твен­ный SEH-обра­бот­чик и, судя по все­му, сей­час будет бро­сать исклю­чения. Теоре­тичес­ки воз­можно засунуть MOV FS:[0], xxx в самомо­дифи­циру­ющий­ся код, убрав его из дизас­сем­блер­ных лис­тингов, одна­ко про­тив аппа­рат­ной точ­ки оста­нова по записи на MOV FS: [0], xxx нич­то не спа­сет. В момент уста­нов­ки нового SEH-обра­бот­чика отладчик тут же «всплы­вет», демас­кируя защит­ный механизм. А SetUnhandledExceptionFilter вооб­ще пред­став­ляет собой API-фун­кцию, экспор­тиру­емую KERNEL32.DLL, которую лег­ко обна­ружить любым API-шпи­оном, даже без ана­лиза все­го дизас­сем­блер­ного кода!

За­дача: уста­новить собс­твен­ный обра­бот­чик струк­турных исклю­чений, но так, что­бы это как мож­но мень­ше бро­салось в гла­за и не палилось три­виаль­ной уста­нов­кой точек оста­нова. Решени­ем мы сей­час, собс­твен­но, и зай­мем­ся, пред­ложив широкий ассорти­мент анти­отла­доч­ных трю­ков, один инте­рес­нее дру­гого.

 

Перезапись существующего обработчика

Вмес­то того что­бы уста­нав­ливать новый обра­бот­чик струк­турных исклю­чений, некото­рые (и дос­таточ­но мно­гие) защиты пред­почита­ют модифи­циро­вать ука­затель на сущес­тву­ющий. Даже если при­ложе­ние и не уста­нав­лива­ет никаких SEH-обра­бот­чиков, сис­тема все рав­но впи­хива­ет ему SEH-обра­бот­чик по умол­чанию, смот­рящий куда‑то в деб­ри KERNEL32.DLL. На этом, кста­ти говоря, осно­ван популяр­ный при­мем поис­ка базово­го адре­са заг­рузки KERNEL32.DLL, в котором нуж­дает­ся shell-код, а так­же прог­раммы, написан­ные без исполь­зования таб­лицы импорта (из‑за ошиб­ки в сис­темном заг­рузчи­ке они работа­ют толь­ко на XP и более поз­дних вер­сиях).

Об­работ­чик по умол­чанию не дела­ет ничего полез­ного, и потому без него мож­но обой­тись, «поза­имс­тво­вав» ука­затель — на вре­мя или нав­сегда. Кон­крет­ный при­мер реали­зации при­веден ниже.

Ус­танов­ка сво­его SEH-обра­бот­чика без переза­писи ячей­ки FS:[0]
souriz()
{
printf("hello, nezumi\n"); ExitProcess(0);
}
main()
{
int *p=0;
__asm{
mov eax, fs:[0]
lea ecx, souriz
add eax, 4
mov [eax], ecx
}
return *p;
}

Внеш­не код очень похож на клас­сичес­кий спо­соб уста­нов­ки SEH-обра­бот­чика, но, прис­мотрев­шись вни­матель­нее, мы видим, что в нашем при­мере модифи­циру­ется отнюдь не ячей­ка FS:[0], а то, на что она ука­зыва­ет. Точ­ка оста­нова по записи на FS:[0] уже не сра­бота­ет, одна­ко сег­мен­тный регистр FS режет глаз, да и бряк на FS:[0] по дос­тупу про­дол­жает работать, а потому для эффектив­ного про­тиво­дей­ствия хакеру тре­буют­ся допол­нитель­ные уров­ни мас­киров­ки. Ну и чего мы сидим? Впе­ред!

Скрытая установка SEH-обработчика
Скры­тая уста­нов­ка SEH-обра­бот­чика
 

Прячем FS

Ос­лепить дизас­сем­бле­ры сов­сем не труд­но. Переза­писать ука­затель на сис­темный SEH-обра­бот­чик мож­но и без явно­го исполь­зования сег­мен­тно­го регис­тра FS. Самое прос­тое, что мож­но сде­лать, — ско­пиро­вать его в любой дру­гой сег­мен­тный регистр (нап­ример, GS). С точ­ки зре­ния про­цес­сора, регис­тры FS и GS совер­шенно рав­ноправ­ны. Глав­ное, что­бы в регис­тре содер­жался «пра­виль­ный» селек­тор, а его наз­вание — уже дело десятое. Соз­давать новые селек­торы мы не можем (точ­нее, можем, но это тема отдель­ного раз­говора), а вот заг­ружать сущес­тву­ющие — почему бы и нет?

Уси­лен­ный фраг­мент защиты при­веден ниже.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии