본문 바로가기

My Study/Reversing

백신 Avast의 Anti-attach 우회하기

Avast 백신에서 실행파일을 검사할 때 어떠한 방식으로 알아보려고 리버싱을 시도하려는데 


이와 같은 창이 뜨게됩니다. 해당 프로세스를 어테치를 할 수가 없습니다.

그래서 시작한 아바스트 어테치하기... 얼른 끝나면 좋으려만;ㅋ


사실 해보면서 글 작성하고 있는 겁니다. 

왜냐하면.. 이렇게 글을 쓰기 시작해놔야 글 완성을 위해서라도 끝까지 하게되기 때문이죠.

저의 게으름성을 채찍질하기 위함?


Avast 는 아래와 같이 기본적으로 2개의 프로세스로 작동하고 있습니다.


두 프로세스다 어테치가 안되는 건 당연..


일단 ollydbg에서 attach를 실패하는 것으로보아 AvastUI.exe의 pid를 가지고 

OpenProcess 할 때 함수가 실패하고 있는 것으로 생각했습니다.

그리고 그렇게 생각했던 이유 중 가장 큰 원인이..


NtOpenProcess가 SSDT 후킹 되어 있다는 점이었습니다. 바로 아바스트 시스템 파일에 의해 말이죠.


하..지..만.. =_= 그건 저의 명백한 착각..


아무리 커널 디버깅을 해서 봐보아도 일반 계산기를 attach할 때와 avastui.exe를 attach 할 때와의 차이점이 없는 것입니다.

NtOpenProcess 성공적으로 호출되구요. 아무튼 아니라는 겁니다.


근데 당연한 거지만 저도 이 짓을 하면서 처음 알았는데 올리디버거에서 Attach를 눌렀을 때 뜨는 바로 이창..

이 창에서 나오는 프로세스들은 OpenProcess가 성공해야만 나오는 것이었습니다.


고로 AvastUI.exe가 저기 나온걸로 보아 OpenProcess는 무조건 성공 -0-;; 아.. 허무허무..


그러면 다른 함수로 눈을 돌려야겠죠. 어테치가 안된다고 에러메시지창이 떴을 때 루틴을 봐보니

DebugActiveProcess 함수가 실패하고 있었던 것입니다. AvastUI.exe를 attach하려고 했을 때 말이죠.


Ollydbg에서.. 보이는 루틴


IDA에서 보이는 루틴


똑같은 주소에 있는 루틴인데 왜 올디에선 저렇게 보이는지.. -_-;;;;

하지만 hex 값을 보아하니 올디가 기계어를 잘못읽고 변환한건 아닙니다.

push 하고 retn하는걸로 보아 0x10002321로 점프를 하고 있군요.



"antiattachkill" 문자열이 있고 막 뭐가 있네요. 그리고 아래 있는 JMP에서 다시 원래 루틴으로 돌아가게 됩니다.


음.. 올디가 런타임 시 내부적으로 .text영역에 있는 코드를 바꿔버리는 걸까요?

IDA에서는 바로 나오는걸로보아 그런듯 싶습니다. 귀찮으니 여긴 분석 X


아무튼 현미경에 DebugActiveProcess 함수를 대보고 봐봐야겠습니다.


DebugActiveProcess 함수 안...

DebugActiveProcess 는 타겟 프로세스의 PID를 가지고 호출을 하게 됩니다.

빨간색으로 네모친 부분이 타겟 PID를 가지고 ZwOpenProcess를 사용해 핸들을 구하는 부분입니다. 

핸들은 성공적으로 잘 얻습니다.


그리고 그 아래 DbgUiDebugActiveProcess 함수가 있네요. 해당 함수는 얻은 핸들을 인자로 호출을 하게 됩니다.


내부적으로 ZwDebugActiveProcess를 호출하네요.  해당 함수는 첫번째 인자 핸들 두번째인자 디버그오브젝트?

라는 값을 가지고 KiFastSystemCall을 호출합니다. 유저는 여기서 끝이군요.


ZwDebugActiveProcess 함수의 리턴 값이 일반적인 경우 0x00000000 인데 

AvastUI.exe를 어테치하면 리턴 값이 0xC0000022 입니다. 접근 거부...


그러면 역시 나 또 커널에서 무언가 조작이 되어 있다는건데...

ZwDebugActiveProcess 함수가 SSDT 후킹되어 있지도 않고 커널 수정된 부분을 봐도 inline훅이 되어 있지도 않습니다.


음.. .그러면 커널 디버깅을 통해 루틴을 따라 가보죠.


NtDebugActiveProcess 첫 부분입니다. 심오하게 들어가야 알 줄 알았지만 다행이 함수 초입부부터 뭔가 이상했습니다.

0x80664545 에서 ObReferenceObjectByHandle 이라는 함수를 사용하고 있습니다. 이는 OpenProcess로 부터 얻은 프로세스의 핸들을 가지고 해당 ThreadObject를 구해주는 함수입니다. 하지만 저 함수의 리턴 값이 0xC0000022 였습니다.

물론 AvastUI.exe를 어테치 했을 경우이고 그냥 계산기를 어테치 했을 경우엔 0x00000000이 리턴 됬습니다.


그러면 ObReferenceObjectByHandle 함수 내부를 봐봐야 뭘 알 것 같군요.

하던 도중 cpu가 쿼드라 일반적인 트레이싱이 힘들더군요. 자꾸 bp걸고 그냥 실행하면 context가 다른 걸로 넘어가 있어서..ㅠ

잡소리 그만하고 아무튼 gogo



