Статья NTFS-Stream, или резидентный код в камуфляжных штанах

Marylin

Marylin

Mod.Assembler
Red Team
05.06.2019
107
266
Рассмотрим файловую систему NTFS как сущность, которой доверяем самое ценное что у нас есть – это личную информацию. Порой мы не знаем куда пристроить пароли или своего трояна так, чтобы он не выдал себя даже под пытками, ..ну или просто хотим скрыть фото зазнобы в неприглядном виде. Для решения "проблемы века", юзеры присваивают файлам атрибут скрытый, более продвинутые шифруют файлы и т.д. Но в своих закромах NTFS предлагает нам более изящные средства, причём без сторонних инструментов – нужно просто открыть и покурить её (для надёжности) несколько раз.

Здесь мы рассмотрим сразу два родственных способа маскировки.. Первый известен в узких кругах как "альтернативный NTFS-поток" ADS (Alternative Data Stream) и живёт он в системе как скрытая часть уже существующего исполнительного потока. Второй – это доставшийся нам в наследство от файловой системы HPFS (OS/2) "расширенный атрибут файла EA" (Extended Attribute). Оба варианта имеют право на жизнь, только ареал их обитания не выходит за рамки файловой системы NTFS и FAT16, что собственно и является их слабой стороной.

Введение (в заблуждение)

Скелет NTFS составляют 14 системных метафайла с приставкой($) например $MFT, $Boot, etc.. В спеках на NTFS можно найти описание всех этих файлов, поэтому не буду останавливаться на них подробно. Мы копнём только в сторону выделенного на скрине метафайла с названием $AttrDef (define, определение), который перечисляет все имеющиеся в природе атрибуты дисковых файлов. Вот как видит эти файлики hex-редактор WinHex:

NTFS-Stream, или резидентный код в камуфляжных штанах


Суть в том, что NTFS рассматривает любой файл как набор атрибутов, в числе которых знакомые нам: имя файла, информация о его безопасности (скрытый, системный, архивный и т.д.), время создания/изменения, ну и конечно-же сами данные. Отметим, что полезные данные файла - это тоже его атрибут типа 0х80, в чём мы убедимся позже.

Если посмотреть на размеры метафайлов, то одним из увесистых является $MFT – Master File Table, или основная таблица файлов. Эта таблица представляет собой глобальную базу-данных буквально всех файлов на диске. Про запас, предусмотрена и зеркальная (mirror) его копия под названием $MFTMirr, правда в ней хранятся только (критически важные) первые 4К-байт записей. Согласно документации, под MFT отводится ~12% из общего пространства накопителя, которые назвали MFT-зоной. По мере того-как мы забиваем диск своим хламом, MFT обрастает соответствующими записями и динамически разбухает, пока не достигнет своего предела 12-15%:

NTFS-Stream, или резидентный код в камуфляжных штанах


Таблица $MFT содержит в себе кучу файловых записей File-Record. Каждая такая запись имеет размер 1024 байта и начинается только с нового сектора диска (кратна 0x200 байтам). Признаком начала файловой записи является сигнатура "FILE", после которой идёт уже служебная информация и заголовки различных его атрибутов.

Если атрибут описываемого файла вмещаются внутри File-Record, то его назвали "резидентным". Однако некоторые атрибуты изначально являются "нерезидентными" и обитают за пределами таблицы $MFT заселяя один из свободных кластеров диска. В этом случае у файла появляется атрибут с именем $ATTRIBUTE_LIST, а внутри MFT помещают только линк на внешний (нерезидентный) атрибут. Такая вот муть..


Структура файловой записи "File-Record"

Раз-уж речь зашла об MFT и описателях файлов, бегло рассмотрим скелет одной из таких записей. Структура записи такова, что имеем один заголовок Header и несколько файловых атрибутов. Размер атрибутов нефиксирован и зависит от его типа, зато заголовок жёстко оговаривается в документации и как-правило равен 0х38 байт. Запустим тот-же WinHex и двойным кликом запросим файл $MFT:

NTFS-Stream, или резидентный код в камуфляжных штанах


