Дела поточные

6 ноябрь, 2002 - 00:00Игорь Дериев

То, что "материальную часть" надо изучать, ни у кого не вызывает сомнений. Другое дело, каким образом. К сожалению, большинство книг и публикаций предлагают лишь совершенно банальную информацию, и так лежащую на поверхности. Однако современное ПО уже достигло такого уровня сложности, что даже самый незначительный нюанс способен привести к существенным последствиям. В первую очередь это касается недокументированных или недостаточно документированных возможностей, которые остаются неизвестными многим пользователям, но вполне могут быть взяты на вооружение злоумышленниками.
Потоки, рассматривающиеся в данной статье, относятся к файловой системе NTFS и представляют собой "альтернативные" данные, которые специальным образом могут быть ассоциированы с существующим файлом. Отсюда и их более полное и точное название -- Alternative Data Streams, или ADS. Учитывая, что эта функциональность изначально присутствовала в NTFS и, соответственно, Windows NT, многие пользователи наверняка в той или иной степени с ней знакомы. Одно из наиболее очевидных проявлений -- специальная вкладка в окне свойств файла, где можно ввести название, имя автора, комментарии и пр. Несложно убедиться, что эта возможность присутствует исключительно на разделах NTFS. Впрочем, неосведомленный пользователь никоим образом не догадается, что это реализуется посредством такой "хитрой" технологии, как ADS, поэтому давайте разберемся с ней подробнее.

Для работы с альтернативными потоками используется достаточно простой синтаксис:

<file name>:<stream name>

По сути, "основное" содержимое файла также является потоком, но неименованным, что и позволяет обращаться к нему только по имени файла (на самом деле ко всем потокам неявно добавляется суффикс :$DATA). Потоки могут ассоциироваться с любыми файлами и даже каталогами, однако мы ограничимся лишь самыми элементарными экспериментами. Необходимо создать временную папку с произвольным именем, в ней -- пустой файл test.txt, затем открыть консольное окно и перебраться на подготовленный "полигон".

Команда dir выдаст вполне предсказуемый результат:

F:\test>dir
Volume in drive F is System
Volume Serial Number is A00A-8F10
Directory of F:\test
31.10.2002 16:27 <DIR> .
31.10.2002 16:27 <DIR> ..
31.10.2002 16:27 0 test.txt
1 File(s) 0 bytes
2 Dir(s) 2 031 284 224 bytes free

Пока ничего необычного. Теперь, собственно, к делу. Хотя создавать потоки можно различными способами, мы остановимся на наиболее простом и достаточно очевидном (при условии знания синтаксиса обращения к ADS):

F:\test>echo Привет > test.txt:stream1
F:\test>echo Hello > test.txt:stream2

В общем-то, на этом эксперимент можно считать завершившимся и вполне успешным, поскольку мы действительно создали у файла test.txt два дополнительных потока с именами stream1 и stream2 и даже поместили туда кое-какую текстовую информацию. Убедиться в этом также довольно несложно:

F:\test>more < test.txt
F:\test>more < test.txt:stream1
Привет
F:\test>more < test.txt:stream2
Hello

В этом месте вполне справедливо задаться вопросом, а где же зарыта та собака, из-за которой загорелся весь сыр-бор? Действительно, пока что все происходит именно так, как и обещано, и подвоха, в общем-то, не видно. Однако нужно учитывать, что мы сами создали альтернативные потоки, выбрали им имена и пр., т. е. мы заранее знали о них все. А если бы это пришлось проделать вслепую? Попробуем.

F:\test>dir
Volume in drive F is System
Volume Serial Number is A00A-8F10
Directory of F:\test
31.10.2002 16:27 <DIR> .
31.10.2002 16:27 <DIR> ..
31.10.2002 16:33 0 test.txt
1 File(s) 0 bytes
2 Dir(s) 2 031 255 552 bytes free

Теперь затронутая проблема начинает приобретать некие очертания. Оказывается, ADS не так-то просто обнаружить. Ни dir, ни Windows Explorer, ни многие другие команды и программы не помогут. Парадоксально, но даже стандартные утилиты из состава Windows ведут себя с потоками отнюдь не однозначно. К примеру, зачем бы мудрить с more и переадресацией ввода/вывода, если есть type? Да затем, что:

F:\test>type test.txt:stream1
The filename, directory name, or volume label syntax is incorrect.

