ETC

Proxy DLL Hijacking for kernel32.dll 삽질

wsoh9812 2021. 8. 1. 01:36

 

서론

특정 바이너리에서 무조건 kernel32.dll을 로드할 것이고, kernel32.dll에 있는 함수들 중 createfile을 후킹한 후 

나머지 함수들은 래핑하는 라이브러리를 만들고자 했다.

 

Windows Dll Search Order에 따라 가능한 얘기인 줄 알았는데,

kerenel32 하이재킹은 Dll search order이랑 거리가 먼 얘기였다.

 

암튼

이러한 삽질을 하면서 배운 내용들을 써본다.

 


 

[*]  Proxy Hijacking이란?

우리는 사용자가 원하는 특정 함수를 후킹해준다.

예를들어 사용자가 Kernel32.dll에 있는 'GetStringScripts'함수를 후킹하고싶다고 가정하자.

그러면 우리는 GetStringSciprt함수를 제외한 나머지 함수들을 랩핑만하면 된다. 이렇게 특정함수를 제외한 나머지를 랩핑한 kernel32.dll을 만든다. ← 이것을 Proxy Dll 이라고 부른다.

 

그림으로 보면 아래와 같다.

(자세한 내용은 여기를 참조하길 바란다.)

Proxy DLL 출처 : https://itm4n.github.io/dll-proxying/

 

 

먼저, 나머지 함수들을 어떻게 래핑하냐??? 즉, Proxy Dll을 어떻게 만드냐?

이렇게 프로그램 하기 위해서는 pragma 라는 컴파일 옵션을 사용하여 구연할 수 있다. 예를 들어 gid32.dll 에 BitBlt 함수를 내가 만든 DLL 에서 그대로 사용하고 싶을 때는 다음과 같이 기술하면 된다.

#pragma comment(linker, "/export:BitBlt=gdi32.BitBlt")

 

그럼 우리는 KERENL32.dll의 export 되는 함수들을 뽑아낼 필요가 있다. ( 여기 )

 

 

[*] Known DLLs의 개념 

Windows DLL Search Order

(먼저, 나는 위 사진을 보지않고 다른 자료를 먼저 보았고, 그 결과  "knowsdll과, dll already loaded in..."을 배제하고, Aplication directory가 1순위 인줄 알았다.ㅜㅜㅜ 이걸 미리 캐치했었더라면,,,, ) <----- 꼭! 

 


( dll 탐색 우순순위 1위가 Application's Directory였다는 가정 하에)

근데!!!! 여기서 의문이 드는게 과연?! 바이너리와 같은 위치에 있다고 kernel32.dll이 먼저호출 될까???

 

그래서 테스트를 해보았다.

 

 

사진1.
사진 2.

그 결과 같은 위치에 있다고, kernel32.dll이 호출 되지 않았다.!

이후 그 이유를 찾기 시작하였고, Known Dlls를 알게 되었다.!,

Known Dlls에 등록되어있는 dll들은 먼저 'system32/'경로에가서 dll들을 searching한다!!!!

 

레지스트리 경로 : HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs

 

 

 

[*] TrustedInstaller 권한

Known Dlls의 value 중 kerenel32.dll을 지우면 그 다음 우선순위인 Application's directory에서 dll을 찾겠지?!라는 생각을 해서, 레지스트리 value를 지우려고했다. 

 

Denied Access

어라?? 그냥 지울 수가 없다. 그리고 ntsytem권한으로도 지울 수 없다.

이유윈도우의 특정 폴더 파일은 "TrustedInstaller" 권한을 가진 친구만이 지울 수 있다고 한다.!!!!

 

 

Known Dlls key 권한

 

이 코드를 이용해서 regedit을 TrustedInstaller권한으로 실행 시킬수 있고 삭제와 수정이 가능하다.

 

 

[*] 메모리에 있는 DLL 로드인 경우

 

그래서 Known Dlls에서 kernel32를 삭제하고, 실행을 해보았는데도 똑같이 사진2와 같은 결과가 나온다..................

 

 

msdn

나느 위의 개념을 까맣게 있고 있었다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

이미 메모리에 로딩되어있는 dll들은 서로 공유한다는 것을 말이다 !!!!!!!!!

 

 


내가 공부한 것은 여기까지고,  다음과 같은 결론을 내렸다.

 

'''

 dll을 로딩할때는 같은이름의 dll이 메모리에 로드되어 있으면 dll searching을 안하고, 그냥 메모리에 올라와있는 dll 그대로 가져다 쓴다고 합니다.
 이전에 조사했던 dll search order는 loadlibrary()를 사용할때 유효한 이야기이고,

기존에 kernel32.dll을 하이재킹 하려면 이게 search order가 의미없이 메모리에 로드되어있는거 그대로 가져다 쓰기때문에 kernel32.dll을 하이재킹 하려면
 사실상 윈도우에서 가장 먼저 실행되는 프로세스가 우리의 custom_kernel32.dll을 로드하도록 해야 이후에 실행되는 프로세스들도 전부 하이재킹이 가능한 상황입니다.
'''

 

https://www.codeproject.com/Articles/325603/Injection-into-a-Process-Using-KnownDlls 

 

Injection into a Process Using KnownDlls

In his article, we will consider an interesting, universal and rarely used method of code injection into a Windows process using KnownDlls sections. To demonstrate the method work we will develop a sample project to inject into all running processes and in

www.codeproject.com

 

위 링크 프로젝트 엄청 재미있어보인다.