Начнём с того, что по-смещению 0х04 лежит указатель на т.н. "Последовательность обновлений" – в данном случае это смещение 0х30, а там прописано значение 0х00С2 (выделено зелёным). Если файл имеет размер больше одного сектора диска (512-байт или 0х200), то он занимает следующий сектор и т.д. В этом случае, по данной последовательности 0х00С2 система соберёт его по-крупинкам в один законченный файл. Значение 0х00С2 уникально для данного файла и будет лежать последним словом во-всех секторах, которые принадлежат данному файлу. Особенно актуально это для фрагментированных файлов, когда один файл размазывается чуть-ли не по всей поверхности накопителя. Утилиты восстановления данных с упавшей NTFS типа R-Studio, Recula и т.д. опираются именно на эту "Последовательность обновлений".

Но сейчас мы ищем атрибуты и в приоритете для нас значение, которое лежит по смещению 0х14 от начала записи (выделено красным), и равно оно 0х0038 – это указатель на первый атрибут данного файла, ..за ним впритык идёт следующий и т.д. Здесь уже сложней из-за того, что атрибуты файла не имеют общей структуры как заголовок выше, и отличаются как по размеру, так и по содержимому (система распознаёт их по типу, см.табл.ниже). Поэтому мы рассмотрим конкретно данный случай, протопав по указанному смещению 0х38:

NTFS-Stream, или резидентный код в камуфляжных штанах


В общем случае, файловые атрибуты бывают 4-х типов: резидент безымянный или с именем, и такой-же нерезидент. Если посмотреть на поля 0х40/41, то в данном случае перед нами "безымянный резидент", тело которого полностью лежит в $MFT. Его тип имеет значение 0х10, а этот код выделен для атрибута $STANDART_INFORMATION (см.первый столбец в таблице ниже). Кому интересно тело и описание самого атрибута (в дампе выделен красным), имеет смысл отрыть документацию на NTFS.


Метафайл $AttrDef

Если загнать под пресс всё вышесказанное, то можно сделать вывод, что даже обычный текстовый файл никакой не обычный, а может иметь аж до 10-ти атрибутов, и только одним из них является $STANDART_INFORMATION со-знакомыми нам свойствами файла типа скрытый и т.п.

На рисунке ниже представлен вывернутый наизнанку файл, причём его тип и расширение не играет сейчас никакой роли – расширение парсит загрузчик файлов в Ntdll.dll позже, при загрузке этого файла с диска в память. Здесь видно, что всего атрибутов 15 и каждый имеет свой тип в диапазоне от 0х10 до 0х100. Например атрибут с именем $DATA имеет тип 0х80 и неограниченный размер, а в атрибуте типа 0х30 лежит Unicode-имя файла и т.д. Файл не обязательно должен иметь все перечисленные здесь атрибуты – это просто лист возможных вариантов. Так, атрибуты $INDEX_хх принадлежат только папкам, а $VOLUME – целым разделам (для файловой системы что дир, что том - всё это файлы):

NTFS-Stream, или резидентный код в камуфляжных штанах


Те атрибуты, которые мы задействуем в своих программах я выделил на рисунке красным – это $DATA для примера с альтернативным потоком Stream, и свободная канистра – атрибут $EA (Extended Attribute), куда мы скрытно попытаемся залить шелл. Как видим, в поле "размер" расширенного атрибута красуется значение 64К и этого вполне хватить, чтобы запихать в него ассемблерного слона (а чтоб не скучал рядом ещё и слониху). Нужно отметить, что система вычисляет размер файла только по дефолтному (безымянному) потоку атрибута $DATA, так-что после наших махинаций размер файла останется прежним.

Win не имеет встроенных утилит для работы с альтернативными потоками и расширенными атрибутами. Ну а если не имеет, значит и не ведёт их учёт. Пропускают потоки между ног и антивирусы, которые следят только за безымянным потоком, что играет нам только на руку. Чтобы хоть как-то контролировать наличие атрибутов у наших программ, воспользуемся утилитой от энтузиастов . Она довольно проста в освоении, но имеет мощный функционал – фейс её представлен ниже:

NTFS-Stream, или резидентный код в камуфляжных штанах


Здесь видно, что из 15-ти возможных атрибутов MFT, моя эксперементальная прожка использовала только три из них – это данные, имя программы и её основные атрибуты типа время/дата создания, флаги доступа и безопасности и т.п. Посмотрим, что можно в него добавить так, чтобы не засветиться системе.


Практика – альтернативные потоки Stream

Атрибут типа 0х80 $DATA не имеет своего имени в MFT – это основной поток нашего программного кода. Однако NTFS предлагает нам добавлять в этот атрибут ещё дочерних атрибутов с таким-же типом 0х80, но чтобы при обращении отличать их друг от друга, предписывает через двоеточие задавать им имена. Таких альтернативных потоков мы можем добавлять хоть 100 штук.

