Рейс кондишен.

Indy

RAM
Пользователь
Регистрация
14.07.2011
Сообщения
130
Реакции
21
Здрасти.
Хотел бы обсудить рк атаку на хэндлы. Суть в следующем. Nt-хэндлер выполняет некоторые дествия с обьектом, если они завершаются с ошибкой, то вызывается оригинальный сервис. В начале всегда ObReferenceObjectByHandle(), которая залочивает обьект и возвращает ссылку на него по описателю. Если передан инвалидный описатель, то вызывается оригинальный сервис с темже значением описателя. В это время другой тред может создать описатель и оригинальный сервис успешно отработает. Понятно что проблема в синхронизации - не вовремя созданный описатель приведёт к детекту. Чтобы это избежать необходимо каким то образом определить что поток покинул ObReferenceObjectByHandle(). Только тогда можно создать обьект. Возможный способ - использовать трассировку описателей. Но есть много подводных камней. Предлагайте ваше решение.
 
Вот что у меня получилось:
Код:
_imp__KiRaiseUserExceptionDispatcher proto

PROCESS_HANDLE_TRACING_ENABLE struct
Flags  ULONG ?
PROCESS_HANDLE_TRACING_ENABLE ends

PROCESS_HANDLE_TRACING_ENABLE_EX struct
Flags  ULONG ?
TotalSlots	ULONG ?
PROCESS_HANDLE_TRACING_ENABLE_EX ends

PROCESS_HANDLE_TRACING_MAX_STACKS	equ 16

HANDLE_TRACE_DB_OPEN	equ 1
HANDLE_TRACE_DB_CLOSE	equ 2
HANDLE_TRACE_DB_BADREF	equ 3

PROCESS_HANDLE_TRACING_ENTRY struct
Handle  HANDLE ?
ClientId  CLIENT_ID <>
_Type  ULONG ?; HANDLE_TRACE_DB_*
Stacks  PVOID PROCESS_HANDLE_TRACING_MAX_STACKS DUP (<>)
PROCESS_HANDLE_TRACING_ENTRY ends

PROCESS_HANDLE_TRACING_QUERY struct
Handle  HANDLE ?
TotalTraces	ULONG ?
HandleTrace	PROCESS_HANDLE_TRACING_ENTRY 1 DUP (<>)
PROCESS_HANDLE_TRACING_QUERY ends

ProcessHandleTracing	equ 32

%NTERR macro
	.if Eax
  Int 3
	.endif
endm

.data
SynchLock  BOOLEAN FALSE
RaiseLock  BOOLEAN TRUE

.code
STACK_FRAME struct
Next  PVOID ?
Ip  PVOID ?
STACK_FRAME ends
PSTACK_FRAME typedef ptr STACK_FRAME

; Откатывает фолт в KiRaiseUserExceptionDispatcher().
;
XcptDispatch proc uses ebx esi edi ExceptionPointers:PEXCEPTION_POINTERS
	mov ebx,ExceptionPointers
	mov esi,EXCEPTION_POINTERS.ExceptionRecord[ebx]
	assume esi:PEXCEPTION_RECORD
	mov edi,EXCEPTION_POINTERS.ContextRecord[ebx]
	assume edi:PCONTEXT
	cmp [esi].ExceptionFlags,NULL
	jne Chain
	cmp [esi].ExceptionCode,STATUS_INVALID_HANDLE
	jne Chain
; Ip ~ KiRaiseUserExceptionDispatcher().
; (leave/ret)
	mov eax,[edi].regEbp
	mov ecx,STACK_FRAME.Next[eax]
	mov edx,STACK_FRAME.Ip[eax]; ~KiFastSystemCallRet
	mov [edi].regEbp,ecx
	add eax,sizeof(STACK_FRAME)
	mov [edi].regEip,edx
	mov [edi].regEsp,eax
Load:
	mov eax,EXCEPTION_CONTINUE_EXECUTION
	jmp Exit
Chain:
	xor eax,eax
Exit:
	ret
XcptDispatch endp

SPINWAIT macro SpinLock
	.repeat
	.until SpinLock != FALSE
	mov SpinLock,FALSE
endm