Причем все подобные нюансы можно выявить исключительно опытным путем, проведя специальный эксперимент. Используются ли в системе альтернативные потоки и для каких целей, будут ли они корректно учитываться и обслуживаться различными программами (резервирования и пр.) -- рядовому пользователю неведомо. Чтобы понять глубину этих проблем, можно привести тот факт, что в 2001 г. вдруг (напомним, что технология существует с момента появления Windows NT) обнаружилось, что практически все наиболее популярные утилиты гарантированного удаления информации оставляют данные ADS в неприкосновенности. Даже сама Microsoft признает, что альтернативные потоки данных вполне могут оказаться причиной "перерасхода" дискового пространства, однако как это выяснить наверняка и как с этим бороться -- ни слова.

Дела поточные
CrucialADS -- потоки не останутся незамеченными
Впрочем, совершенно понятно, что данная технология внедрена в NTFS неспроста. Считается, что появление ADS обусловлено необходимостью обеспечения "мирного сосуществования" в рамках одной сети платформ PC и Mac. Дело в том, что "яблочные" файлы состоят из двух потоков (в оригинале -- forks), один из которых хранит собственно содержимое, а второй -- вспомогательную информацию вроде типа файла, пиктограммы и пр. Благодаря ADS они совершенно корректно могут копироваться на и с NTFS-разделов, скажем, на файл-сервере под управлением Windows NT/2000. Бесспорно -- цель благая.

Но Microsoft не была бы сама собой, если бы ограничилась решением подобных узких проблем. Естественно, в ADS заложено гораздо больше возможностей, которые в совокупности способны превратить файловую систему в некий аналог базы данных. Скажем, уже упоминавшиеся расширенные свойства файлов (при условии, конечно, их аккуратного заполнения) позволяют организовать унифицированное хранилище разнородных документов и осуществлять в нем быстрый поиск с помощью стандартной службы индексирования (при наличии соответствующих фильтров). Этот же подход реализуется и в некоторых серверных продуктах Microsoft.

С другой стороны, наличие не слишком афишируемых функций априори означает, что рано или поздно кто-то попытается применить их в неблаговидных целях. ADS не исключение. За последние полтора-два года поступало несколько сообщений о появлении вирусов, использующих для своей деятельности альтернативные потоки данных (обычно в их названии присутствует слово stream). Справедливости ради следует сказать, что ни один из них не представлял серьезной угрозы, скорее это были "лабораторные образцы", действующие достаточно откровенно и примитивно. Скажем, один из них попросту замещал собой зараженный файл, одновременно копируя его содержимое в ADS. При этом его смогут обнаружить любые антивирусные средства.

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

Для примера попробуем проверить созданный нами test.txt с помощью Norton Antivirus. Он отрапортует только об одном проверенном файле. Если же в явном виде указать test.txt:stream1, то число исследованных файлов сократится до 0. Можно провести даже более убедительный эксперимент -- скопировать в альтернативный поток тело стандартного тестового вируса EICAR. Результат не изменится, Norton Antivirus просто не работает с ADS. То же самое относится и к подавляющему большинству других антивирусных средств -- их разработчики считают подобную угрозу несущественной.

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

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

Немногим отличается sdir -- она не поддерживает рекурсивный обход папок, зато суммирует размеры обнаруженных ADS. Программа lads совмещает возможности обеих и потому, вероятно, наиболее удобна. А crucialADS даже обеспечивает кое-какой GUI, правда, категориями, меньшими логического диска, не оперирует. Одним словом, выбрать есть из чего.

Несколько сложнее обстоит дело с удалением ADS. А все потому, что напрямую удалить альтернативный поток невозможно, поэтому приходится искать "обходные пути". Скажем, самое простое -- переместить необходимый файл с NTFS на FAT-раздел (и, при необходимости, обратно). Можно также воспользоваться теми утилитами, что не понимают ADS. Для текстовых данных вполне подойдет type:

F:\test>type test.txt > test.bat
F:\test>del test.txt
F:\test>ren test.bat test.txt

Для двоичных обычно рекомендуется утилита cat, которая входит в состав Windows 2000 Resource Kit, однако отдельно не распространяется. Естественно, проделать такие же операции с каталогами (как говорилось выше, ADS могут присоединяться и к ним) уже не получится. Существует также более универсальный пакет ads_cat (посвященный ему сайт, кажется, приказал долго жить, загрузить же архив можно по адресу packetstorm.decepticons.org/NT/), куда, кроме одноименной утилиты, входят ads_cp, ads_extract и ads_rm. Последняя -- именно для удаления, правда, в Windows XP она работает несколько странно, лишь обнуляя потоки. Поэтому по-настоящему эффективные решения сегодня придется создавать самостоятельно, например с помощью различных скриптовых средств, благо примеры имеются (вот один из наиболее хитроумных).