Содержимое именованых потоков лежит чисто на нашей совести – это может быть безобидная иконка для файла, а можно припарковать туда совсем недетский шелл, который отработает как самостоятельная программа. Можно комбинировать тушку, например в JPG или TXT пристроить EXE и т.д. Но вот оригинально вытащить эти данные из матки-носителя – это уже совсем из другой оперы и требует хорошей практики.

Создать именованный поток просто – достаточно ввести имя жертвы и через двоеточие приписать к нему любое имя потока например так (используя консоль). Для начала создадим базовый файл-матку, к которому будем прикреплять наш поток:

Bash:
C:\> echo Hello World! > hello.txt
Таким образом в корне диска Ц получили приветствующий мир текстовый файл размером 15-байт. Теперь напишем шелл-код, который склеим с этим текстовым файлом. Чтобы не провоцировать общество к написанию вирусов, мой шелл будет просто выводить окно – это всего пару строк на fasm'e:

C-подобный:
include 'win32ax.inc'
.data
capt   db  'shell',0
text   db  'Сработал альтернативный поток!',0
;------
.code
start: invoke   MessageBox,0,text,capt,0
       invoke   ExitProcess,0
.end start
На следующем этапе выводим на консоль содержимое этого шела в бинарном виде, и тут-же перенаправим его в альтернативный поток нашего hello.txt:

Bash:
C:\ type shell.exe > hello.txt:hide.exe
С этого момента экзешник находится внутри текстового файла и оригинал "shell.exe" можно смело удалить. Обратите внимание, что при этом размер "hello.txt" как был 15-байт, так и остался. Посмотрим, на реакцию "NTFS-Stream-Explorer", которому вскормим наш гибридный hello:

NTFS-Stream, или резидентный код в камуфляжных штанах


В результате этих действий мы поженили два отдельных файла, что и показывает нам эксплорер в виде двух атрибутов – безымянного :$DATA, и дополнительного именованного потока :hide.exe:$DATA. В поле размер верхнего окна указано значение 88 – это размер атрибута в файловой записи таблицы MFT, о чём шла речь выше.

Если просто жмякнуть по "hello.txt" энтером, то нашему взору предстанет содержимое основного потока, т.е. 15-байтная надпись "Hello World!". Вызвать-же альтернативный поток можно только по его имени, например из специально заточенной для этого программной оболочки, ну или прямо из той-же консоли:

Bash:
C:\> start .\hello.txt:hide.exe
Кстати, поскольку для NTFS папки тоже являются файлами, всё сказанное применительно и для папок. То-есть можно использовать в качестве носителя шелла не только файлы, но и папки.


Расширенные атрибуты $EA

..как упоминальсь выше – это тоже один из атрибутов типа 0хЕ0 NTFS-файла. Мне так и не удалось выудить из сети какую-нибудь информацию по этому поводу, зачем их вводили, и что именно подразумевается под расширенным атрибутом. В отличии от альтернативных потоков, работать с этим атрибутом сложней и приходится прибегать к нативным API-функция из Ntdll.dll

Для создания ЕА можно использовать NtCreateFile() или NtSetEaFile(), если мы хотим добавить атрибут в уже существующий файл. Для чтения и перечисления всех атрибутов применяют функцию NtQueryEaFile(). Все эти функции для своей работы используют буфер, который оформлен в виде структуры FILE_FULL_EA_INFORMATION – вот члены этой структуры:

C-подобный:
struct FILE_FULL_EA_INFORMATION
  NextEntryOffset      dd  0   ; указатель на сл.структуру в цепочке
  Flags                db  0   ; флаги..
  EaNameLength         db  0   ; длина имени ЕА в байтах
  EaValueLength        dw  0   ; длина данных ЕА в байтах
  EaName               db  ?   ; буфер для данных ЕА
ends
Как видим, тут имеется "связной список" NextEntryOffset для перечисления нескольких атрибутов ЕА, и из этой структуры можно вытащить имя атрибута, если таковой имеется в файле. Прототипы остальных функций выглядят так:

C-подобный:
NtQueryEaFile (      ;// Чтение расширенных атрибутов
  FileHandle           ; хендл файл, открытый с доступом FILE_READ_EA
  IoStatusBlock        ; результат ввода-вывода
  Buffer               ; указатель на буфер для вывода данных
  Length               ; длина этого буфера в байтах
  ReturnSingleEntry    ; если установлено, возвращается только один элемент
  EaList OPTIONAL      ; доп.список структур FILE_GET_EA_INFORMATION с именами EA
  EaListLength         ; длина этого списка байтах
  EaIndex OPTIONAL     ; указатель на индекс запрашиваемого атрибута ЕА
  RestartScan          ; если установлено, результат является первым EA атрибутом
);

NtSetEaFile (        ;// Устанавливает расширенный атрибут
  FileHandle           ; хендл открытого файла
  IoStatusBlock        ; результат ввода-вывода
  EaBuffer             ; указатель на буфер со-структурой FILE_FULL_EA_INFORMATION
  EaBufferSize         ; его размер в байтах
);
Заключение

Файловая система NTFS достаточно устойчивая к сбоям система, способная восстанавливать сама-себя. Как правило, положить её на лопатки могут только физические разрушения секторов, в народе именуемые "бэдами" или Bad-sector. Больше информации на эту тему можно найти по следующим ссылкам:

Спецификация на NTFS:
Лучшая в сети HTML версия спецификации
Куча материала по теме:
К.Касперски -
 
SearcherSlava

SearcherSlava

Red Team
10.06.2017
708
1 012
Рассмотрим файловую систему NTFS как сущность, которой доверяем самое ценное что у нас есть – это личную информацию. Порой мы не знаем куда пристроить пароли или своего трояна так, чтобы он не выдал себя даже под пытками, ..ну или просто хотим скрыть фото зазнобы в неприглядном виде. Для решения "проблемы века", юзеры присваивают файлам атрибут скрытый, более продвинутые шифруют файлы и т.д. Но в своих закромах NTFS предлагает нам более изящные средства, причём без сторонних инструментов – нужно просто открыть и покурить её (для надёжности) несколько раз.

Здесь мы рассмотрим сразу два родственных способа маскировки.. Первый известен в узких кругах как "альтернативный NTFS-поток" ADS (Alternative Data Stream) и живёт он в системе как скрытая часть уже существующего исполнительного потока. Второй – это доставшийся нам в наследство от файловой системы HPFS (OS/2) "расширенный атрибут файла EA" (Extended Attribute). Оба варианта имеют право на жизнь, только ареал их обитания не выходит за рамки файловой системы NTFS и FAT16, что собственно и является их слабой стороной.

Введение (в заблуждение)

Скелет NTFS составляют 14 системных метафайла с приставкой($) например $MFT, $Boot, etc.. В спеках на NTFS можно найти описание всех этих файлов, поэтому не буду останавливаться на них подробно. Мы копнём только в сторону выделенного на скрине метафайла с названием $AttrDef (define, определение), который перечисляет все имеющиеся в природе атрибуты дисковых файлов. Вот как видит эти файлики hex-редактор WinHex:

Посмотреть вложение 33453

Суть в том, что NTFS рассматривает любой файл как набор атрибутов, в числе которых знакомые нам: имя файла, информация о его безопасности (скрытый, системный, архивный и т.д.), время создания/изменения, ну и конечно-же сами данные. Отметим, что полезные данные файла - это тоже его атрибут типа 0х80, в чём мы убедимся позже.

Если посмотреть на размеры метафайлов, то одним из увесистых является $MFT – Master File Table, или основная таблица файлов. Эта таблица представляет собой глобальную базу-данных буквально всех файлов на диске. Про запас, предусмотрена и зеркальная (mirror) его копия под названием $MFTMirr, правда в ней хранятся только (критически важные) первые 4К-байт записей. Согласно документации, под MFT отводится ~12% из общего пространства накопителя, которые назвали MFT-зоной. По мере того-как мы забиваем диск своим хламом, MFT обрастает соответствующими записями и динамически разбухает, пока не достигнет своего предела 12-15%:

Посмотреть вложение 33454

Таблица $MFT содержит в себе кучу файловых записей File-Record. Каждая такая запись имеет размер 1024 байта и начинается только с нового сектора диска (кратна 0x200 байтам). Признаком начала файловой записи является сигнатура "FILE", после которой идёт уже служебная информация и заголовки различных его атрибутов.