APPLY_OBJECT struct
Handle  HANDLE ?
Callback  PVOID ?
Context  PVOID ?
APPLY_OBJECT ends
PAPPLY_OBJECT typedef ptr APPLY_OBJECT

ReferenceThreadRoutine proc RefObj:PAPPLY_OBJECT
Local ProcessInformation:PROCESS_BASIC_INFORMATION
	mov ebx,RefObj
	assume ebx:PAPPLY_OBJECT
@@:
	mov RaiseLock,TRUE
	SPINWAIT SynchLock
	push [ebx].Context
	push [ebx].Handle
	Call [ebx].Callback
	cmp eax,STATUS_INVALID_HANDLE
	je @b
	mov RaiseLock,TRUE
	Int 3
	invoke RtlExitUserThread, Eax
	Int 3
ReferenceThreadRoutine endp

ReferenceObject proc uses ebx esi edi OpObj:PAPPLY_OBJECT, RefObj:PAPPLY_OBJECT
Local ThreadHandle:HANDLE, ClientId:CLIENT_ID
Local Tracing:PROCESS_HANDLE_TRACING_ENABLE
Local TraceInformation:PROCESS_HANDLE_TRACING_QUERY
Local Context:CONTEXT, InformationLength:ULONG
Local TracingOn:PROCESS_HANDLE_TRACING_ENABLE
	invoke RtlAddVectoredExceptionHandler, 1, addr XcptDispatch
	.if !Eax
    Int 3
	.endif
	mov Tracing.Flags,NULL
	invoke ZwSetInformationProcess, NtCurrentProcess, ProcessHandleTracing, addr TracingOn, sizeof(PROCESS_HANDLE_TRACING_ENABLE)
	%NTERR
	mov ebx,OpObj
	assume ebx:PAPPLY_OBJECT
	mov edi,RefObj
	assume edi:PAPPLY_OBJECT
	invoke RtlCreateUserThread, NtCurrentProcess, NULL, FALSE, 0, 0, 0, addr ReferenceThreadRoutine, RefObj, addr ThreadHandle, addr ClientId
	%NTERR
	lea ecx,[ebx].Handle
	push [ebx].Context
	push ecx
	Call [ebx].Callback
	mov esi,[ebx].Handle
	%NTERR
	invoke ZwClose, Esi
	mov [edi].Handle,esi	
@@:
; Ожидаем захват спинлока.
	SPINWAIT RaiseLock
; Синхронно останавливаем тред.
	mov SynchLock,TRUE
	invoke ZwSuspendThread, ThreadHandle, NULL
	%NTERR
; Проверяем была ли выполнена KeRaiseUserException().
	mov Context.ContextFlags,CONTEXT_CONTROL
	invoke ZwGetContextThread, ThreadHandle, addr Context
	%NTERR
; Ip = @KiRaiseUserExceptionDispatcher().
	mov eax,dword ptr [_imp__KiRaiseUserExceptionDispatcher]
	mov ecx,Context.regEsp
	cmp Context.regEip,eax
	mov edx,dword ptr [ecx]
	jne Resume
; Восстанавливаем контекст для отката фолта.
	mov Context.regEip,edx
	add Context.regEsp,4
	mov Context.regEax,STATUS_SUCCESS
	invoke ZwSetContextThread, ThreadHandle, addr Context
	%NTERR
	lea ecx,[ebx].Handle
	push [ebx].Context
	push ecx
	Call [ebx].Callback
	%NTERR
	.if [ebx].Handle != Esi
    Int 3
	.endif
	SPINWAIT RaiseLock
;	invoke ZwClose,ObjHandle
	invoke ZwResumeThread, ThreadHandle, NULL
	%NTERR
	ret
Resume:
	invoke ZwResumeThread, ThreadHandle, NULL
	jmp @b
ReferenceObject endp
В теории для данного алго не возможен не удачный вызов(передача валидного описателя в аверский хэндлер).
 
RC.zip contents:
- NtGdiEnumFontChunk(Защита памяти от изменения).
- NtGdiGetSpoolMessage(Защита памяти от изменения).
- NtGdiSetBitmapBits(Защита памяти от удаления).
- ObReferenceObjectByHandle
Если не rc, то что тогда ?))

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


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