Раздел: Документация
0 ... 48 49 50 51 52 53 54 ... 102 ретЫ, tpoKT!Pggg!!lMW shellKC«a16Jl л£1-файле shell-код располагается, начиная с адреса lOOOh, и нродолжает-1""°В ьмого конца файла. Точнее, практически до самого конца — один или два f" вых байта -могУт "РисУтствовать по соображениям выравнивания, однако Si*мешают- ь полученный двоичный файл необходимо зашифровать (если, конечно, "нкод содержит в себе шифровщик). Чаще всего для этого используется уже * "омяиутый HIEW, реже — внешний шифровщик, на создание которого обыч-"""nXouiit не больше, чем десяток минут: fopen/fread/for(a = FROMCRYPT; ""то CRVPT; a-h=sizeof(key)) buf[a] л= key:/fwrite. При всех достоинства HIEWa -тавный минус его шифровщика заключается в том, что полностью автоматизировать процесс трансляции shell-кода в этом случае оказывается невозможно и при частых перекомпиляциях необходимость ручной работы дает о себе чиать. Тем не менее... лучше за час долететь, чем за пять минут добежать — программировать внешний шифровщик поначалу лениво, вот все и предпочитают заниматься Кама-Сутрой с HIEWom, чем автоматизировать серые будни унылых дождливых дней окружающей жизни. Готовый shell-код тем или иным способом имплантируется в основное тело червя, как правило, представляющее собой Си-программу. Самое простое (но не самое лучшее) — подключить shell-код как обыкновенный obj-файл, однако этот путь не свободен от проблем. Чтобы определить длину shell-кода, потребуются две публичные метки — в его начале и конце. Разность их смещений и даст искомое значение. Но это еще что — попробуйте-ка с разбега зашифровать obj-файл. В отличие от «чистого» двоичного файла, привязываться к фиксированным смещениям здесь нельзя и приходится прибегать к анализу служебных структур п заголовка, что также не добавляет энтузиазма. Наконец, нетекстовая природа obj-файлов существенно затрудняет публикацию и распространение исходных текстов червя. Поэтому (а может быть, просто в силу традиции) 5 е 1-код чаще всего внедряется в программу непосредственно через строковой массив, олаго язык Си поддерживает возможность введения любых НЕХ-сим-волов,естественно, за исключением ноля, так как последний служит символом ок°нчаиия строки. сов М0ЖеТ выглядеть, например, так (разумеется, набивать hex-коды вручную Рый ИН° Не ооязатсльно — быстрее написать несложный конвертер, кото-ВСе лаетза вас) (листинг 4.36). 4.36. Пример включения sheil-кода в Си-программу 3UChar х8Г-гьгеаОП -•WlX?Xx6aU00Xx54x50\x50\xbO\xO3\xccl\x8O\x83\xc5" Nx°CA*ff\xfiAxer. Иерь пРети"ь>Г°Ворим 00 укрощении компилятора и оптимизации программ. Как ГТаточц0Ь КОМП11ЛЯТОРУ внедрять start-up и RTL-код? Да очень просто — до-Г°Чк-уьхоНе °Ъявлять функцию main, принудительно навязав линкеру новую "Wm!? ПосРедством ключа /ENTRY. Покажем это на примере следующей нпо-<листинг 4.37) Листинг 4.37. Классический вариант, компилируемый обычным способом: cl evB /0х«1е.г #include <windows.h> ma-ri() I MessageBox(0. "Sailor", "Hello". 0): } < Будучи откомпилированной с настройками по умолчанию, то есть cl Ox "file name.с", программа образует исполняемый файл, занимающий 25 Кб* Не так уж и много, но не торопитесь с выводами (листинг 4.38). Сейчас вы дите такое...ув,! Листинг 4.38. Оптимизированный вариант, компилируемый так: cl.exe /с /Ох file с а линкуемый так: link.exe /ALIGN-.32 /DRIVER /ENTRY:my main / SUBSYSTEM:console file.obj USER32.lib #include <windows.h> my main() { Message3ox(0. "Sailor". "Hello". 0): } Слегка изменив имя главной функции программы и подобрав оптимальные ключи трансляции, мы сократили размер исполняемого файла до 864байт. причем большую его часть будет занимать РЕ-заголовок, таблица импорта и пустоты, оставленные для выравнивания. То есть на реальном полновесном приложении, состоящем из сотен, а то и тысяч строк, разрыв станет еще более заметным, но и без этого мы сжали исполняемый файл более чем в тридцать раз (!). причем безо всяких ассемблерных извращений. Разумеется, вместе с RTL гибнет и подсистема ввода-вывода, а, значит, большинство функций из библиотеки stdio использовать не удастся и придется ограничиться преимущественно API-функциями. Под Windows 9х файлы с таким выравниванием работать не будут, так что переходите на NT или производи* от нее системы. ДЕКОМПИЛЯЦИЯ ЧЕРВЯ Обсуждая различные аспекты компиляции червя, мы решали задачу, двнеТ. от прямого к обратному. Но стоит нам оглянуться назад, как позади не ся ничего. Приобретенные навыки трансляции червей окажутся "Рдн-или полностью бесполезными перед лицом их анализа. Ловкость ДнзаС1)3 K0Tf ровапия червей опирается на ряд неочевидных тонкостей, о некоторые рых я и хочу рассказать. Первой и наиболее фундаментальной проблемой является поиск точ10дятД° Подавляющее большинство червей, выловленных в живой г,РиР°де0 в*" исследователей либо в виде дампа памяти пораженной машины. отрубленное ином e-zine. отрубленной головы, либо... в виде исходного кода, опубликование0 8 - И Листинг 4.39. Фрагмент исходного кода червя .№ SplOltG - {
ЗхОА. OxOD.OxOA }: Попытка непосредственного дизассемблирования shell-кода ни к чему хорошему не приведет, поскольку голова червя начинается со строки "GET / АААААААААААААААААА-" ни в каком дизассемблировании вообще не нуждающейся. С какого байта начинается актуальный код — доподлинно неизвестно. Для определения действительного положения точки входа необходимо «скормить» голову червя уязвимому приложению и посмотреть: куда метнется регистр EIP. Это (теоретически!) и будет точкой входа. Практически же это отличный способ убить время, но не более того. Начнем с того, что отладка - опасный и неоправданно агрессивный способ исследования. Экспериментировать с «живым» сервером вам никто не даст, и уязвимое программное обеспечение должно быть установлено на отдельный компьютер, на котором нет ничего такого, что было бы жалко потерять. Причем это должна быть именно та версия программного обеспечения, которую вирус в состоянии поразить, ничего не обрушив, в противном случае управление получит отнюдь не истинная точка входа, а неизвестно что. Но ведь далеко не каж-1ын исследователь имеет в своем распоряжении -«зоопарк» программного июспечения различных версий и кучу операционных систем! К тому же далеко не факт, что нам удастся определить момент передачи унравле-шя shell-коду. Тупая трассировка здесь не поможет, - современное программки; обеспечение слишком громоздко, а передача управления может осуществ-шться спустя тысячи, а то и сотни тысяч машинных инструкций, выполняемых, том числе, н в параллельных потоках. Отладчиков, способных отлаживать не-тсолько потоков одновременно, насколько мне известно, не существует (во вся--ом случае, они не были представлены на рынке). Можно, конечно, установить исполняемую» точку останова на регион памяти, содержащий в себе принимавший буфер, но это не поможет в тех случаях, когда shell-код передается по це-">чкебуферов, лишь один из которых подвержен переполнению, а остальные — "нолне нормальны. Имеете с тем определить точку входа можно и визуально. Просто загрузит -hell--------..... -г....................------- " е s е них тот, что дает наиболее осмысленный код. Эту операцию удобнее всего код в дизассемблер и, перебирая различные стартовые адреса, выберит гифетнтроектирования shell-кода , -- Казалось бы. наличие исходного кода просто не оставляет места для вопросов. \н нет! Вот перед нами лежит фрагмент исходного текста червя IIS-Worm . shell-кодом внутри (листинг 4.39). 0 ... 48 49 50 51 52 53 54 ... 102
|