|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Листинг 6.4. Ручное декодирование файловой записи (разные атрибуты выделены разным цветом): 00 01 02 03 04 05 06 07 | 08 09 0A 0B 0C 0D 0E 0F 00000000: 46 49 4C 45 2A 00 03 00 | 60 79 1A 04 02 00 00 00 FILE*...`y...... 00000010: 01 00 01 00 30 00 01 00 | 50 01 00 00 00 04 00 00....0...P....... 00000020: 00 00 00 00 00 00 00 00 | 04 00 03 00 00 00 00 00................ 00000030: 10 00 00 00 60 00 00 00 | 00 00 00 00 00 00 00 00................ 00000040: 48 00 00 00 18 00 00 00 | B0 D5 C9 2F C6 0B C4 01 H.......░╒╔/╞.─. 00000050: E0 5A B3 7B A9 FA C3 01 | 90 90 F1 2F C6 0B C4 01 рZ│{й·├.PPё/╞.─. 00000060: 50 7F BC FE C8 0B C4 01 | 20 00 00 00 00 00 00 00 P⌂╝■╚.─........ 00000070: 00 00 00 00 00 00 00 00 | 00 00 00 00 05 01 00 00................ 00000080: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00................ 00000090: 30 00 00 00 70 00 00 00 | 00 00 00 00 00 00 02 00 0...p........... 000000A0: 54 00 00 00 18 00 01 00 | DB 1A 01 00 00 00 01 00 T.......█....... 000000B0: B0 D5 C9 2F C6 0B C4 01 | B0 D5 C9 2F C6 0B C4 01 ░╒╔/╞.─.░╒╔/╞.─. 000000C0: B0 D5 C9 2F C6 0B C4 01 | B0 D5 C9 2F C6 CB C4 01 ░╒╔/╞.─.░╒╔/╞.─. 000000D0: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00................ 000000E0: 20 00 00 00 00 00 00 00 | 09 03 49 00 6C 00 66 00..........I.l.f. 000000F0: 61 00 6B 00 2E 00 64 00 | 62 00 78 00 00 00 00 00 a.k...d.b.x..... 00000100: 80 00 00 00 48 00 00 00 | 01 00 00 00 00 00 03 00 А...H........... 00000110: 00 00 00 00 00 00 00 00 | ED 04 00 00 00 00 00 00........э....... 00000120: 40 00 00 00 00 00 00 00 | 00 E0 4E 00 00 00 00 00 @........рN..... 00000130: F0 D1 4E 00 00 00 00 00 | F0 D1 4E 00 00 00 00 00 Ё╤N.....Ё╤N..... 00000140: 32 EE 04 D9 91 00 00 81 | FF FF FF FF 82 79 47 11 2ю.┘С..Б ВyG. 000001F0: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 03 00................ : 00 01 02 03 04 05 06 07 | 08 09 0A 0B 0C 0D 0F 0F Первым делом необходимо восстановить оригинальное содержимое последовательности обновления. По смещению 04h от начала сектора лежит 16-разрядный указатель на нее, равный в данном случае 2Ah (значит, это NTFS 3.0 или более ранняя версия). А что у нас лежит по смещению 2Ah? Это — пара байт 03 00. Данная последовательность представляет собой номер последовательности обновления. Сверяем его с содержимым двух последних байт этого и следующего секторов (смещения 1FEh и 3FEh соответственно). Они равны! Следовательно, данная файловая запись цела (по крайней мере, на первый взгляд), и можно переходить к операции ее восстановления. По смещению 2Ch расположен массив, содержащий оригинальные значения последовательности обновления. Количество элементов в нем равно содержимому 16-разрядного поля, расположенному по смещению 06h от начала сектора и уменьшенного на единицу (в данном случае имеем 03h - 01h == 02h). Извлекаем два слова, начиная со смещения 2Ch (в данном случае они равны 00 00 и 00 00) и записываем их в конец первого и последнего секторов. Теперь нам необходимо выяснить, используется ли данная файловая запись, или же ассоциированный с ней файл или каталог был удален. 16-разрядное поле, расположенное по смещению 16h, содержит значение 01h. Следовательно, перед нами файл, а не каталог, и этот файл еще не удален. Но является ли эта файловая запись базовой для данного файла или мы имеем дело с ее продолжением? 64-разрядное поле, расположенное по смещению 20h, равно нулю, следовательно, данная файловая запись — базовая. Очень хорошо, теперь переходим к исследованию атрибутов. 16-разрядное поле, находящееся по смещению 14h, равно 30h, следовательно, заголовок первого атрибута начинается со смещения 30h от начала сектора. Первое двойное слово атрибута равно 10h, значит, перед нами атрибут типа $STANDARD_INFORMATION. 32-разрядное поле длины атрибута, находящееся по смещению 04h и равное в нашем случае 60h байт, позволяет нам вычислить смещение следующего атрибута в списке: 30h (смещение нашего атрибута) + 60h (его длина) == 90h (смещение следующего атрибута). Первое двойное слово следующего атрибута равно 30h, значит, это атрибут типа $NAME, и следующее 32-разрядное поле хранит его длину, равную в данном случае 70h. Сложив длину атрибута с его смещением, мы получим смещение следующего атрибута — 90h + 70h == 100h. Первое двойное слово третьего атрибута равно 80h, следовательно, это атрибут типа $DATA, хранящий основные данные файла. Складываем его смещение с длиной — 100h + 32h == 132h. И вот здесь мы наткнулись на частокол FFFFFFh, сигнализирующий о том, что атрибут $DATA последний в списке. Теперь, разбив файловую запись на атрибуты, можно приступить к исследованию каждого из атрибутов в отдельности. Начнем с разбора имени. 8-разрядное поле, находящееся по смещению 08h от начала атрибутного заголовка (и по смещению 98h от начала сектора), содержит флаг нерезидентности. В данном случае этот флаг равен нулю. Это значит, атрибут резидентный, и его тело хранится непосредственно в самой файловой записи, что уже хорошо. 16-разрядное поле, расположенное по смещению 0Сh от начала атрибутного заголовка (и по смещению 9Ch от начала сектора) равно нулю, следовательно, тело атрибута не сжато и не зашифровано. Таким образом, можно приступать к разбору тела атрибута. 32-разрядное поле, расположенное по смещению 10h от начала атрибутного заголовка (и по смещению A0h от начала сектора), содержит длину атрибутного тела, равную в данном случае 54h байт. 16-разрядное поле, расположенное по смещению 14h от начала атрибутного заголовка и по смещению A4h от начала сектора, хранит смещение атрибутного тела, равное в данном случае 18h. Следовательно, тело атрибута $FILE_NAME располагается по смещению A8h от начала сектора. Формат атрибута типа $FILE_NAME описан в табл. 6.9. Первые восемь байт содержат ссылку на родительский каталог этого файла, равную в данном случае 11ADBh:01 (индекс — 11ADBh, номер последовательности — 01h). Следующие 32 байта содержат данные о времени создания, изменения и времени последнего доступа к файлу. По смещению 28h от начала тела атрибута и D0h от начала сектора лежит 64-разрядное поле выделенного размера, а за ним — 64-разрядное поле реального размера. Оба равны нулю, что означает, что за размером файла следует обращаться к атрибутам типа $DATA. Длина имени файла содержится в 8-разрядном поле, находящемся по смещению 40h байт от начала тела атрибута и по смещению E8h от начала сектора. В данном случае оно равно 09h. Само же имя начинается со смещения 42h от начала тела атрибута и со смещения EAh от начала сектора. И здесь находится имя файла llfak.dbx. Переходим к атрибуту основных данных файла, пропустив атрибут стандартной информации, который не содержит решительно ничего интересного. 8-разрядный флаг нерезидентности, расположенный по смещению 08h от начала атрибутного заголовка и по смещению 108h от начала сектора, равен 01h, следовательно, атрибут нерезидентный. 16-разрядный флаг, расположенный по смещению 0Ch от начала атрибутного заголовка и по смещению 10Ch от начала сектора, равен нулю, значит, атрибут не сжат и не зашифрован. 8-разрядное поле, расположенное по смещению 09h от начала атрибутного заголовка и по смещению 109h от начала сектора, равно нулю — атрибут безымянный. Реальная длина тела атрибута (в байтах) содержится в 64-разрядном поле, расположенном по смещению 30h от начала атрибутного заголовка и по смещению 130h от начала сектора. В данном случае она равна 4ED1F0h (5.165.552). Два 64-разрядных поля, расположенных по смещениям 10h/110h и 18h/118h байт от начала атрибутного заголовка/сектора соответственно, содержат начальный и конечный номер виртуального кластера нерезидентного тела. В данном случае они равны: 0000h и 4EDh соответственно. Остается лишь декодировать список отрезков, адрес которого хранится в 16-разрядном поле, находящемся по смещению 20h от начала атрибутного заголовка и 120h от начала сектора. В данном случае поле равно 40h, что соответствует смещению от начала сектора в 140h. Сам же список отрезков выглядит так: 32 EE 04 D9 91 00 00. Ага! Два байта занимает поле длины (равное в данном случае 04EEh кластерам) и три — поле начального кластера (0091h). Завершающий ноль на конце говорит о том, что этот отрезок последний в списке отрезков. Подытожим полученную информацию. Файл называется llfak.dbx, он начинается с кластера 0091h и продолжается вплоть до кластера 57Fh, при реальной длине файла в 5.165.552 байт. Это все, что надо! Теперь остается только скопировать файл на резервный носитель (например, ZIP или стример). Возможные опасности NTFS Сейчас мы немного отвлечемся и поговорим о... компьютерных вирусах, обитающих внутри NTFS и активно использующих ее расширения в своих личных целях. В любом случае конструирование вирусов — отличный стимул к изучению ассемблера! И хотя вирус в принципе можно написать и на Си, это будет как-то не по-хакерски и вообще неправильно! Настоящие хакеры пишут только на FASM. Итак, запускаем Multi-Edit или TASMED и погружаемся в мрачный лабиринт кибернетического мира, ряды обитателей которого скоро пополнятся еще одним зловредным созданием... Простейший вирус под Windows NT Внедрение вируса в исполняемый файл, в общем случае, достаточно сложный и мучительней процесс. Как минимум для этого требуется изучить формат РЕ-файла и освоить десятки API-функций. Но ведь такими темпами мы не напишем вируса и за сезон, а хочется создать его прямо здесь и сейчас. Но хакеры мы или нет? Файловая система NTFS (основная файловая система Windows NT/2000/XP) содержит потоки данных (streams), называемые также атрибутами. Внутри одного файла может существовать несколько независимых потоков данных (рис. 6.4). Рис. 6.4. Файловая система NTFS поддерживает несколько потоков в рамках одного файла Имя потока отделяется от имени файла знаком двоеточия (:), например: my_file:stream. Основное тело файла хранится в безымянном потоке, но мы также можем создавать и свои потоки. Заходим в FAR Manager, нажимаем клавиатурную комбинацию <Shift>+<F4>, вводим с клавиатуры имя файла и потока данных, например: xxx:yyy, и затем вводим какой-нибудь текст. Выходим из редактора и видим файл нулевой длины с именем xxx. Почему же файл имеет нулевую длину? А где же введенный нами только что текст? Нажмем клавишу <F4> и... действительно не увидим никакого текста. Однако ничего удивительного в этом нет. Если не указать имя потока, то файловая система отобразит основной поток, а он в данном случае пуст. Размер остальных потоков не отображается, и дотянуться до их содержимого можно, только указав имя потока явно. Таким образом, чтобы увидеть текст, необходимо ввести следующую команду: more < xxx:yyy. Будем мыслить так: раз создание дополнительных потоков не изменяет видимых размеров файла, то пребывание в нем постороннего кода, скорее всего, останется незамеченным. Тем не менее, чтобы передать управление на свой поток, необходимо модифицировать основной поток. Контрольная сумма при этом неизбежно изменится, что наверняка не понравится антивирусным сканерам. Метод, применяемый для обмана антивирусных программ, мы рассмотрим в дальнейшем, а пока определимся со стратегией внедрения. Алгоритм работы вируса Закройте руководство по формату исполняемых файлов (Portable Executable, РЕ). Для решения поставленной задачи оно нам не понадобится. Действовать будем так: создаем внутри инфицируемого файла дополнительный поток, копируем туда основное тело файла, а на освободившееся место записываем наш код, делающий свое черное дело и передающий управление на основное тело. Работать такой вирус будет только на Windows NT/2000/XP и только под NTFS. На работу с файловой системой FAT он изначально не рассчитан. Оригинальное содержимое заражаемого файла на разделах FAT будет попросту утеряно. То же самое произойдет, если упаковать файл с помощью ZIP или любого другого архиватора, не поддерживающего файловых потоков. В качестве примера архиватора, поддерживающего файловые потоки, можно привести RAR. В диалоговом окне Имя и параметры архива есть вкладка Дополнительно, которая содержит группу опций Параметры NTFS (рис. 6.5). В составе этой группы опций есть флажок Сохранять файловые потоки. Установите эту опцию, если при упаковке файлов, содержащих несколько потоков, требуется сохранить их все. Рис. 6.5. Архиватор RAR способен сохранять файловые потоки в процессе архивации Существует и другая проблема. Windows блокирует доступ ко всем открытым файлам, и попытка внедрения в них обречена на неудачу. Тем не менее, выход из этого положения существует. Заблокированный файл нельзя открыть, но можно переименовать. Возьмем, например, explorer.exe, и переименуем его, например, в foo. Затем создадим новый файл с точно таким же именем, в основном потоке которого поместим вирусное тело, а прежний explorer.exe скопируем в дополнительный поток. При последующих запусках системы управление получит наш explorer.exe, и файл foo будет можно удалить. Примечание Вообще говоря, переименованный файл можно и не удалять. Правда, в этом случае он может привлечь внимание бдительного пользователя или антивирусного ревизора. Теперь настал момент поговорить об антивирусных ревизорах. Внедрить вирусное тело в файл — это всего лишь половина задачи, и притом самая простая. Теперь создатель вируса должен продумать, как защитить свое творение от всевозможных антивирусных программ. Эта задача не так сложна, как кажется на первый взгляд. Достаточно заблокировать файл сразу же после запуска и удерживать его в этом состоянии в течение всего сеанса работы с Windows вплоть до перезагрузки. Антивирусы просто не смогут открыть файл, а, значит, не смогут обнаружить и факт его изменения. Существует множество путей блокировки — от CreateFile со сброшенным флагом dwShareMode до LockFile/LockFileEx. Подробнее об этом можно прочитать в Platform SDK. Основная ошибка большинства вирусов состоит в том, что, однажды внедрившись в файл, они сидят и покорно ждут, пока антивирус не обнаружит их и не сотрет. А ведь сканирование современных винчестеров занимает значительное время, зачастую оно растягивается на многие часы. В каждый момент времени антивирус проверяет всего один файл, поэтому, если вирус ведет кочевую жизнь, мигрируя от одного файла к другому, шансы на его обнаружение стремительно уменьшаются. Мы будем действовать так: внедряемся в файл, ждем 30 секунд, удаляем свое тело из файла, тут же внедряясь в другой. Чем короче период ожидания — тем выше шансы вируса остаться незамеченным, но и тем выше дисковая активность. А регулярные мигания красной лампочки без видимых причин сразу же насторожат опытных пользователей, поэтому приходится хитрить. Например, можно вести мониторинг дисковой активности, осуществляя заражение только тогда, когда происходит обращение к какому-нибудь файлу. В решении этой задачи нам поможет файловый монитор (Filemon.exe) Марка Руссиновича (http://www.systeminternals.com). Эта утилита поставляется с исходным кодом, который легко доработать под любые потребности. Программный код вируса Естественные языки с описанием компьютерных алгоритмов практически никогда не справляются. Уж слишком они неоднозначны и внутренне противоречивы. Поэтому, во избежание недоразумений, продублируем описание алгоритма на языке ассемблера. В листинге 6.5 приведен исходный код ключевого фрагмента вируса с комментариями. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.007 сек.) |