본문 바로가기

My Study/Programming&Theory

Anti Dll Hijacking

저번에 아주 간단하게 Dll Hijacking에 대해 쓴적이 있습니다.
제가 사용 했던 방법에 대해서 간략히 그림으로 나타내보겠습니다.


이렇게 특정 어플리케이션에선 수 많은 dll들을 가져오게 됩니다. 
그 중에서 너무 가져오는 dll이 많다보니 어떤 dll은 찾을 수가 없어서 못가져오게되는 dll도 있습니다.

아마 제 생각인데 개발자들이 어플리케이션을 패치할 때 원래 필요했던 dll이지만 패치 시에 해당 dll이 필요 없어서 그냥 지워버릴 때가 있습니다. 그러면 그 dll을 Load하는 소스코드 또한 없애주어야 하는데 dll을 Load하는 코드는 그대로 남겨두어서 이런 현상이 발생하는 것 같습니다. 많은 이유가 있겠지만 제가 생각하는 이유입니다.

일단 저렇게 찾지 못하는 dll이 발견되면 해커는 그 찾지 못하는 dll경로로 자기가 만든 악성 dll파일을 거기에 똑같이 심는 것입니다. 그림으로 보시겠습니다.

악성 dll의 원래 이름은 Crackdll인데 그것을 Test2.dll로 변경한 후 dll Load에 실패했던 경로에 그대로 넣어주면 
어플리케이션을 실행 했을 때 악성 dll또한 시작되게 됩니다.

저번에 이 방법을 사용해서 간단하게 메시지박스를 띄우는 예제를 해보았습니다.

그러면 이번에는 저 방법처럼 했을 때 어떻게 막을 것인가.. 에 대해서 고민을 해보았습니다.
제가 생각하는 방법은 보통 dll을 찾을수 없다고 뜨는 dll들을 보면 거의 다 어플리케이션 개발자가 만든 dll입니다.
윈도우 환경에서 어플을 실행시키기 위해 중요한 dll인 kernel32.dll, ntdll.dll, user32.dll 등등 이런 dll들은 NOT FOUND가 뜨진 않기 때문이죠.

그렇기 때문에 개발자가 dll을 만들 때 그 안에 개발자만 알아볼수 있도록 특정 시그니처를 사용합니다.
그리고 dll을 Load시 그 시그니처 dll파일로부터 읽어온 다음, 그 시그니처가 원래 시그니처와 같은지 확인 후
다르면 dll Load를 하지 않는 것입니다.

한번 구현을 해 보았습니다.

일단 dll을 Load하는 LoadLibrary를 후킹했습니다.
제가 만든 LoadLibrary에서는 로드되는 해당 dll로부터 특정 offset위치에 있는 시그니처를 읽어옵니다.
그리고 어플리케이션에 하드코딩 되어있는 문자열과 비교를 하게 됩니다.

비교 후 다르면 LoadLibrary를 하지 않고 그냥 return해버리는 것이고 같으면 LoadLibrary를 해주는 것입니다.

간단하게 MyLoadLibrary소스코드만 보도록 하겠습니다.

아랫부분은 그냥 언훅해서 원래 함수 호출하고 다시 후킹하는 부분입니다.
중요부분은 if문으로 감싸여 있는 부분입니다.
중요하긴 하지만 코드구현은 길지 않습니다.
fopen을 통해서 파일을 열고
fseek로 파일포인터를 시그니처 있는 곳으로 옮겨준 후
fread로 시그니처를 읽어온것입니다.

그리고 strncmp를 사용해 두 시그니처를 비교를 하는 것이지요.

테스트 결과 이런식으로 Dll을 Load하니까 제가 사용했던 Dll Hijacking 기법이 안통했다는 것입니다.
비록 후킹을해서 몇가지 작업을 하므로 실행에 있어서 속도가 조금은 느려지겠지만 아마 사용자들은 느끼지 못하는 정도 일 것입니다. 지금까지 제가 생각해본 Dll Hijacking 대응 방안 중 하나 였습니다.

아마 이렇게 하면 또 이런 질문이 들어올수도 있겠군요.
" 그 시그니처를 그냥 리버싱으로 알아낸 다음 악성코드 개발자도 그 위치에 똑같은 시그니처를 사용해버리면 되지 않느냐..."
이 부분에 대해서는 Dll Hijacking의 범위가 아닌 리버싱 쪽이므로 여기선 언급하지 않겠습니다.

저렇게 말해버리면 안티리버싱 기법을 또한 사용해야겠지요.. :-)

그냥 단순히 제가 생각해본 대응방안으로서 틀린점이 있다면 지적부탁 드리겠습니다.

'My Study > Programming&Theory' 카테고리의 다른 글

Intel CPU의 영리함??  (5) 2010.10.09
Visual Studio 2010 ddk 연동 (Window7)  (9) 2010.10.05
Create BSOD in usermode  (4) 2010.09.22
둘 중 큰수 찾는 정의 된 메크로  (0) 2010.09.01
콘솔모드에서 메시지 처리  (0) 2010.09.01