Автор: (c)Крис Касперски ака мыщъх
6 июня Tavis Ormandy обнаружил уязвимость библиотеки ZLIB версии 1.2.2 и более ранних, приводящую к переполнению буфера с возможностью выполнения произвольного кода на пораженной машине. Ошибка контроля допущена в функции inflate_table(), расположенной в файле inftrees.c, ключевой фрагмент которой идет ниже:
Листинг 1. Ошибка контроля в функции inflate_table() библиотеки zlib-1.2.2.
Исправленный вариант выглядит так:
Листинг 2. Та же самая функция в библиотеке zlib-1.2.3.
И хотя рабочего exploit'а в сети обнаружить не удалось, приведенной выше информации вполне достаточно, чтобы его написал любой грамотный хакер.
Это настоящая катастрофа! Библиотека ZLIB используется огромным количеством программ как с динамической, так и со статической компоновкой. А это значит, что для устранения уязвимости обновить файл zlib1.dll/libz.so будет явно недостаточно и потребуется перекомпилировать все программное обеспечение, слинкованное с ZLIB статическим способом. А если программа включает в себя фрагменты исходных текстов компрессора, "вживляя" их в свое тело, то... починить ее сможет только разработчик.
Полный список уязвимых систем можно найти на www.securityfocus.com/bid/14162/info, а заплатки к ним - на http://www.securityfocus.com/bid/14162/solution. Как и следовало ожидать, под угрозой оказались практически все платформы: Apple Mac OS X, Conectiva Linux, Debian Linux, FreeBSD, Gentoo Linux, HP-UX, Mandrake Linux, RedHat Fedora, S.u.S.E. Linux, SCO Unixware, Slackware Linux, Sun Solaris, Trustix Secure Linux, Ubuntu Linux, а также ряд прикладных программ: XFree86 X11R6, IPCop, Sun Java Enterprise System, MandrakeSoft Multi Network Firewall, IPCop, MySQL, OpenPKG, CVS и т.д.
Рисунок 1. Патч, накладываемый на библиотеку ZLIB 1.2.2 для устранения уязвимости.
До сих пор главным мотивом использования горящего лиса (и его производных) была уверенность в его безопасности. Чем больше дыр обнаруживалось в IE, тем охотнее пользователи переходили к аутсайдеру. Когда популярность лиса достигла некоторой критической отметки, хакеры взялись за него всерьез и дыры полились полноводной рекой, подмочив лису его огненно-рыжий хвост. Если так будет продолжаться и дальше, то движок Mozilla (кстати говоря, расшифровываемый как Mosaic Killer - движок, на котором основан IE), не только догонит, но и перегонит IE!
За последнее время было обнаружено огромное количество дыр в Mozill'e, позволяющих выполнять произвольный код на атакуемой машине, повышать уровень привилегий JavaScript вплоть до исполнения машинного кода, запускать JavaScript, даже когда он отключен, обрушивать браузер, предоставлять доступ к личным данным пользователя и т.д.
Все ошибки перечислять было бы слишком утомительно, вот только некоторые из них: хакер по кличке moz_bug_r_a4 обнаружил, что JavaScript, запущенный через компонент EvalInSandbox (используемый главным образом для автоматической настройки proxy), может вырваться за пределы "песочницы" и повысить свои привилегии простым вызовом valueOf(), обращаясь к объекту, созданному вне "песочницы" и "затягивая" его внутрь. Другой исследователь Mikolaj J. Habryn обнаружил переполнение буфера в функции crypto.signText() из-за неправильной обработки индексов в массивах. Также команда разработчиков столкнулась с трудновоспроизводимыми разрушениями памяти, создающими угрозу засылки shell-кода со всеми вытекающими отсюда последствиями.
Уязвимости подвержены следующие продукты: Mozilla Thunderbird 1.5.2, Mozilla SeaMonkey 1.0.1, Mozilla Firefox 1.5.3, Netscape Browser 8.0.4 (кстати говоря, более ранние версии неуязвимы). Proof-of-concept exploit'ы можно найти в базе данных "Mozilla Bugzilla", доступной только разработчикам и закрытой для публичного доступа (к счастью, присоединиться к команде может практически любой желающий).
<html> <body> <iframe src="javascript:alert('Found by www.sysdream.com !')"></iframe> </body> </html>
Листинг 3. JavaScript выполнен, даже если он отключен.
<html> <body> <iframe src="javascript:parent.document.write('Found by www.sysdream.com!')"></iframe> </body> </html>
Листинг 4. HTML-код, вызывающий крах приложения.
За более подробной информацией обращайтесь по ссылкам securityfocus.com/bid/18228, www.securityfocus.com/bid/16770/ и www.securityfocus.com/bid/17516.
Рисунок 2. FireFox исполнят JavaScript в плавающий фреймах, даже если они запрещены.
Microsoft прилагает большие усилия по защите и вылизыванию кода IE, однако поток дыр не прекращается и вот 31 мая 2006 года два хакера Mr Niega и Hariharan обнаружили переполнение локального стекового буфера в функции inetcomm!CActiveUrlRequest::ParseUrl, принадлежащей библиотеке INETCOMM.DLL.
Исходный код последних версий IE транслировался компилятором Microsoft Visual Studio .NET с ключом /GS, активирующим примитивную защиту стека от переполнения, представляющую собой некоторую разновидность Stack-Guard'а, причем далеко не в лучшей его "инаугурации". Никогда не разрабатывающая собственных продуктов, а только "ворующая" уже готовые, Microsoft, как это часто и бывает, сама не поняла, что стащила и у кого.
В практическом плане это означает, что при затирании секретного cookie, расположенного перед адресом возврата, управление получает недокументированная функция inetcomm!__report_gsfailure, завершающая приложение в аварийном режиме. Короче, грохает IE. Однако передать управление на shell-код все-таки возможно и в статье Переполняющиеся буфера - активные средства защиты показано, как это сделать.
Сами же exploit'ы выглядят довольно тривиально:
<html> <a href="mhtml://mid:AAA...AAAA">example</a> </html>
Листинг 5. Фрагмент exploit'а, поражающего IE (полный текст находится на www.securityfocus.com/data/vulnerabilities/exploits/18198.htm).
[DEFAULT] BASEURL= [InternetShortcut] URL=mhtml://mid:AAA...AAA
Листинг 6. Фрагмент exploit'а, поражающего IE (полный текст находится на www.securityfocus.com/data/vulnerabilities/exploits/18198.url.
Уязвимости подвержены следующие версии IE: 6.0, 6.0 SP1, 6.0 SP2, 7.0 beta1, 7.0 beta2, а также возможно и более младшие версии (версия 6.0.2800.1106, установленная у мыщъха неуязвима - сам проверял).
За дополнительной информацией обращайтесь на www.securityfocus.com/bid/18198/.
Рисунок 3. IE не выдержал атаки и весь раскрошился.
Опера - это быстрый, надежный, относительно безопасный и во многом культовый бразузер (не такой, конечно, культовый как Рысь, но все-таки сформировавший свое, особое сообщество - в частности мыщъх любит Оперу за развитый клавиатурный ввод, позволяющий вообще отказаться от мыши, что значительно ускоряет серфинг). Самое главное, Опера - это единственный независимый браузер, созданный с нуля и лишенный тяжелого наследия прошлого. FireFox, основанный на движке Mozilla, и IE, все еще содержащий фрагменты кода древнего Mosaic, представляют собой настоящее "кладбище" программистских технологий всех времен и народов. "Осадочные" слои кода взаимодействуют друг с другом очень сложным образом и потому ошибки вылезают то тут, то там. Добавление новых свойств требует глобального пересмотра всего кода, поскольку он уже давно превратился в сплошной клубок...
В отличие от них, Опера сначала проектировалась (с учетом всех требований современности), а потом кодировалась с четким разделением функций каждого модуля. Такой подход упрощает отладку продукта и ликвидирует целый пласт ошибок, но... не страхует от них полностью. Программ без ошибок, увы, не бывает. В Опере они тоже встречаются. Последняя была обнаружена 13 апреля 2006, исправлена и заново "переоткрыта" 7 июня, поскольку проблема оказалась намного серьезней, чем ожидалось.
Речь идет о классическом знаковом переполнении, в последнее время находящимся под прицелом хакеров всего мира. Рассмотрим следующий код и попробуем найти в нем ошибку (только чур - не подглядывать):
Листинг 7. Пример, демонстрирующий простейший случай знакового переполнения.
На первый взгляд все написано правильно - мы тщательно проверяем длину строки перед копированием в буфер... О каком переполнии тут можно говорить?! А вот о каком - о знаковом. Переменная len имеет тип signed int (в большинстве компиляторов int имеет знаковый тип по умолчанию), в то время как прототип функции strncpy выглядит так: strncpy(char *dst, char *source, unsigned int count).
Предположим, что длина строки s превышает 2 Гбайта, тогда знаковый бит переменной len будет установлен в единицу и выражение (len < MAX_LEN) окажется истинным, поскольку len отрицательный, а всякое отрицательное число, как известно, меньше любого положительного. В то же самое время функция strncpy трактует len как беззнаковый аргумент и копирует в буфер buf очень-очень много байт.
Чтобы избежать переполнения, необходимо явно объявить переменную len как unsigned int, но разработчики сплошь и рядом об этом забывают. В том числе, и разработчики Оперы.
Итак, значит, Опера. Возьмем английскую версию 8.52 и будем ее пытать (http://www.opera.com/download/index.dml?opsys=Windows&lng=en&ver=8.52&platform=Windows&local=y). Это последняя уязвимая версия и Opera 8.54 уже исправлена. Точнее - как бы исправлена. Беглый просмотр под дизассемблером показывает, что знаковое сравнение там по-прежнему встречается и всего лишь остается разобраться, какие именно входные параметры подвержены переполнению. Короче, надо копать от забора до обеда.
Начнем с того, что файл opera.exe упакован ASPack'ом - в hex-редакторе хорошо видны секции .aspack, .adata, а PEiDE даже определяет даже версию упаковщика - 2.12. Однако при своем размере 78 Кбайт, ничего интересного он содержать не может и весь функционал сосредоточен в opera.dll размером 2,3 Мбайт, который также упакован все тем же ASPack'ом.
Рисунок 4. Утилита PEiD определила, что opera.exe упакована ASPack'ом.
Чтобы не искать готовый распаковщик (не все распаковщики умеют распаковывать динамические библиотеки), воспользуемся утилитой PE-TOOLS и снимем дамп с opera.dll. Таблица импорта останется искаженной, но зачем она нам?! Мы же ведь не crack собрались писать, а проводить исследование на предмет безопасности. Главное, чтобы полученный дамп можно было загрузить в IDA Pro или hiew, а все остальное - уже дело техники!
Рисунок 5. Снятие полного дампа памяти с opera.dll утилитой PE Tools.
Поскольку стартовый код точки входа в dll (dllentry) искажен, IDA Pro не может опознать компилятор и загрузить сигнатуры, оставляя нас без библиотечных имен, что значительно усложняет анализ. Впрочем, отождествить компилятор можно и вручную по текстовым строкам, оставленным из патриотических соображений поборников авторский прав. Просмотр дампа в hiew'е убеждает нас в том, что Опера была скомпилирована ничем иным, как Microsoft Visual C++:
.67F3DFBC: 4D 69 63 72-6F 73 6F 66-74 20 56 69-73 75 61 6C Microsoft Visual .67F3DFCC: 20 43 2B 2B-20 52 75 6E-74 69 6D 65-20 4C 69 62 C++ Runtime Lib .67F3DFDC: 72 61 72 79-00 00 00 00-52 75 6E 74-69 6D 65 20 rary Runtime
Листинг 8. Поиск текстовых строк в opera.dll позволяет легко и быстро отождествить компилятор.
Остается только загрузить соответствующие сигнатуры. Это делается так: в меню File IDA Pro выбираем пункт Load file -> FLIRT signature file, в появившимся списке имеющихся сигнатур находим строку "vc32rtf Microsoft VisualC 2-7/net runtime" и с удовлетворением жмем <ENTER>. Вот теперь с файлом можно по-настоящему работать!
Как найти места потенциального знакового переполнения? Существует множество путей. Например, можно искать все команды JL, JLE или (если этих команд окажется слишком много) перебирать все вызовы строковых функций типа _strlen, _strcpy, _wcsncpy, обращая внимая на те из них, что соседствуют со знаковым сравнением длины копируемой строки. Это уже почти переполнение! "Почти", потому что для совершения атаки необходимо, чтобы копируемые данные были как-то связаны с пользовательским вводом и нигде не "усекались" по пути. В принципе, задачу можно автоматизировать, написав специальный скрипт, но его разработка займет довольно продолжительное время, поскольку придется учитывать слишком много ситуаций, так что "ручная" работа все же окажется эффективнее.
Рисунок 6. Уязвимая функция глазами дизассемблере IDA Pro.
Bernhard Mueller, работающий в австрийской компании SEC Consult Unternehmensberatung GmbH, нашел одно из таких мест (о чем и рапортовал разработчикам Оперы, немедленно исправившим версию 8.54 и текущую 9.0), однако в программе по-прежнему присутствует большое количество ошибок подобного типа, которые ждут своего хакера, поэтому нелишне присмотреться к уже заткнутой дырке поподробнее.
.text:67B8CEFE n2k_vulnerably proc near ; CODE XREF: sub_67B4DB72+9D6?p .text:67B8CEFE ; sub_67B8AE6E+1B4?p .text:67B8CEFE .text:67B8CEFE arg_src = dword ptr 4 .text:67B8CEFE arg_len = dword ptr 8 .text:67B8CEFE .text:67B8CEFE A1 60 EF F9 67 mov eax, dword_67F9EF60 ; pObj .text:67B8CF03 53 push ebx ; сохраняем ebx .text:67B8CF04 56 push esi ; сохраняем esi .text:67B8CF05 57 push edi ; сохраняем edi .text:67B8CF06 8B 7C 24 14 mov edi, [esp+0Ch+arg_len] ; edi := arg_len .text:67B8CF0A 8B 70 40 mov esi, [eax+40h] ; pDestination .text:67B8CF0D 81 FF 00 10 00 cmp edi, 1000h ; проверка длины arg_len .text:67B8CF13 8B D9 mov ebx, ecx ; this call .text:67B8CF15 7C 05 jl short loc_67B8CF1C ; see! over here! .text:67B8CF17 BF FF 0F 00 00 mov edi, 0FFFh ; "усечение" arg_len .text:67B8CF1C .text:67B8CF1C loc_67B8CF1C: ; CODE XREF: n2k_vulnerably+17?j .text:67B8CF1C 57 push edi ; size_t .text:67B8CF1D FF 74 24 14 push [esp+10h+arg_src] ; wchar_t * .text:67B8CF21 56 push esi ; wchar_t * .text:67B8CF22 E8 E9 C0 31 00 call _wcsncpy ; копируем имя шрифта .text:67B8CF27 66 83 24 7E 00 and word ptr [esi+edi*2],0 ; ставим завершающий нуль .text:67B8CF2C 83 C4 0C add esp, 0Ch ; выталкиваем аргументы .text:67B8CF2F 8B CB mov ecx, ebx ; this call .text:67B8CF31 56 push esi ; скопированный arg_len .text:67B8CF32 E8 D9 FD FF FF call sub_67B8CD10 ; обрабатываем имя шрифта .text:67B8CF37 66 85 C0 test ax, ax ; все ок? .text:67B8CF3A 7D 0C jge short loc_67B8CF48 ; имеем хэндл .text:67B8CF3C 8B 8B D0 05 00 mov ecx, [ebx+5D0h] ; обработчик ошибки .text:67B8CF42 E8 75 F8 FF FF call sub_67B8C7BC ; eax := [ecx] .text:67B8CF47 40 inc eax ; eax++ .text:67B8CF48 .text:67B8CF48 loc_67B8CF48: ; CODE XREF: n2k_vulnerably+3C?j .text:67B8CF48 5F pop edi ; восстанавливаем edi .text:67B8CF49 5E pop esi ; восстанавливаем edi .text:67B8CF4A 5B pop ebx ; восстанавливаем ebx .text:67B8CF4B C2 08 00 retn 8 ; выталкиваем аргументы .text:67B8CF4B n2k_vulnerably endp ; конец процедуры
Листинг 9. Дизассемблерный листинг уязвимой функции n2k_vulnerably со знаковым переполнением.
Как мы видим, эта процедура (назовем ее n2k_vulnerably) принимает два аргумента - указатель на строку и длину этой строки, которая затем сравнивается знаковой операцией с константой 1000h, в результате чего допустимый диапазон длин строк оказывается равен [0, 1000h) и (7FFFFFFFh, FFFFFFFFh]. Затем эта строка копируется внутрь какой-то структуры (по всей видимости - объекта, поскольку присутствуют вызовы типа this call), который передается функции sub_67B8CD10 для обработки.
Очевидно, что передав строку размером 2 Гбайта или выше, мы затрем добрую половину адресного пространства приложения, отчего ему станет очень нехорошо. В лучшем случае дело кончится крэшем, в худшем - передачей shell-кода и захватом управления. Вот только передать такую длинную строку по сети очень проблематично. Даже если жертва сидит на DSL, атака растянется на несколько часов и пользовать, скорее всего, просто закроет Оперу или соединение будет выбито по тайм-ауту.
Но... к счастью для хакеров разработчики Оперы допустили двойную ошибку, использовав расширение слова до двойного слова. Со знаком, разумеется. Куда же без него! (По правде говоря, за разработчиков это сделал компилятор, разработчики лишь использовали неправильное преобразование типов, но пользователям Оперы от этого ничуть не легче). Причем это преобразование осуществляется в функции, вызывающей n2k_vulnerably!
Ниже приведен ее ключевой фрагмент с некоторыми сокращениями:
.text:67B8AF5D loc_67B8AF5D: ; CODE XREF: sub_67B8AE6E+F8?j .text:67B8AF5D 89 46 2C mov [esi+2Ch], eax .text:67B8AF60 EB 16 jmp short loc_67B8AF78 .text:67B8AF62 .text:67B8AF62 loc_67B8AF62: ; CODE XREF: sub_67B8AE6E+E2?j .text:67B8AF62 0F BF 45 EC movsx eax, [ebp+ var_length_ovfl] .text:67B8AF62 ; вот оно! расширение слова, хранящего длину копируемой .text:67B8AF62 ; строки, до двойного слова со знаком .text:67B8AF62 ; если длина строки превышает 7FFFh байт, .text:67B8AF62 ; то и результат превышает 7FFFFFFFh .text:67B8AF62 ... .text:67B8B012 FF 76 08 push dword ptr [esi+8] ; передаем arg_src функции .text:67B8B015 8B 0D 18 EF F9 mov ecx, dword_67F9EF18 ; this .text:67B8B01B 8D 85 B0 FD FF lea eax, [ebp+var_250] ; получаем arg_len .text:67B8B021 50 push eax ; передаем arg_len функции .text:67B8B022 E8 D7 1E 00 00 call n2k_vulnerably ; вызываем функцию
Листинг 10. Уязвимый код, вызывающий функцию n2k_vulnerably и передающий ей в качестве arg_len знаковое слово, расширенное (со знаком!) до двойного слова.
Код функции довольно громоздкий и потому приведен не полностью. Под сокращение, в частности, попала передача расширенного EAX в переменную [EBP+var+250], но тот факт, что она передается, сокращает длину переполняемой строки всего до 8000h байт или 32 Кбайт, что вполне приемлемо для атаки.
Остается выяснить - что же это за строка такая и как она связана с пользовательским вводом (и связана ли вообще). Ответ дает функция sub_67B8CD10, вызываемая из n2k_vulnerably.
Вот ее дизассемблерный текст:
.text:67B8CD10 sub_67B8CD10 proc near .text:67B8CD5C FF 74 24 14 push [esp+0Ch+arg_0] ; передаем "свой"аргумент... .text:67B8CD60 E8 D3 FE FF FF call sub_67B8CC38 ; ...подфункции sub_67B8CC38 ... ; // дизассемблерный листинг подфункции sub_67B8CC38 .text:67B8CC38 sub_67B8CC38 proc near ; CODE XREF: sub_67B8CB3C:loc_67B8CBA5? .text:67B8CC38 ; sub_67B8CD10+50?p ... .text:67B8CC38 .text:67B8CC38 arg_0 = dword ptr 8 .text:67B8CC38 .text:67B8CC38 56 push esi .text:67B8CC39 8B 74 24 08 mov esi, [esp+arg_0] .text:67B8CC3D 68 94 24 F5 67 push offset aSerif ; "SERIF" .text:67B8CC42 56 push esi .text:67B8CC43 E8 3D 30 0A 00 call sub_67C2FC85 ; обработка шрифта .text:67B8CC48 59 pop ecx .text:67B8CC49 85 C0 test eax, eax .text:67B8CC4B 59 pop ecx .text:67B8CC4C 74 04 jz short loc_67B8CC52 .text:67B8CC4E 33 C0 xor eax, eax .text:67B8CC50 5E pop esi .text:67B8CC51 C3 retn .text:67B8CC52 .text:67B8CC52 loc_67B8CC52: ; CODE XREF: sub_67B8CC38+14?j .text:67B8CC52 68 88 24 F5 67 push offset aSansSerif_0 ; "SANS-SERIF" .text:67B8CC57 56 push esi .text:67B8CC58 E8 28 30 0A 00 call sub_67C2FC85 ; обработка шрифта .text:67B8CC5D 59 pop ecx .text:67B8CC5E 85 C0 test eax, eax .text:67B8CC60 59 pop ecx .text:67B8CC61 74 05 jz short loc_67B8CC68 .text:67B8CC63 6A 01 push 1 .text:67B8CC65 .text:67B8CC65 loc_67B8CC65: ; CODE XREF: sub_67B8CC38+43?j .text:67B8CC65 ; sub_67B8CC38+58?j .text:67B8CC65 58 pop eax .text:67B8CC66 5E pop esi .text:67B8CC67 C3 retn .text:67B8CC68 .text:67B8CC68 loc_67B8CC68: ; CODE XREF: sub_67B8CC38+29?j .text:67B8CC68 68 80 24 F5 67 push offset aFantasy ; "FANTASY" .text:67B8CC6D 56 push esi .text:67B8CC6E E8 12 30 0A 00 call sub_67C2FC85 ; обработка шрифта
Листинг 11. Переполняющая строка передается функции, обрабатывающей шрифты, это позволяет предположить, что строка представляет собой имя шрифта.
Имена шрифтов сразу же бросаются в глаза. Ага! Значит, эта функция управляет стилем оформления страницы, загружая соответствующий шрифт. И это хорошо, потому что шрифты мы можем принудительно менять через CSS. Главное, чтобы длина имени шрифта (необязательно реально существующего, вполне сойдет и фиктивный), превышала 32 Кбайта. Вместе с именем может быть передан shell-код, который пойдет гулять по куче (динамической памяти), основательно ее затирая. Ну, а технику переполнения кучи мы уже неоднократно рассматривали в прошлых номерах “Хакера”.
Ниже приведен код простейшего exploit'а, "роняющего" Оперу версий 8.52 и более младших (впрочем, атака может не сработать, если CSS отключен):
<STYLE type=text/css>A { FONT-FAMILY: 35000x'A' } </STYLE>
Листинг 12. Код простейшего CSS-exploit'а, вызывающего обрушение Оперы.
Для ликвидации уязвимости необходимо скачать новую версию Оперы (благо, она бесплатна) или... ликвидировать дыру собственными руками! Действительно, зачем перекачивать несколько мегабайт по модему, переустанавливать и т.д., когда нас и текущая версия вполне устраивает. Как известно, с каждой новой версией программное обеспечение все толстеет и толстеет, становится неповоротливым, не принося никаких существенно новых фич.
Всего-то и нужно - заменить 67B8CF15: JL loc_67B8CF1C (7Ch 05h) на JB loc_67B8CF1C (72h 05h). Если бы файл не был упакован, это можно было бы сделать прямо в hiew'е, а так... Нет, конечно, распаковать opera.dll вполне возможно, тем более, что ASPack - упаковщик вполне известный, но... не всегда распаковка проходит успешно и потом начинают вылезать баги в разных местах.
Мы пойдем другим путем, прибегнув к on-line patch'у, то есть запустим opera.exe, дождемся распаковки opera.dll и исправим байты прямо в оперативной памяти! Аналогичный подход может быть применен и к другим программам, не только к Опере, поэтому ниже приводится исходный текст простейшего универсального on-line patсher'а.
Листинг 13. Исходный текст on-line patcher'a opera_loader.c.
Естественно, теперь каждый раз придется запускать не opera.exe, а opera_loader.exe. Впрочем, чтобы не напрягаться, достаточно всего лишь сменить ярлыки и файловые ассоциации. Правда, в силу небольшой конструктивной недоработки on-line patcher'а, он не передает Опере аргументов командой строки, поэтому если она установлена основным браузером по умолчанию, то htm-файлы открываться не будут! Используйте drag-n-drop или доработайте patcher "напильником" до законченной конструкции.
Главное, что мы заткнули дыру своими собственными силами и нам не понадобились никакие обновления. Но если захочется получить дополнительную информацию по уязвимости, то милости просим посетить следующие ресурсы: http://www.securityfocus.com/bid/17513, http://www.greymagic.com/security/advisories/gm008-op/, а мыщъх тем временем идет спать, сожрав феназепам, подтолкнув под себя хвост и нацепив наушники, в которых разворачивается aus der tiefe.