Состояние выделения блока определяется по битовой карте блоков, местонахождение которой задается дескриптором группы. Для хранения битовой карты выделяется полный блок, каждый бит которого представляет некоторый блок группы. Чтобы определить, какой бит представляет заданный блок, необходимо сначала определить адрес блока относительно начала группы. Полученный адрес может рассматриваться как логический адрес блока в группе. Формула вычисления первого блока в группе выглядит так:

первый_блок - группа * БЛ0К0В_В_ГРУППЕ + ПЕРВЫЙ_БЛОК_ДАННЫХ

Затем адрес первого блока в группе вычитается из адреса блока. Например, базовый адрес группы 1 в нашем примере равен 32 768, поэтому блоку 60 ООО будет соответствовать смещение 27 232. Соответствующий бит находится в байте 3 404 битовой карты. Пример битовой карты ExtX приводится в следующей главе.

Механизм создания файловых систем в Linux выбирает размер группы блоков таким образом, чтобы битовая карта блоков помещалась в одном блоке. Следовательно, во всех файловых системах с 4 096-байтовыми блоками по умолчанию группа состоит из 32 768 блоков. Пользователь может переопределить эти значения при создании файловой системы, а в других приложениях могут использоваться другие алгоритмы.

В отличие от NTFS, не каждый выделенный блок принадлежит какому-либо файлу. В системе существует множество выделенных блоков с административными данными файловой системы, которые с файлами не ассоциируются. В качестве примеров можно привести суперблоки, таблицы дескрипторов групп, битовые карты блоков и индексных узлов, а также таблицы индексных узлов.

Программа dstat из пакета TSK отображает состояние выделения блока и номер группы блоков, к которой он принадлежит. Пример вывода dstat для тестового образа:

# dstat -f linux-ext3 ext3.dd 14380 Block: 14380 Allocated Group: 0

Мы видим, что блок 14 380 входит в группу блоков 0 и что он выделен.

Алгоритмы выделения

В системе Linux блоки выделяются на уровне групп, но в других ОС могут использоваться другие методы. При выделении блока индексному узлу Linux использует стратегию поиска первого доступного блока и пытается выделить блок из той же группы, к которой принадлежит индексный узел. Это делается для того, чтобы сократить перемещения головки диска при чтении файла. При расширении существующих файлов Linux сначала пытается применить стратегию поиска следующего доступного блока и ищет блоки за концом текущего файла. Одна из совместимых функций файловой системы осуществляет предварительное выделение блоков для каталогов, чтобы они не фрагментировались при выделении дополнительных блоков.

Если в группе не остается свободного места, используется блок из другой группы. Учтите, что это поведение определяется на прикладном уровне и не каждая ОС следует этой методике выделения. Например, ОС может с таким же успехом игнорировать существование групп и использовать алгоритм выделения первого доступного блока от начала файловой системы (а не от начала группы блоков).

ЕхЬХ обычно не разрешает пользователю выделять каждый блок файловой системы. Одно из значений суперблока указывает, сколько блоков должно быть зарезервировано для некоторого пользователя (как правило, привилегированного). Когда количество свободных блоков падает до минимального порога, обычные пользователи не могут создавать файлы, но администратор может войти в систему для ее очистки. Впрочем, это поведение также относится к прикладному уровню и может не поддерживаться некоторыми ОС.

При записи данных на диск 1лпих заполняет неиспользуемые байты нулями, поэтому за последним блоком файла не должно оставаться никаких предыдущих данных.

Методы анализа

При анализе категории содержимого в ExtX эксперт должен знать, как найти любой блок, прочитать его содержимое и проверит состояние выделения. Найти заданный блок несложно, потому что первый блок начинается в первом секторе файловой системы, а размер блока задается в суперблоке.

Проверка состояния выделения любого блока состоит из трех этапов. Сначала необходимо определить, к какой группе относится блок. Затем запись этой группы ищется в таблице дескрипторов групп, и по ней определяется местонахождение битовой карты блока. На последнем этапе производится обработка битовой карты блока и анализ бита, связанного с этим блоком. Если бит установлен, значит, блок выделен для использования.

