[Anti-Anti-Debug][Frida]bypassing IsDebuggerPresent() check

silver35·2022년 5월 22일
0

Reversing

목록 보기
2/2

IsDebuggerPresent()란?

BOOL WINAPI IsDebuggerPresent();

설명 : 호출된 프로세스가 디버깅툴에 의해 디버깅이 되는지 확인하는 윈도우 API
리턴 값 : 현재 프로세스가 디버거에서 작동하면 nonzero을 반환하며 현재 프로세스가 디버거에서 작동하지 않으면 zero를 반환

테스트 프로그램 준비

IsDebuggerPresent API를 호출해 디버거가 작동하지 않으면 [*] PASS를 출력하고 디버거가 작동중이면 [*] Debugger Detected!!!을 출력하는 C++ 프로그램을 작성하였다.

#include <Windows.h>
#include <iostream>

int main()
{
	bool check = IsDebuggerPresent();
	if (check == 0) {
		std::cout << "[*] PASS" << std::endl;
	}
	else 
	{
		std::cout << "[*] Debugger Detected!!!!" << std::endl;
	}
	return 0;
}

테스트 프로그램을 작성 후 exe파일로 빌드가 필요하다. x32로 빌드를 진행하였다.

방법은 간단하니 아래 참고 블로그를 참고하면 된다.
참고자료) [비주얼 스튜디오] 콘솔 실행파일(exe)만들기 / "빌드를 통해서" | 2017, 2019

hooking code

기존의 참고한 사이트에 나와있는 frida 코드는 아래와 같다. 이 코드로 후킹을 진행했을때 target.exe프로그램을 처음 실행시에만 IsDebuggerPresent( )함수를 찾기 때문에 우회가 불가능 하였다.

isDebuggerPresentAddr = DebugSymbol.getFunctionByName("IsDebuggerPresent")
console.log("function address : " + isDebuggerPresentAddr)

Interceptor.attach(isDebuggerPresentAddr, {
        onEnter: function (args) {
			console.log("IsDebuggerPresent() get called ...");
        },
        onLeave: function (retval) {
			retval.replace(0);
        },
});

// frida .\target.exe .\poc.js

따라서, Module.findExportByName 함수를 활용해 IsDebuggerPresent() 함수를 찾으면 리턴값을 0으로 변조하는 코드를 작성해 진행하였다. Module.findExportByName(exportName)은 export Name의 절대 주소를 반환하며, exportName을 찾을 수 없는 경우에는 null을 반환한다.

function antidebugbypass(){
Interceptor.attach(Module.findExportByName(null, 'IsDebuggerPresent'), {
	
    onEnter: function(args) {
       	console.log("IsDebuggerPresent() is called");
    },
    onLeave: function(ret) {
       ret.replace(0);
	   console.log("bypass antidebug!");
   	},
});
}

console.log("[*]going silver!!!!")
antidebugbypass()
// frida .\target.exe .\poc1.js

참고자료) JavaScript API

FIRDA을 사용해 hooking후 안티 디버깅 우회

먼저 hooking code 없이 frida로 target.exe를 spawn하고나면 frida는 entrypoint 지점에 멈춘다. 그러면 프로그램을 실행하기 위해 %resume 명령을 주면 디버깅을 부착하지 않았으므로 [*]PASS를 출력하고 끝낸다.

(1) IsDebuggerPresent()을 후킹하기 위해 작성한 poc1.js 스크립트를 로드해 target.exe를 실행한다.

(2) target.exe를 x32bdg에 부착한다.

(3) %resume 명령어를 통해 프로그램을 실행하면 hooking 코드에 의해 디버거가 탐지 우회를 성공했다.

우회를 마치며

frida는 모바일 취약점 분석시 사용해본적은 있었지만 윈도우에서 후킹하는 건 처음이였다. 사용해보니 모바일에서 사용하는 코드랑 별반 다른게 없었다고 느꼈고, frida는 생각보다 엄격한 도구라는걸 깨달았다. 프로그램 코드를 짜보고 우회까지 해보니 디버깅 탐지 방식에 대해 더 잘 이해할 수 있었다.

참고자료) Frida by example: bypassing IsDebuggerPresent() check

0개의 댓글