내부를 보니.. 처음 부분에 ExMapHandleToPointerEx 함수가 호출되고 있습니다.

제가 알기론 HANDLE_TABLE 이라는 구조체를 리턴 값으로 넘겨주는 함수입니다.

일단 해당 함수를 호출한 이후 리턴 값을 봐보겠습니다. ( 현재 AvastUI.exe 를 어테치한 상황입니다. )



저 빨간색 네모친 부분이 중요합니다. 근데 자료를 찾아보니 QuotaProcess 의 자료형은 PEPROCESS로 프로세스 객체 포인터를 가지고 있어야하는데 저 값이 이상하군요. 아무튼 저 값이 사용되는 부분을 봐보겠습니다.



빨간색 네모친 부분위에서 해당 값을 가져다가 지지고 볶고 한 다음 test로 어떠한 값(이 모듈 인자) 과 test 연산을 하는데

QuotaProcess가 0x410이면 점프를 한다는 것입니다.



점프를 하고 나면 이 부분으로 오는데 저기서 익숙한 값이 0xC0000022 값을 ebx 레지스터에 넣고 있습니다. 저기가 실행되면 안되겠죠.


그러면 Avast 관련 프로세스가 아닌 일반 프로세스를 대상으로 위와 같은 짓을 다시 해보겠습니다. 어떠한 차이점이 있는지를 알면 우회하기가 더욱 편할 것 같군요.



이번엔 notepad.exe 프로세스를 어테치 했을 때의 상황입니다. 위와 다르게 0x410이 아닌 0xc3a가 저 부분에 존재하더군요.

실제로 notepad.exe 말고도 calc.exe 등등 Anti-attach가 적용되지 않은 여러 프로세스를 다 어테치 해봤을 때 저 부분이 0xc3a 였습니다. 이때 0xc3a를 0x410으로 바꿔서 실행하니 


반가운 창이 뜨네요.


그러면 메모리 패치를 시도해볼 수 있는 기회가 생겼군요.


AvastUI.exe를 어테치 한 상황에서 ExMapHandleToPointerEx 함수까지 호출 된 후! 리턴 값인 HANDLE_TABLE의  QuotaProcess 멤버변수를 0x410이라는 값에서 0xc3a로 바꿔서 실행을 해보겠습니다.


올레~~~~ Attach 성공입니다.


음.. 그러면 저 0x410이라는 값은 도데체 언제 셋팅이 되는 것일까요?


ExMapHandleToPointerEx 함수의 리턴 값은

"BaseHandleTableAddress + (Target Handle / 4 * 8)" 이라는 공식하에 나오는 건데...( 내부적으로 이렇게 얻어옴 )

NtDebugActiveProcess 함수를 들어오기 전부터 이미 핸들은 셋팅되어 있는 것이고..


고로 NtDebugActiveProcess 들어오기 전부터 핸들 테이블에는 0x410이라는 값이 셋팅되어 있는 것입니다.


그러면 핸들을 얻어오는 NtOpenProcess!!!  이놈을 다시 조저봐야하는 건가요?? 처음으로 다시 돌아가야하는 기분이네요.

근데 NtOpenProcess는 아바스트 시스템 파일에 의해 SSDT 후킹이 되어 있는 상황이라.. 말이 되는군요.


시험기간이고 시간이 없어서 여기까지만 하겠습니다. 분명 예상대로라면 핸들을 얻어와서 핸들 테이블에 처음엔 0xc3a를 넣겠지만 나중에 0x410을 또 어딘가에 넣겠지요.


nt!ExCreateHandle:

80571d96 8bff            mov     edi,edi

80571d98 55              push    ebp

80571d99 8bec            mov     ebp,esp

80571d9b 51              push    ecx

80571d9c 8365fc00        and     dword ptr [ebp-4],0

80571da0 53              push    ebx

80571da1 56              push    esi

80571da2 8b7508          mov     esi,dword ptr [ebp+8]

80571da5 8d45fc          lea     eax,[ebp-4]

80571da8 50              push    eax

80571da9 56              push    esi

80571daa e81cffffff      call    nt!ExpAllocateHandleTableEntry (80571ccb)

80571daf 8bd8            mov     ebx,eax

80571db1 85db            test    ebx,ebx

80571db3 7444            je      nt!ExCreateHandle+0xbd (80571df9)

80571db5 57              push    edi

80571db6 64a124010000    mov     eax,dword ptr fs:[00000124h]

80571dbc 8bf8            mov     edi,eax

80571dbe ff8fd4000000    dec     dword ptr [edi+0D4h]

80571dc4 8b450c          mov     eax,dword ptr [ebp+0Ch]

80571dc7 8b08            mov     ecx,dword ptr [eax]

80571dc9 890b            mov     dword ptr [ebx],ecx

80571dcb 8b4004          mov     eax,dword ptr [eax+4]

80571dce 894304          mov     dword ptr [ebx+4],eax    ; BaseHandleTableAddress + (Handle/4*8) + 4 위치에 0xc3a 넣음


알아낸건 일단 이 부분입니다. 저기서 0xc3a를 넣는건 확인했습니다. ExCreateHandle 함수!







'My Study > Reversing' 카테고리의 다른 글

WriteProcessMemory Anti Reversing  (0) 2012.06.27
Prefetch queue Anti Debugging  (4) 2012.05.25
NtSetInformationThread 를 이용한 Anti-Debugging  (0) 2012.04.17
Themida 2.1.2.0 Virtual Machine  (9) 2012.02.01
ARM CPU 공부시작.. ㅠ_ㅠ  (6) 2012.01.25