Если потребуется извлечь содержимое всех свободных блоков в файловой системе, необходимо последовательно перебрать все записи в таблице дескрипторов групп. Для каждой записи загружается битовая карта блока, и в ней производится поиск нулевых битов. Далее остается лишь извлечь содержимое каждого блока, бит которого равен 0. В ExtX суперблоки, дескрипторы групп, таблицы индексных усзлов и битовые карты относятся к выделенным данным, хотя они и не связываются с конкретными файлами. Если в начале файловой системы присутствуют зарезервированные секторы, определить состояние выделения несколько сложнее, потому что информация о таких секторах не включается в битовую карту. Вероятно, результат будет зависеть от конкретной программы.

Факторы анализа

В том, что касается восстановления удаленного содержимого, может пригодиться знание алгоритмов выделения в файловых системах Ех1Х. Если ОС выделяет блоки в той же группе, в которой находится индексный узел, поиск обычно можно ограничить группой (вместо поиска по всей файловой системе). Например, если вы ищете файл, содержащий некоторое ключевое слово, и вы знаете, к какой группе относился этот файл, проведите поиск улик в рамках группы. Такой способ работает гораздо быстрее, чем поиски по всей файловой системе. Впрочем, такой способ поиска не является универсальным, потому что копии файла могут существовать в других группах, а ОС выделяет блоки не только из той группы, к которой принадлежит индексный узел. Для определения местонахождения группы можно воспользоваться программой fsstat из пакета TSK, как это было сделано ранее; впрочем, ту же информацию можно получить и при помощи других программ.

Время существования удаленных данных в ExtX отличается от NTFS или FAT. Если блок уже заполнен информацией, а операции с ней выполняются относительно редко, удаленные данные будут заменяться реже, чем в группах с частыми операциями записи. В NTFS и FAT вероятность перезаписи любого кластера одинакова, тогда как в ExtX она зависит от того, в какой группе находится блок.

Сценарий анализа

В следующем сценарии требуется прочитать содержимое последнего блока файловой системы, в котором руткит хранит свой пароль (вообще говоря, мне не известны руткиты, которые вели бы себя подобным образом, но это неважно). Для решения этой задачи необходимо определить размер блока и количество блоков в файловой системе. Оба значения хранятся в суперблоке. Трудность заключается в том, что в нашем распоряжении имеется только шестнадцатеричный редактор, работающий с 512-байтовыми секторами.

Сначала мы читаем суперблок, находящийся в секторе 2 файловой системы. Размер блока хранится в байтах 24-27; он равен 2. Размер блока хранится в виде числа двоичных разрядов, на которые необходимо сдвинуть число 1024 (0x0400); в нашей файловой системе сдвиг производится на две позиции влево. Однократный сдвиг дает число 2048 (0x0800), а повторный - число 4096 (0x1000). Если вы не поняли, что происходит, достаточно вспомнить, что число 0x4 имеет двоичное представление 0100, а число 0x8 - двоичное представление 1000. При сдвиге 0x4000 на 1 разряд влево число 0x4 переходит в 0x8.

Затем необходимо определить последний блок файловой системы. Значение хранится в байтах 4-7 и не требует дополнительных вычислений. Файловая система состоит из 512 064 блоков; это означает, что поиск должен производиться вперед на 512 063 блока, а каждый блок занимает 4 096 байт, или 8 секторов. Таким образом, в шестнадцатеричном редакторе следует просмотреть секторы с 4 096 504 по 4 096 511.

В рассмотренном сценарии был воспроизведен процесс поиска заданного блока. Многие программы анализа делают это автоматически, однако поиск блока - достаточно стандартная задача, поэтому полезно знать, как она решается.

Категория метаданных

К категории метаданных относятся данные, описывающие файлы или каталоги. В этом разделе рассказано, где хранятся эти данные и как производится их анализ.

Общие сведения