Если атрибут описываемого файла вмещаются внутри File-Record, то его назвали "резидентным". Однако некоторые атрибуты изначально являются "нерезидентными" и обитают за пределами таблицы $MFT заселяя один из свободных кластеров диска. В этом случае у файла появляется атрибут с именем $ATTRIBUTE_LIST, а внутри MFT помещают только линк на внешний (нерезидентный) атрибут. Такая вот муть..


Структура файловой записи "File-Record"

Раз-уж речь зашла об MFT и описателях файлов, бегло рассмотрим скелет одной из таких записей. Структура записи такова, что имеем один заголовок Header и несколько файловых атрибутов. Размер атрибутов нефиксирован и зависит от его типа, зато заголовок жёстко оговаривается в документации и как-правило равен 0х38 байт. Запустим тот-же WinHex и двойным кликом запросим файл $MFT:

Посмотреть вложение 33456

Начнём с того, что по-смещению 0х04 лежит указатель на т.н. "Последовательность обновлений" – в данном случае это смещение 0х30, а там прописано значение 0х00С2 (выделено зелёным). Если файл имеет размер больше одного сектора диска (512-байт или 0х200), то он занимает следующий сектор и т.д. В этом случае, по данной последовательности 0х00С2 система соберёт его по-крупинкам в один законченный файл. Значение 0х00С2 уникально для данного файла и будет лежать последним словом во-всех секторах, которые принадлежат данному файлу. Особенно актуально это для фрагментированных файлов, когда один файл размазывается чуть-ли не по всей поверхности накопителя. Утилиты восстановления данных с упавшей NTFS типа R-Studio, Recula и т.д. опираются именно на эту "Последовательность обновлений".

Но сейчас мы ищем атрибуты и в приоритете для нас значение, которое лежит по смещению 0х14 от начала записи (выделено красным), и равно оно 0х0038 – это указатель на первый атрибут данного файла, ..за ним впритык идёт следующий и т.д. Здесь уже сложней из-за того, что атрибуты файла не имеют общей структуры как заголовок выше, и отличаются как по размеру, так и по содержимому (система распознаёт их по типу, см.табл.ниже). Поэтому мы рассмотрим конкретно данный случай, протопав по указанному смещению 0х38:

Посмотреть вложение 33457

В общем случае, файловые атрибуты бывают 4-х типов: резидент безымянный или с именем, и такой-же нерезидент. Если посмотреть на поля 0х40/41, то в данном случае перед нами "безымянный резидент", тело которого полностью лежит в $MFT. Его тип имеет значение 0х10, а этот код выделен для атрибута $STANDART_INFORMATION (см.первый столбец в таблице ниже). Кому интересно тело и описание самого атрибута (в дампе выделен красным), имеет смысл отрыть документацию на NTFS.


Метафайл $AttrDef

Если загнать под пресс всё вышесказанное, то можно сделать вывод, что даже обычный текстовый файл никакой не обычный, а может иметь аж до 10-ти атрибутов, и только одним из них является $STANDART_INFORMATION со-знакомыми нам свойствами файла типа скрытый и т.п.

На рисунке ниже представлен вывернутый наизнанку файл, причём его тип и расширение не играет сейчас никакой роли – расширение парсит загрузчик файлов в Ntdll.dll позже, при загрузке этого файла с диска в память. Здесь видно, что всего атрибутов 15 и каждый имеет свой тип в диапазоне от 0х10 до 0х100. Например атрибут с именем $DATA имеет тип 0х80 и неограниченный размер, а в атрибуте типа 0х30 лежит Unicode-имя файла и т.д. Файл не обязательно должен иметь все перечисленные здесь атрибуты – это просто лист возможных вариантов. Так, атрибуты $INDEX_хх принадлежат только папкам, а $VOLUME – целым разделам (для файловой системы что дир, что том - всё это файлы):

Посмотреть вложение 33458

Те атрибуты, которые мы задействуем в своих программах я выделил на рисунке красным – это $DATA для примера с альтернативным потоком Stream, и свободная канистра – атрибут $EA (Extended Attribute), куда мы скрытно попытаемся залить шелл. Как видим, в поле "размер" расширенного атрибута красуется значение 64К и этого вполне хватить, чтобы запихать в него ассемблерного слона (а чтоб не скучал рядом ещё и слониху). Нужно отметить, что система вычисляет размер файла только по дефолтному (безымянному) потоку атрибута $DATA, так-что после наших махинаций размер файла останется прежним.

