본문 바로가기

*집필*/*집필* Reverse

안티 리버싱 우회 - ZwSetInformationThread


ZwSetInformationThread.png

리버서는 역시나 안티기법에 대한 기술에 목이 타는것은 당연한듯하다.

그래서 분석 중 안티 기법이 나오면 혼자서 별별 짓을 다 해보다가 나름 정리한다.

노련한 리버서라면 이미 알고 있는 내용이겠지만

안티 기법(ZwSetInformationThread)으로 골머리 썩힌 과거를 회상하며 정리한다.

ZwSetInformationThread는 무슨 동작을 하기에 안티 기법에 사용된다 하는가?

근본적인 부분부터 알아봤다.

프로세스 내의 스레드가 가지는 속성을 변경하는 기특?한 녀석이란다.

안티 리버싱이라는 거창한 네임으로 소개되곤한다. 리버서로선 귀찮은

그럼. 어떻게 안티로 사용될까?

이 문제를 알아보기전 ZwSetInformationThread의 함수 기본 형식부터 알아봐야한다.

NTSTATUS ZwSetInformationThread(
__in  HANDLE ThreadHandle,
__in  THREADINFOCLASS ThreadInformationClass,
__in  PVOID ThreadInformation,
__in  ULONG ThreadInformationLength
);

MSDN에서 소개하는 ZwSetInformationThread의 함수 원형이다.

핸들, 스레드 클래스, 스레드 정보, 스레드 정보 길이

음? 다른 인수는 알겠다만 스레드 클래스(ThreadInformationClass)라니?

MSDN에서 또 뒤져봤다.

"안나온다. 못찾은건가?"

하는 수 없이 google에서 찾아봤다.

[ Windows NT/2000 native API reference ] 여기에선 아주 친절하게

THREADINFOCLASS의 정의에 대하여 정리되어 있다.

THREADINFORCLASS의 값 0x00에서 0x11까지

각 데이터 값에 따른 의미와

ZwSetInformationThread, ZwQueryInformationThread 에서의

사용 유무에 대한 정보를 표기해 두었으니 이 정보만으로 충분히 이해할만하다.

( Link : http://books.google.co.kr/books?id=Fp1ct-bKYdcC&pg=PA119&hl=ko&source=gbs_toc_r&cad=3#v=onepage&q&f=false )

안티기법으로 사용한다는 의미는 역시나 디버거에 있었다.

0x11 값이 의미하는것은 다름 아니라

ThreadHideFromDebugger

언젠가 분석하는 중에 어셈블리어가 전부 사라지고 휑한 디버거 화면을 만났던 기억이 지금 이해되기 시작하는것이다.

스레드 정보를 숨겼는데 디버거에 보일리가 있을까.

역시 문제는 ZwSetInformationThread의 인수 THREADINFOCLASS ThreadInformationClass 였다.

만일 휑한 디버거 화면을 만났다면 ZwSetInformatinThread에 BP를 걸고 두 번째 인수를 유심히 보길 바란다.

"0x11" 이렇게 찍혀있을 가능성이 높다.

우회는 생각보다 간단하다.

ZwSetInformationThread의 첫 번째 인자 즉, 스레드 핸들 값을 변경한다.

스레드 자신의 핸들 값으로 "0xFFFFFFFE"로 설정해 두었을 것이다.

직접 확인해본 값이기 때문에 다른 값에 대해서는 확인하지 못하였다.

하지만 이 값만 아니라면 현재 보고있는 핸들 값이 아니기만 하면되지 않은가?

OllyDbg를 사용한다면 상단의 "H"(Handler) 버튼을 클릭하고 나타나는 핸들 윈도우에서

사용하지 않는 핸들 값으로 수정해 준다.

물론 다른 방법도 있다.

적절한 THREADINFOCLASS의 인수 값으로 변경하면 되는것.

상황에 따라 변경한다면 충분히 우회가 가능하다.