В ExtX основные метаданные файлов хранятся в структурах данных индексных узлов. Дополнительные метаданные могут храниться в расширенных атрибутах. Обе разновидности структур данных будут описаны в этом разделе.

Индексные узлы

Все индексные узлы в ExtX имеют одинаковый размер, который может определяться в суперблоке. Каждому файлу и каталогу выделяется один индексный узел; адресация индексных узлов начинается с 1. Каждой группе блоков выделяется набор индексных узлов, размер которого задается в суперблоке. Индексные узлы каждой группы хранятся в таблице, местонахождение которой определяется в дескрипторе группы. Если адрес индексного узла известен, его группа вычисляется по следующей формуле:

группа = (узел - 1) / УЗЛ0В_В_ГРУППЕ

Индексные узлы 1-10 обычно резервируются и должны быть выделены. В суперблоке хранится значение первого незарезервированного индексного узла. Из зарезервированных индексных узлов только номер 2 имеет особую функцию и используется для представления корневого каталога. Индексный узел 1 используется для хранения информации о поврежденных блоках, но не имеет особого статуса с точки зрения ядра Linux. Для журнала обычно используется индексный узел 8, но его номер может быть переопределен в суперблоке. Первый пользовательский файл обычно создается в узле 11; этот узел часто выделяется под каталог lost+found. Этот каталог используется программами проверки целостности файловой системы; любой индексный узел, выделенный для использования, но не ассоциированный ни с одним именем файла, помещается в этот каталог под новым именем.

Количество полей в каждом индексном узле является статической величиной. Дополнительная информация сохраняется в расширенных атрибутах и косвенных указателях, о которых речь пойдет далее в этой главе. Состояние выделения индексного узла определяется по карте индексных узлов, местонахождение которой задается в дескрипторе группы.

Индексный узел содержит информацию о размере файла, его владельце и временных штампах. Поле размера в новых версиях ExtX является 64-разрядным, но в старых версиях оно содержало всего 32 бита, что делало невозможной работу с файлами, размер которых превышал 4 Гбайт. В новых версиях старшие 32 бита размера хранятся в поле, которое ранее не использовалось. При наличии в системе больших файлов устанавливается флаг совместимой функции только для чтения.

Для хранения информации о «владельце» используются идентификаторы пользователя и группы. В UNIX каждому пользователю присваивается идентификатор; имя пользователя связывается с идентификатором в файле /etc/passwd. Аналогично, файл /etc/groups связывает идентификатор группы с именем. Учтите, что присутствие идентификатора пользователя в индексном узле не обязательно означает, что файл был создан именно этим пользователем. Идентификаторы пользователя и группы в индексном узле можно в любой момент сменить командами chown и chgrp. Также учтите, что файл /etc/passwd не обязан содержать имя пользователя для каждого идентификатора. Стандартные системные программы просто выводят идентификатор пользователя, если они не могут преобразовать его в имя.

Что касается временных штампов, в индексном узле хранятся времена последнего обращения, модификации, изменения и удаления. Значения хранятся в виде количества секунд, прошедших с 1 января 1970 года в формате UTC. Время последней модификации, обращения и изменения также существует в UFS; эти величины часто обозначаются сокращением MAC. Время последнего обращения (A-время) соответствует времени последнего обращения к содержимому файла. Время последней модификации (М-время) соответствует последней модификации содержимого файла, а время последнего изменения (С-время) соответствует последнему изменению метаданных файла. При создании файла все три величины обычно устанавливаются равными текущему времени. Время удаления (D-вре-мя) соответствует моменту удаления файла. В Linux и других системах семейства UNIX команда touch позволяет легко присвоить файлу произвольное М- и А-вре-мя. Команда touch задает значения М- и A-времени, но С-время при этом обновляется автоматически.

Тип файла хранится в поле режима, которое также содержит базовые разрешения доступа к файлу. В UNIX существует множество типов файлов. Нормальные файлы, создаваемые пользователем, называются обычными файлами, а каталоги, как и следовало ожидать, называются каталогами. В остальных случаях ситуация не столь очевидна для пользователей, не обладающих навыками работы в UNIX, а для хранения «файлов» не выделяются блоки. Такие файлы представляют собой имена, которые используются программами для обращения к аппаратным устройствам или коммуникационным каналам.