Win не имеет встроенных утилит для работы с альтернативными потоками и расширенными атрибутами. Ну а если не имеет, значит и не ведёт их учёт. Пропускают потоки между ног и антивирусы, которые следят только за безымянным потоком, что играет нам только на руку. Чтобы хоть как-то контролировать наличие атрибутов у наших программ, воспользуемся утилитой от энтузиастов . Она довольно проста в освоении, но имеет мощный функционал – фейс её представлен ниже:

Посмотреть вложение 33459

Здесь видно, что из 15-ти возможных атрибутов MFT, моя эксперементальная прожка использовала только три из них – это данные, имя программы и её основные атрибуты типа время/дата создания, флаги доступа и безопасности и т.п. Посмотрим, что можно в него добавить так, чтобы не засветиться системе.


Практика – альтернативные потоки Stream

Атрибут типа 0х80 $DATA не имеет своего имени в MFT – это основной поток нашего программного кода. Однако NTFS предлагает нам добавлять в этот атрибут ещё дочерних атрибутов с таким-же типом 0х80, но чтобы при обращении отличать их друг от друга, предписывает через двоеточие задавать им имена. Таких альтернативных потоков мы можем добавлять хоть 100 штук.

Содержимое именованых потоков лежит чисто на нашей совести – это может быть безобидная иконка для файла, а можно припарковать туда совсем недетский шелл, который отработает как самостоятельная программа. Можно комбинировать тушку, например в JPG или TXT пристроить EXE и т.д. Но вот оригинально вытащить эти данные из матки-носителя – это уже совсем из другой оперы и требует хорошей практики.

Создать именованный поток просто – достаточно ввести имя жертвы и через двоеточие приписать к нему любое имя потока например так (используя консоль). Для начала создадим базовый файл-матку, к которому будем прикреплять наш поток:

Bash:
C:\> echo Hello World! > hello.txt
Таким образом в корне диска Ц получили приветствующий мир текстовый файл размером 15-байт. Теперь напишем шелл-код, который склеим с этим текстовым файлом. Чтобы не провоцировать общество к написанию вирусов, мой шелл будет просто выводить окно – это всего пару строк на fasm'e:

C-подобный:
include 'win32ax.inc'
.data
capt   db  'shell',0
text   db  'Сработал альтернативный поток!',0
;------
.code
start: invoke   MessageBox,0,text,capt,0
       invoke   ExitProcess,0
.end start
На следующем этапе выводим на консоль содержимое этого шела в бинарном виде, и тут-же перенаправим его в альтернативный поток нашего hello.txt:

Bash:
C:\ type shell.exe > hello.txt:hide.exe
С этого момента экзешник находится внутри текстового файла и оригинал "shell.exe" можно смело удалить. Обратите внимание, что при этом размер "hello.txt" как был 15-байт, так и остался. Посмотрим, на реакцию "NTFS-Stream-Explorer", которому вскормим наш гибридный hello:

Посмотреть вложение 33460

В результате этих действий мы поженили два отдельных файла, что и показывает нам эксплорер в виде двух атрибутов – безымянного :$DATA, и дополнительного именованного потока :hide.exe:$DATA. В поле размер верхнего окна указано значение 88 – это размер атрибута в файловой записи таблицы MFT, о чём шла речь выше.

Если просто жмякнуть по "hello.txt" энтером, то нашему взору предстанет содержимое основного потока, т.е. 15-байтная надпись "Hello World!". Вызвать-же альтернативный поток можно только по его имени, например из специально заточенной для этого программной оболочки, ну или прямо из той-же консоли:

Bash:
C:\> start .\hello.txt:hide.exe
Кстати, поскольку для NTFS папки тоже являются файлами, всё сказанное применительно и для папок. То-есть можно использовать в качестве носителя шелла не только файлы, но и папки.


Расширенные атрибуты $EA

..как упоминальсь выше – это тоже один из атрибутов типа 0хЕ0 NTFS-файла. Мне так и не удалось выудить из сети какую-нибудь информацию по этому поводу, зачем их вводили, и что именно подразумевается под расширенным атрибутом. В отличии от альтернативных потоков, работать с этим атрибутом сложней и приходится прибегать к нативным API-функция из Ntdll.dll

