본문 바로가기

My Study/Reversing

NtSetDebugFilterState 안티 디버깅 기법

발표 준비때문에 안티디버깅 기법에 대해서 이것저것 조사도 하고 찾아보고.. 하지만!
직접 만들어 보려고 문서화 안된 함수들 위주로 찾아보다가 필 꽂힌 함수가 있길래 찾아봤더니..
이미 고수분들이 안티디버깅 기법으로 소개가 되어있더군요. ^^; 언제쯤 안티디버깅 기법을 만들어볼지..;;
간략하게 설명하도록 하겠습니다.
========================================================
NtSetDebugFilterState함수는 당연히 문서화 되지 않은 함수입니다.
함수의 형태를 봐보도록 하겠습니다.
NTSTATUS WINAPI NtSetDebugFilterState(ULONG ComponentId, unsigned int Level, char State)
함수명 그대로 디버그 필터 상태를 변경하는 함수 입니다.
하지만 디버깅 중에는 필터 상태를 변경하는 것이 불가능 하다는 것입니다.
그래서 리턴 값이 0이아닌 값이 리턴되게 됩니다. ( 0xC0000022 )

이것을 이용한 안티디버깅 기법이었습니다. 간단하게 코드만 구현해서 해봐야지 하고 해보았는데
이상한 점을 발견했습니다. 일단 보시겠습니다.

코드는 너무 간단합니다. 해당 API함수의 주소를 얻어와서 호출하는게 끝입니다.
일단 올디에 붙여보겠습니다.

위 방법대로 올디를 먼저 킨 후 해당 파일을 드래그해서 올려서 실행시켜보겠습니다.


앵?? Debugging이 아닌 Normal state가 출력 되었습니다.
여기까지만 했다면 이거 디버깅 탐지 않되는 함수 아닌가..라는 여운만 남긴체 돌아섰을지 모르지만
다른 방법으로 올디에 붙혀본 결과 디버깅 중이라고 탐지가 되었습니다.

 
보통 리버싱 하시는 분들이라면 올디를 전부 위와 같이 셋팅을 해주겠죠.
저도 마찬가지로 등록을 해놨고 위 방법으로 올디에 붙혀서 실행시켜보았습니다.


이번엔 디버깅이라고 탐지가 되었습니다. 우연의 결과라고 처음엔 생각해서 여러번 해보았지만
결과 값은 항상 같았습니다.

리버싱을 지금까지 해오면서 두 실행 방법에 있어서 차이점이 있다는 것을 이번 문서를 작성하면서 알게되었습니다.
두번째 실행 방법은 실행중인 프로세스를 Attach해서 디버깅 되는 것과 같은 결과를 내줍니다.

프로그램이 실행되고 나서 올디로 Attach를 시켜봐도 같은 결과가 나옵니다.
WinDbg로도 같은 실험을 했었는데 Attach를 해서 디버깅 할때만 탐지가 되었습니다.

위 방법은 프로세스를 Attach할때 탐지할 수 있는 방법입니다.
어떠한 플러그인으로 우회가능할지 많은 플러그인의 옵션들을 써봤는데 우회가 안되더군요..

참고로 NtSetDebugFilterState함수 호출이 성공하면 0이 리턴되지만 실패될 경우 0xC0000022 예외가 발생하게 됩니다.
0xC0000022 예외는 윈도우 내부에서 발생하는 예외입니다. MS의 리소스를 일반 클라이언트가 열 수 없기 때문입니다.