Аппаратному устройству назначается одно или несколько имен файлов, каждое из которых соответствует блочному или символьному устройству. Блочные устройства представляют оборудование, обмен данными с которым происходит на уровне блоков - например, жесткие диски. Как было показано в главе 2, для получения любых данных с жесткого диска необходимо прочитать как минимум 512 байт. Если приложению достаточно прочитать менее одного сектора с блочного устройства, то ОС читает необходимые секторы и возвращает только те данные, которые запросило приложение. С другой стороны, символьные устройства, также называемые низкоуровневыми устройствами, не нуждаются в блочной передаче данных. В качестве примера символьного устройства можно назвать клавиатуру. Как правило, для блочного устройства также параллельно создается символьное устройство, но при попытке его использования для чтения/записи данных, размер которых отличен от размера блока, происходит ошибка. Индексные узлы, в которых обычно хранится информация о блоках, выделенных файлу, используются для хранения информации об идентификаторе устройства.

Еще один тип файлов предназначен для обмена данных между процессами. Каналы FIFO, также называемые именованными каналами, обеспечивают одностороннюю передачу данных между двумя и более процессами. Процесс открывает файл и читает данные, записанные в него другим процессом. Данные при этом хранятся не на диске, а в памяти ядра. Если обмен данными между процессами должен быть двусторонним, используются сокеты UNIX. Сокетом UNIX называется файл, открываемый процессами при помощи специальных функций и обеспечивающий двусторонний обмен данными. Как и в случае с именованными каналами, данные на диск не записываются. Последнюю категорию файлов составляют символические (мягкие) ссылки. Они будут более подробно рассмотрены в разделе

«Категория данных имен файлов», а пока достаточно сказать, что символические ссылки определяют альтернативные имена для обращения к файлам или каталогам.

Помимо типа файла, в поле режима хранятся основные разрешения доступа к файлу. Разрешения определяют возможность чтения, записи и выполнения команд для владельца, группы или всех пользователей. Например, если группе разрешено чтение файла, а остальным пользователям доступ запрещен, то прочитать содержимое файла смогут только пользователи группы, идентификатор которой хранится в индексном узле. Принадлежность к группе определяется по файлу /etc/groups. Конечно, эти данные относятся к необязательным, потому что ОС может и не соблюдать установленные ограничения.

Наконец, поле режима определяет особые свойства файлов и каталогов. Если для исполняемого файла установлен «бит устойчивости», то некоторые данные процесса останутся в памяти после завершения процесса. Если этот бит устанавливается для файла или каталога, то удаление содержимого каталога разрешается только владельцу файла. Если для исполняемого файла установлены биты SUID (Set User ID) и SGID (Set Group ID), то процесс берет идентификаторы группы и пользователя из файла (вместо данных пользователя, запустившего процесс). Это позволяет непривилегированным пользователям запускать некоторые программы в качестве привилегированного пользователя. Если бит SGID установлен для каталога, всем файлам в этом каталоге назначается идентификатор группы, установленный для каталога.

В каждом узле хранится счетчик ссылок; его значение равно количеству имен файлов, ссылающихся на данный узел. Когда счетчик уменьшается до нуля и файл не открыт ни одним процессом, индексный узел освобождается. Если счетчик равен нулю, но файл открыт процессом, узел освобождается после его закрытия процессом. Индексный узел также содержит счетчик поколения, используемый системой NFS (Network File System) при получении информации о создании новых файлов. Когда индексный узел ассоциируется с новым файлом, счетчик поколения изменяется; таким образом сервер узнает о появлении нового файла. Его можно сравнить с полем порядкового номера, которое встречалось нам в NTFS.

За описаниями структур данных и примерами индексных узлов обращайтесь к следующей главе.

Блоки | Криминалистический анализ файловых систем | Указатели на блоки


Криминалистический анализ файловых систем



Новости за месяц

  • Март
    2020
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс