Обзор эксплойтов Крис Касперски Хакер, номер #108, стр. 108-054-1 Текущий обзор посвящен компании Adobe, в продуктах которой обнаружено множество знаменательных дыр, допускающих возможность удаленного захвата управления, чем уже с успехом воспользовались черви, вызвав очередную волну эпидемии. Acrobat Reader: удаленное выполнение кода через mailtoBrief20 сентября 2007 года хакер по кличке pdp (pdp.gnucitizen@googlemail.com) обнаружил серьезную дыру в Acrobat Reader'е, обнародовав ее в своем блоге (www.gnucitizen.org/blog/0day-pdf-pwns-windows). Adobe отреагировала на эту предъяву лишь 22 октября (притом что первый публичный эксплойт появился 16 октября). А на следующий день, 23 октября, корпорация Symantec изловила живого червя Trojan.Pidief.A (он же EXPL_PIDIEF.B [Trend], он же Troj/PDFex-A [Sophos]), написанного китаянкой Elia Florio и распространяющегося по электронной почте вместе с вложениями invoice.pdf, your_bill.pdf, bill.pdf и statemet.pdf (смотри symantec.com/business/security_response/writeup.jsp?docid=2007-102310-3513-99&tabid=2 и symantec.com/enterprise/security_response/weblog/2007/10/when_pdfs_attack_again.html). Это довольно необычная дыра, возникающая на стыке Adobe Acrobat Reader'а с MS IE7 в процессе определения приложения, ответственного за обработку протокола mailto. Чтобы форсировать автоматический запуск исполняемого приложения, достаточно создать: «<</URI(mailto:test%../../../../../../../../windows/system32/calc.exe".cmd)/S/URI>>». И тогда на XP|Server 2003/IE7 при локальном открытии pdf-документа запустится калькулятор без каких бы то ни было дополнительных действий со стороны жертвы (кликать по ссылке необязательно). Открытие документа через pdf-ActiveX plug-in обойти сложнее: seclists.org/bugtraq/2007/Oct/0213.html. Более подробную информацию о дыре можно получить на www.securityfocus.com/bid/25748/, www.symantec.com/avcenter/attack_sigs/s22634.html и www.symantec.com/security_response/vulnerability.jsp?bid=25748. TargetsУязвимости подвержены только системы с XP|Server 2003/IE7 и стандартным почтовым клиентом по умолчанию. Версия Acrobat'а не имеет значения, баг косит все билды подряд от 3.х до 8.х. ExploitПубличная версия эксплойта, запускающего калькулятор, выложена на security.fedora-hosting.com/0day/pdf/pdf_poc.pdf, а рядом с ней лежит и ее описание: security.fedora-hosting.com/0day/pdf/pdf_poc.txt. Все это добро на всякий случай скопировано на мой сервер: http://nezumi.org.ru/souriz/hack/pdf_poc.7z. SolutionsПользователи Acrobat Reader'а версий 7.х-8.x могут установить заплатку от Adobe или, следуя радикальным предписаниям последней, отключить обработку протокола mailto в реестре: www.adobe.com/support/security/bulletins/apsb07-18.html. Остальным же рекомендуется просто установить любой другой мыльник, назначив его почтовым клиентом по умолчанию. Adobe Flash Prayer: удаленное выполнение кодаBrief15 июля 2007 года клевые китайские хакеры Stefano DiPaola, Elia Florio (создательница вируса Trojan.Pidief.A) и Giorgio Fedon из Ph4nt0m Security Team (www.ph4nt0m.org) лихо подломали Adobe Flash Player 9.0.45.0, используемый кучей браузеров (в том числе и на игровых консолях!). А наши братья по разуму - luoluo и yunshu - заточили под это дело нехилый эксплойт: www.icylife.net/yunshu/attachment.php?id=5 с shell-кодом внутри. История получила продолжение 17 июля, когда Henke37 обнаружил множественные signed/unsigned ошибки переполнения в flv-парсере, а yunshu заточил под это дело еще один эксплойт. 31 октября эхо атаки докатилось и до Оперы, а точнее, до Adobe Flash Player'а, работающего в ее контексте. Суть бага такова: парни из Adobe решили копировать буфер двойными словами (это быстрее) и потому тщательно проверили наличие на кассе по меньшей мере 8 байт, а вот о большей мере впопыхах как-то позабыли, позволив инструкции REP MOVSD чесать по куче во весь опор. А что у нас интересного в куче? Ну, например, указатели на виртуальные функции, одна из которых вызывается вслед за переполнением :). TargetsУязвимость подтверждена в следующих версиях Flash Player'а: 7.0.69.0, 8.0.34.0, 9.0.28.0, 9.0.31.0, 9.0.45.0, а также некоторых других. Затронуты практически все платформы: Windows, Linux, Mac OS X и даже игровая консоль Nintendo Wii! ExploitРеально работающий эксплойт (вместе с объяснениями принципов его работы) лежит на packetstorm.linuxsecurity.com/0707-exploits/07162007-flash_flv_9.0.45.0_exp.zip, а на www.securityfocus.com/data/vulnerabilities/exploits/24856.zip - его зеркало. SolutionУстановить обновление от Adobe (adobe.com/support/security/bulletins/apsb07-12.html) или же от конкретного производителя браузера, например для Оперы: www.opera.com/support/search/view/868. Photoshop: множественные переполнения буфераBrief10 октября 2007 года хакер Marsu (Marsupilamipowa@hotmail.fr) обнаружил очередную ошибку переполнения буфера в Photoshop'е/Illustrator'е. На этот раз - в парсере BMP, DIB и RLE-файлов. Вполне классическая ситуация. Тривиальное стековое переполнение, допускающее возможность передачи управления на shell-код, расположенный здесь же, в переполняемом буфере. Под W2K атака реализуется на ура без каких бы то ни было осложнений. XP SP2 с аппаратной поддержкой DEP, задействованной для всех приложений (по умолчанию DEP включен только для системных процессов и некоторых родных Windows-программ типа IE), ломается чуть-чуть сложнее, и для обхода защиты от неисполняемого стека нам приходится прибегать к атаке типа return2libc (смотри http://nezumi.org.ru/zq-nx.uncensored.zip). А вот Виста и Server 2008 уже создают хакеру серьезную преграду, поскольку рандомизируют адресное пространство, и, чтобы передать управление на shell-код, приходится не по-детски извращаться. Перспективы атаки в целом представляются не слишком обнадеживающими - Photoshop с Illustrator'ом не самые распространенные среди пользователей программы. Зато для целенаправленных атак на различные издательства и дизайн-студии разворачивается совсем нехилое поле деятельности, тем более что расширение файла не играет никакой роли и для маскировки BMP можно переименовать в JPG (рассылка BMP вызывает определенные подозрения, поскольку это не самый популярный формат среди профи). Более подробную информацию о дыре можно нарыть на www.securityfocus.com/bid/23621. TargetsДыра подтверждена в Adobe Photoshop CS2/CS3, Adobe Illustrator CS3 и Adobe GoLive 9. ExploitProof-of-concept эксплойт, заточенный хакером Marsu и протестированный под XP SP2, лежит на www.securityfocus.com/data/vulnerabilities/exploits/23621.c. В случае успешной работы он запускает калькулятор (кто его только не запускает... - прим. Forb’а). SolutionУстановить обновление для соответствующего продукта, загрузив его с сервера www.adobe.com. PageMaker: переполнение длинными именами фонтовBrief9 октября 2007 года китаец... нет, не китаец, а уже японец! Японец Tan Chew Keong обнаружил в PageMaker'е ошибку переполнения стека, вызываемую длинными именами шрифтов, сохраненными в pmd-файлах, и обнародовал эксплойт, но спустя короткое время убрал его из публичного доступа. Вот су... суровый человек! Впрочем, я написал свой собственный (но об этом ниже). Дефект сидит в динамической библиотеке MAIPM6.dll и не представляет собой ничего интересного. Ну подумаешь, забыли проверить длину фонта перед его копированием в буфер. PageMaker также не относится к широко распространенным программам, и об этой ошибке можно было бы и забыть, по ходу дела списав ее в утиль, если бы не одно важное обстоятельство. PageMaker широко используется в издательствах и других крупных фирмах, обменивающихся макетами и файлами презентаций в формате pmd, причем количество незалатанных машин, на которых установлен дырявый PageMaker, не поддается никакому учету! Поскольку нарыть в Сети техническую информацию об уязвимости не удалось, я (вовлеченный в очередной виток пен-тестинга) занялся самостоятельной исследовательской деятельностью. TargetsВ настоящее время уязвимость подтверждена в Adobe PageMaker 7.0.1/7.0.2; другие версии не проверялись, но есть все основания полагать, что дыра присутствует и там. ExploitДемонстрационный эксплойт, вызывающий инструкцию INT 03h, лежит на: http://nezumi.org.ru/souriz/hack/nezumi-pagemaker-MAIPM6-bug.7z. Он протестирован под W2K и должен работать под XP в конфигурации по умолчанию (если задействован аппаратный DEP для всех приложений, эксплойт следует доработать, задействовав атаку типа return2libc). SolutionУстановить обновленную версию динамической библиотеки MAIPM6.dll, выпущенную производителем: www.adobe.com/support/security/bulletins/downloads/MAIPM6.zip. Full discloseДля экспериментов нам понадобится PageMaker 7.x, 30-дневную испытательную версию которого можно бесплатно скачать у Adobe, предварительно зарегистрировав там халявный аккаунт (https://www.adobe.com/cfusion/tdrc/index.cfm?loc=en%5Fus&product=pagemaker). Если хочешь сэкономить 64 Мб трафика, возьми его с диска, прилагаемого к журналу. Установка не вызывает никаких проблем и проходит без сучка и задоринки. Чтобы не засирать машину всяким барахлом, рекомендуется использовать VMware или другой эмулятор подобного типа, особенно если ты не собираешься работать с PageMaker'ом в дальнейшем. И вот этот монстр установлен! Запускаем Pm70.exe и выбираем какой-нибудь шаблон проекта, немного поиздевавшись над которым, сохраняем на диск с расширением pmd (например, nezumi.pmd). На этом подготовительные мероприятия можно считать законченными. Мы получили файл, над которым будем медитировать на протяжении всей статьи. Открываем nezumi.pmd в hiew'е и ищем там какое-нибудь имя шрифта, например Courier, и ведь находим его по смещению 24B0h. Естественно, в зависимости от структуры файла это смещение может и другим, но это неважно. Пока лишь просто запомним его, попутно обратив внимание на непонятную, но очень интересную структуру a-ля «1 :) :) :) :) :)», расположенную чуть ниже. Позже она нам очень понадобится! Впрочем, не будем забегать вперед и вернемся в настоящее время. А в настоящем времени мы нажимаем <F3> (Edit) и дописываем к Courier длинный ряд шестерок, затирающий своим хвостом структуру «1 :) :) :) :) :)». Если переполнять, то уж наверняка. Почему именно шестерки? Просто нравятся они мне! Большинство хакеров использует для переполнения последовательность «AAA...AAA», что работает ничуть не хуже. Кстати, прежде чем затирать файл, его рекомендуется скопировать, например в nezumi-3.pmd, чтобы сохранить оригинал для возможности отката. Теперь сохраняем изменения по <F9> и выходим. Загружаем nezumi-3.pmd в PageMaker (если нас спросят: «Open the most recent version?», отвечаем: «No, thank you») и получаем крэш: «Инструкция по адресу 0x36363636 обратилась к памяти по адресу 0x36363636. Память не может быть read». Что это значит?! 36h – hex-код ASCII-символа «6». Инструкция по адресу 36363636h не собиралась читать память по адресу 36363636h, это она сама не может быть прочитана процессором, потому что такой памяти нет, точнее, она не выделена. Тот факт, что регистр EIP (указатель команд) принял значение 36363636h, говорит о том, что затираемый код перекрыл собой адрес возврата из функции, на который мы можем воздействовать, передавая управление туда, куда нам заблагорассудится! Для дальнейших экспериментов нам понадобится какой-нибудь отладчик, например бесплатный OllyDebugger (www.ollydbg.de) или его хакнутый клон Immunity Debugger с поддержкой скриптов, написанных на Питоне (http://debugger.immunityinc.com/register.html). Лично я ненавижу Питон еще с того дня, когда обнаружил, что тот относится к форматированию листинга так же строго, как Си к соблюдению регистра. Впрочем, при желании можно обойтись и штатным Доктором Ватсоном. Устанавливаем OllyDbg и назначаем его Just-in-Time Debugger'ом, так же называемым Post-Morten отладчиком, то есть отладчиком, вызываемым после краха приложения («Options -> Just-In-Time Debugging, Make Olly Just-In-Time Debugger, Confirm before attaching»). После этого повторяем открытие файла nezumi-3.pmd вновь, нажимая «Отмену» для вызова отладчика. В окне CPU пусто, и это нормально, поскольку памяти, на которую указывает регистр EIP (равный 363636363h), как уже говорилось, нет и показывать здесь нечего. Смотрим на стек. Регистр ESP (равный 0012DF8Ch) указывает на строку «6666», которой забит верх стека. Регистр ESI также указывает на «6666», но, судя по его значению (04DDC2B4h), эта копия строки расположена не в стеке, а в куче (выяснить это нам поможет карта памяти, вызываемая по <Alt-M>) - это очень важное обстоятельство, которое выручит нас в дальнейшем. Регистр EDI также смотрит в кучу (04DDC270h), но указывает непосредственно на само имя шрифта Courier66666, тогда как ESI – куда-то на его середину. Перейдем к следующей фазе атаки - попробуем выяснить, какой именно по счету байт перекрывает адрес возврата. Один из способов сделать это - воспользоваться «бегущей строкой», изменяющейся на всем своем протяжении. Для приблизительного определения дислокации адреса возврата поверх шестерок запишем «AAA...BBB...CCC». Загружаем обновленный файл в PageMaker, и крэш мистическим образом исчезает. Как же это так? Очень просто - по-видимому, буквенная комбинация, перекрывшая адрес возврата, совершенно случайно указала на вменяемую область памяти! Рехнуться можно! Но такова наша хакерская жизнь. Сплошные сюрпризы. Ладно, меняем «AAABBBCCC» на «111222333», надеясь, что на этот раз нам повезет. И точно! Теперь исключение выпрыгивает по адресу 32323232h, что соответствует последовательности «222». Очень хорошо! Самое время для сужения сектора поиска. Меняем «222» на «FF FE FF FD FF F8 FF F7». Естественно, эта последовательность может быть и другой. Никакого принуждения тут нет. Главное, чтобы мы точно смогли определить локацию двойного слова, попадающего в адрес возврата. На этот раз исключение выпрыгивает по адресу F7FFF8FFh, из чего можно заключить, что в адрес возврата попадают последние четыре байта. Нажимаем «Отмену» для вызова отладчика и смотрим на содержимое регистров и стека, а в стеке у нас содержится «444555». Приехали! В стек попадает буферная память, находящаяся за подменяемым адресом возврата, и если в адресе возврата окажется хотя бы один нулевой символ, он будет воспринят как завершитель строки и остаток переполняемого буфера в стек просто не попадет! Не попадет - и черт с ним! В конце концов, можно выбрать такой адрес возврата, чтобы без нулей. Например, передать управление на API-функцию TerminateProcess, чтобы аккуратно захлопнуть PageMaker при открытии файла без сохранения данных. Невелика подлость, но для начала сгодится и это. Находясь в отладчике, давим <Alt-E> (Executable Modules), находим там KERNEL32.DLL, которая и экспортирует TerminateProcess (смотри Platform SDK или кури Рихтера), и пишем «TerminateProcess» для быстрого поиска обозначенной функции, в W2K расположенной по адресу 77E8225Ch. Открываем наш многострадальный файл в hiew'е и меняем «FFh F8h FFh F7h» на «5Ch 22h E8h 77h» (адрес 77E8225Ch, записанный задом наперед с учетом порядка следования байт в двойном слове). Сохраняем изменения по <F9>, выходим из hiew'а, грузим файл в PageMaker и получаем неожиданный крэш по адресу 57E8225Ch. Что это за ботва такая и откуда она вообще приплыла?! Смотрим - ага, совпадают все байты, только 77h магическим образом превратилось в 57h. Убеждаемся, что hex-код 77h соответствует символу «w», а 57h – «W», то есть наш подопытный PageMaker перед копированием шрифтов переводит их имя в верхний регистр - ну чтобы искать легче было (как утверждает Platform SDK от MS, шрифты нечувствительны к регистру, и потому, чтобы исключить неоднозначность, регистр должен быть один). Таким образом, наша задача очень сильно осложняется - необходимо выбрать такой адрес возврата, чтобы в нем не было символов нижнего регистра. Но это ерунда. Самый главный вопрос - где располагать shell-код. Смотрим на значение остальных регистров. Так-так-так… Регистр ESI указывает на подстроку «444555», расположенную в куче. Отсюда возникает идея поместить shell-код, начиная со строки «444», а в качестве адреса возврата подсунуть адрес инструкции JMP ESI с опкодом FF E6, который легко отыскать в памяти процесса. Какая по счету четверка попадает в ESI? На этот вопрос можно ответить сразу, просто подсчитав количество четверок, расположенных до первой пятерки. Их будет ровно 12. А мы вбивали 16. Следовательно, ESI указывает на третью четверку, считая от нуля. Между прочим, именно по этому адресу располагалась та загадочная структура «1 :) :) :) :) :)», назначение которой мы не выяснили до сих пор, но которая нас очень здорово выручает, поскольку копируется в кучу независимо от наличия нулевых символов в имени шрифта. Короче, кончаем болтать и приступаем к поиску JMP ESI. Для этого в списке исполняемых модулей выбираем PM70.EXE, нажимаем на <ENTER> для перехода в его начало и давим <Ctrl-B> для форсирования двоичного поиска последовательности «FFh F6h». Клавиши <Ctrl-L> продолжают поиск. В общем, нам подойдет любой адрес. Главное, чтобы он: а) не содержал символов нижней строки; б) находился в пределах модуля PM70.EXE. Последнее обстоятельство обеспечивает переносимость эксплойта между системами, поскольку базовый адрес загрузки PM70.EXE всегда постоянный, где бы он ни был, а это значит, что постоянным будет и адрес команды JMP ESI, найденный внутри него. Вполне подходящий вариант расположен по адресу 005E0BE7h, который в символьном виде выглядит как «ч>^». И хотя «ч» находится в нижнем регистре, будем надеяться, что американский PageMaker с особенностями национального характера русского хакера не знаком и вообще не в теме. Ну, поехали! Заменяем «FFh F8h FFh F7h» на «E7h 0Bh 5Eh 00h», а в третий (считая от нуля) байт последовательности «444» внедряем наш shell-код, которым для простоты будет машинная инструкция INT 03h (опкод CCh). Последняя при выполнении должна вызывать исключение 80000003h, что послужит доказательством корректности работы эксплойта. В общем, финальный вариант должен выглядеть так, как показано на рисунке. Загружаем сформированный файл (его можно взять с http://nezumi.org.ru/souriz/hack/nezumi-pagemaker-MAIPM6-bug.7z) в PageMaker и ловим исключение 80000003h, как и предполагалось ранее. Естественно, INT 03h – очень простой shell-код и его можно заменить любым другим боевым зарядом, взятым с www.milw0rm.com или написанным самостоятельно. В Сети валяется куча shell-кодов, устанавливающих бэкдор или делающих разные прикольные дела, остающиеся на совести их разработчиков. Но меня это не интересует. Я подготовил публичный эксплойт, объяснив, с какой позиции туда внедрять shell-код, чем и доволен. |