본문 바로가기
Programming/Security Programming

SetUnhandledExceptionFilter를 이용한 AntiDebugging

by Winduck 2018. 4. 10.
반응형

최근에 발견된 악성코드에서 SetUnhandledExceptionFilter를 이용한 Anti Debugging기법이 있어 끄적여본다.

우선 SetUnhandledExceptionFilter에 대해 알아보자.


SetUnhandledExceptionFilter란?


After calling this function, if an exception occurs in a process that is not being debugged, and the exception makes it to the unhandled exception filter, that filter will call the exception filter function specified by the lpTopLevelExceptionFilter parameter. by MSDN 

간략히 말하자면 예외발생시 디버깅중이지 않으면 SetUnhandledExceptionFilter lpTopLevelExceptionFilter를 통하여 전달된 filter function이 호출된다는 말이다. 다음은 구조를 알아보자.


SetUnhandledExceptionFilter구조?


LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(

  _In_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);

- lpTopLevelExceptionFilter : A pointer to a top-level exception filter function that will be called whenever the UnhandledExceptionFilter function gets control, and the process is not being debugged. A value of NULL for this parameter specifies default handling within UnhandledExceptionFilter

=>말인즉슨 프로세스가 디버깅중이 아니라면 UnHandledExceptionFilter가 호출될때마다 TopLevelExceptionFilter함수를 호출한다는 말이다. 여기서도 디버깅중이지 않으면!!!

그렇다면 간단히 해당 함수를 호출하는 UnHandledExceptionFilter함수 구조를 보고 AntiDebugging이 이루어지는 것을 보겠다.

UnHandledExceptionFilter란?

An application-defined function that passes unhandled exceptions to the debugger, if the process is being debugged. Otherwise, it optionally displays an Application Error message box and causes the exception handler to be executed. This function can be called only from within the filter expression of an exception handler. 

디버깅 중이라면 제어권을 디버거에게 넘기고 아니라면 메시지박스를 띄우거나 예외핸들러를 호출한다.


UnhandledExceptionFilter구조?

 
LONG WINAPI UnhandledExceptionFilter(
  _In_ 
struct _EXCEPTION_POINTERS *ExceptionInfo
);


-ExceptionInfo : 발생한 예외의 정보를 담고있는 구조체를 가리키는 포인터이다.

※악성코드속 Anti-Debugging

MSDN에서 친절히(?) 설명했듯 디버깅중일때와 디버깅중이지 않을 때의 행위가 나뉜다. 그렇다면 내부적으로 디버깅체크하는 루틴이 있다는 말????그래서 UnHandledExceptionFilter를 봤더니 다음과 같은 루틴이 보인다.

주목할부분은 ZwQueryInformationProcess의 두번째파라미터 0x7이것은 ProcessDebugPort으로 디버깅중일시 3번째 파라미터인 buffer로 0xFFFFFFFF를 리턴한다. 이것을 통해 디버깅중인지 아닌지를 확인한다. 따라서 악성코드는 예외를 일부러 발생시키고 디버깅중일경우 예외를 처리하지 못하도록하여 종료를 시킨다. 다음은 실제의 과정이다.


①정수를 0으로 나누어 예외발생


②예외를 처리하기위해 UnhandledExceptionFilter호출


디버깅 체크를 위해 UnhandledExceptionFilter내부에서 ZwQueryInformationProcess 호출한다.


④분기 실행

- 디버깅중일시, 디버거에게 제어를 넘기고 디버거는 해당 예외를 처리할수 없어 종료된다.

- 일반 실행중일 ,사용자의 0x40bd68 1 주고 예외를 처리한다.  0x40bd68 이상 0 아니므로 나눗샘이 가능해지고 그다음 실행이 가능하도록한다.


※구현

위 악성코드의 안티디버깅 루틴을 그대로 구현해보았다.


일반실행시, 결과창은 다음과 같다.



하지만 디버깅시에는 다음과같이 에러창이 뜨고 프로세스가 죽는것을 볼수있다.





오랜만에 포스팅을 했네요.... 

반응형

댓글