Для создания ЕА можно использовать NtCreateFile() или NtSetEaFile(), если мы хотим добавить атрибут в уже существующий файл. Для чтения и перечисления всех атрибутов применяют функцию NtQueryEaFile(). Все эти функции для своей работы используют буфер, который оформлен в виде структуры FILE_FULL_EA_INFORMATION – вот члены этой структуры:

C-подобный:
struct FILE_FULL_EA_INFORMATION
  NextEntryOffset      dd  0   ; указатель на сл.структуру в цепочке
  Flags                db  0   ; флаги..
  EaNameLength         db  0   ; длина имени ЕА в байтах
  EaValueLength        dw  0   ; длина данных ЕА в байтах
  EaName               db  ?   ; буфер для данных ЕА
ends
Как видим, тут имеется "связной список" NextEntryOffset для перечисления нескольких атрибутов ЕА, и из этой структуры можно вытащить имя атрибута, если таковой имеется в файле. Прототипы остальных функций выглядят так:

C-подобный:
NtQueryEaFile (      ;// Чтение расширенных атрибутов
  FileHandle           ; хендл файл, открытый с доступом FILE_READ_EA
  IoStatusBlock        ; результат ввода-вывода
  Buffer               ; указатель на буфер для вывода данных
  Length               ; длина этого буфера в байтах
  ReturnSingleEntry    ; если установлено, возвращается только один элемент
  EaList OPTIONAL      ; доп.список структур FILE_GET_EA_INFORMATION с именами EA
  EaListLength         ; длина этого списка байтах
  EaIndex OPTIONAL     ; указатель на индекс запрашиваемого атрибута ЕА
  RestartScan          ; если установлено, результат является первым EA атрибутом
);

NtSetEaFile (        ;// Устанавливает расширенный атрибут
  FileHandle           ; хендл открытого файла
  IoStatusBlock        ; результат ввода-вывода
  EaBuffer             ; указатель на буфер со-структурой FILE_FULL_EA_INFORMATION
  EaBufferSize         ; его размер в байтах
);
Заключение

Файловая система NTFS достаточно устойчивая к сбоям система, способная восстанавливать сама-себя. Как правило, положить её на лопатки могут только физические разрушения секторов, в народе именуемые "бэдами" или Bad-sector. Больше информации на эту тему можно найти по следующим ссылкам:

Спецификация на NTFS:
Лучшая в сети HTML версия спецификации
Куча материала по теме:
К.Касперски -
Здрав будь! Там же:
 
  • Нравится
Реакции: alЬt и Marylin
Hardreversengineer

Hardreversengineer

Member
20.08.2019
19
5
Выше всяких похвал !
 
  • Нравится
Реакции: Marylin
A

alЬt

Grey Team
31.01.2018
54
52
Статья мне напомнила гайды кодебай 16-17го года - строгое оформление, рекомендация\мануал работает, читать приятно. Такое в мини-вики можно включать на любом тематическом форуме. Спасибо, Marylin. Золото :)
 
P

Pavel Shuhray

Member
14.12.2016
6
0
Под Win64 не запускается ("не удаётся найти .\hello.txt:hide.exe") Хотя он там есть, NTFS его видит.
 
M

morgot

Active member
25.07.2018
37
13
Я думаю, тут не в х64 дело, а в том, что в более поздних виндах этот трюк пофиксили. На 64 битной ХР все работает , а вот десятка уже все. Но , как бы никто не мешает считать данные тем же павершеллом и запустить. Вариантов много, что можно сделать.
 
  • Нравится
Реакции: Marylin
Hardreversengineer

Hardreversengineer

Member
20.08.2019
19
5
Я думаю, тут не в х64 дело, а в том, что в более поздних виндах этот трюк пофиксили. На 64 битной ХР все работает , а вот десятка уже все. Но , как бы никто не мешает считать данные тем же павершеллом и запустить. Вариантов много, что можно сделать.
Даже если бы работало, меня всё равно смущает запуск через командную строку и через двоеточие указывать exeшник. BAT-ники не менее палевные, чем EXE-шники. Конечно, сути это особо не меняет, но сама идея. Идея сама по себе крайне интересная. Marylin никогда не учит плохому и не даст готовый способ что-то скрыть или взломать, но даст намёк на то как это сделать, оставляя возможность каждому додумать алгоритм по своему. Урок вводный и не сколько про это ассемблер, сколько про файловую систему. Конечно, хотелось бы и про особенности FAT32 (и прочие) поговорить, но это как решит автор.
 
  • Нравится
Реакции: Marylin