11월, 2018의 게시물 표시

NTLL!KiUserExceptionDispatcher(두번째 파라미터)

두번째 파라미터값에 대해서 조사를 해봐서 ContextFlags(1003f)이면 .cxr로 해당 컨텍스트로 이동해 볼수 있다 typedef struct _EXCEPTION_POINTERS {    PEXCEPTION_RECORD ExceptionRecord; // CPU 독립적인 정보    PCONTEXT ContextRecord; // CPU 의존적인 정보 } EXCEPTION_POINTERS , * PEXCEPTION_POINTERS ; 해당 정보는 다음의 2가지 경우에 저장이 될 수 있다. 1) exception filter 수행중 덤프 수집된 경우 2) exception filter 수행중 얻은 exception 정보를 저장한 경우(크래쉬 덤프) A) NTDLL!KiUserExceptionDispatcher ; 두번재 파라미터가 PCONTEXT B) kv 커맨드 ; CONTEXT @ 0f123456 C) msvcrt!__InternalCxxFrameHandler    - kpL 커맨드로 쉽게 볼 수 있다(첫번째 파라미터 Exception Record, 세번째 파라미터 Context Record) D) !dumpstack 또한 ContextRecord의 ContextFlags값은 i386 기준으로 1003f임 팁으로 s 커맨드로 범위내의 1003f 값을 갖는 경우를 찾기 위해서 다음과 같이도 할 수 있음 x86> s -d start_addr end_addr 1003f 약간 이상하기는 한데 ntdll!RtlDispatchException ntdll!KiUserExceptionDispatcher(2, 8, ...) 처럼 KiUser~() 두번째 파라미터가 CONTEXT를 가리키고 있지 않다면 위쪽에서(RtlDispatchException)을 검사해 봐라. 해당 위치에서는 i386인데도 1007f값을 가리킨다. 해당 위치로 CONTEXT를 위치시켜보면 정...

Kernel to User land(APC 인젝션)

커널모드에서 유저 프로세스로 코드를 인젝션시키는 두가지 방법이 존재 1) Queue user APC to alertable thread 타겟 프로세스의 어느 스레드가 alertable state인지를 알수 있는 코드가 필요하다. 각 스레드 ETHREAD 구조체를 검사해야 한다. thread가 alertable인지 설정되는 flag가 존재한다.  이 방법은 다소 신뢰할수 없고 MS가 해당 구조체를 무작위로 변경하기 쉽다는게 일반적 생각입니다. 2) Queue user APC to new thread 스레드가 시작하기 전에 스레드에 도달하는 방법이 필요합니다. 기본적으로 CreateThreadNotifyRoutine 등록함으로서 달성됩니다. 해당 콜백이 호출되면 두개의 시나리오중 하나가 발생될 수 있습니다. 2.1 스레드가 죽고 있음. 콜백이 죽는 스레드 컨텍스트에서 호출됨 2.2 스레드가 생성되고 있음. CNTR 콜백이 스레드 생성시 호출된것을 확인한 후에, 해당 스레드가 관심 프로세스에서 생성중인지를 알아보기 위해 몇가지 검사를 수행할 수 있다. CNTR에서 실행코드에서 기억할 중요한 사항으로는 각각의 CNTR이 끝나기전까지는 새로운 스레드가 만들어질 수 없다는 것이다. 만약 CNTR 코드가 실행하는데 1분이 걸린다면, 스레드 생성이 병목현상이 생긴다. 무엇을 하든지간에 그것이 빠르다는 것을 확인해라. 생성 스레드에 APC를 큐잉하기 위해, 커널코드가 신규 스레드에 ETHREAD 구조체를 갖을 필요가 있다. Win7에서 ETHREAD 구조체 핸들을 얻기 위해 PsLookupThreadByThreadId 호출할 수 있다. XP에서 코드검사가 실패해서 동작하지 않습니다. XP에서는 이 시점에 ETHREAD 구조체 얻기에 실패하는것으로 생각됩니다. 왜냐하면 오브젝트 리스트에 완전히 만들어지지 않기 때문에 다음으로, 2개의 파라미터를 갖는 KeStackAttachProcess 사용해 프로세스 컨텍스트에 붙일 필요가 있다....

SeDebugPrivilege 권한이 필요한 경우

High Integrity Level 프로세스에서 그보다 높은 Level 프로세스에 인젝션을 수행시도를 할때 SeDebugPrivilege 권한을 준다. 이 디버그 권한을 갖는다면 접근통제정책을 우회할 수 있다. 그러나 이 권한은 관리자 계정에만 주어진다. 즉 High Integrity Level인 경우에만 이 디버그 권한을 활성화시킬수 있다.

SetThreadContext Inject 테스트

void __declspec(naked) InjectFunction() {  __asm  {   PUSHAD    MOV EAX, 0xAAAAAAAA //eventually the address of LoadLibraryA    PUSH 0xBBBBBBBB //eventually the module name    call EAX    POPAD    //vc is pissy and requires us to emit the hardcoded jump    __emit 0xE9    __emit 0xCC    __emit 0xCC    __emit 0xCC    __emit 0xCC  } } void __declspec(naked) AfterFunction() { } void InjectDll( HANDLE hProc, HANDLE hThread, char *DllName ) {  //hold up  SuspendThread( hThread );  //get the thread context  CONTEXT ThreadContext;  ThreadContext.ContextFlags = CONTEXT_FULL;  GetThreadContext( hThread, &ThreadContext );  //copy the function to a tmp buffer  ULONG FunctionSize = (PBYTE)AfterFunction - (PBYTE)InjectFunction;  PBYTE LocalFunction = ...