컴퓨터 프로그래밍에서 DLL 인젝션(DLL injection)은 다른 프로세스의 주소 공간 내에서 DLL을 강제로 로드시킴으로써 코드를 실행시키는 기술이다.[1] DLL 인젝션은 외부 프로그램을 통해 다른 프로그램에 저작자가 의도하거나 예상하지 않은 영향을 미치기 위해 사용된다.[1][2][3] 예를 들면 삽입된 코드는 시스템 함수 호출을 후킹 하거나[4][5] 또는 보통 방식으로는 읽을 수 없는 패스워드 텍스트 박스의 내용을 읽을 수 있다.[6] 임의적인 코드를 삽입하는데 사용되는 프로그램을 DLL injector라고 부른다.

마이크로소프트 윈도우에서의 접근

편집

마이크로소프트 윈도우에는 프로세스에게 DLL의 코드를 로드하고 실행시키는 여러 방법이 있다.

  • 레지스트리 엔트리 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs 에 목록화 된 DLL들은 User32.dll(이것이 프로세스에 부착되는 순간)을 로드하는 모든 프로세스에서 로드된다.[5][7][8][9] 윈도우 비스타를 시작으로, AppInit_DLL들은 기본 설정으로 비활성화되어 있다.[10] Windows 7 이후로, AppInit_DLL 하부 구조는 code signing을 지원한다.
  • 레지스트리 키  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDLLs 아래 목록화 된 DLL들은 Win32 API 함수들인 CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW 그리고 WinExec를 호출할 때 로드된다.
  • CreateRemoteThread 같은 프로세스 조작 함수들은 실행 중인 프로그램에 DLL을 삽입하기 위해서 사용될 수 있다.[5][6][11][12][13][14]
    1. 타겟 프로세스의 handle을 오픈한다. 이것은 프로세스를 생겨나게 하거나[15][16] 프로세스에 의해 생겨났으며 존재한다고 알려진 것(예를 들면 예상 가능한 타이틀을 가진 윈도우[17])을 키 오프하거나, 실행중인 프로세스들[18]의 목록을 얻고 타겟 실행 파일의 이름을 조사함으로써 이루어된다.[19]
    2. 타겟 프로세스에서 메모리를 할당하고,[20] 할당받은 메모리에 인젝트될 DLL의 이름을 쓴다.[11][21]
      이 단계는 만약 적절한 DLL 이름이 이미 타겟 프로세스 안에서 사용 가능하다면 건너뛸 수 있다. 예를 들면, 프로세스가 ‘User32.dll’, ‘GDI32.dll’, ‘Kernel32.dll’ 또는 ‘32.dll’로 끝나는 다른 라이브러리와 링크되어 있다면, 로드하는 것이 가능하다. 이 기술은 과거에는 DLL 인젝션에서 프로세스들을 지키는 방식에 대해 효과적이라고 입증되었다.[22]
    3. 타겟 프로세스에 새로운 스레드[23] (스레드의 시작 주소는 LoadLibrary의 주소로, 인수는 타겟에 업로드되는 문자열의 주소로 해서) 생성한다.[11][24]
      로드될 DLL의 이름을 쓰고 LoadLibrary에서 새로운 스레드를 시작하는 것 대신, 실행 가능한 코드를 타겟에 넣고, 그 코드를 실행시키는 것도 가능하다.[6]
    4. 운영체제는 이제 삽입된 DLL에서 DllMain을 호출할 것이다.[11][25]
    경계 없이, 이 접근은 (스레드 시작 시 모든 로드된 모듈에 보내지는) DLL_THREAD_ATTACH 알림 때문에 타겟 프로세스에게 발견될 수 있다.[25]
  • SetWindowsHookEx 같은 윈도우 후킹 함수.[2][5][6][26][27][28]
  • 모든 스레드들을 중지시키기 위해 SuspendThread 또는 NtSuspendThread 함수를 사용하고 삽입된 코드를 실행할 목적으로, 존재하는 응용 프로그램 내의 스레드의 문맥을 수정하기 위해 SetThreadContext나 NtSetContextThread 함수를 사용하면 DLL이 로드된다.[29]
  • 익스플로잇은 윈도우에서 한계치들을 디자인하고 모든 검증된 DLL 경로 명시 없이 LoadLibrary() 함수를 호출하는 응용 프로그램들을 로드된다.[30]
  • 응용 프로그램에 명시된 DLL을 원본 같이 똑같은 함수 호출을 내보내게 구현된 로그 교체로 대체하는 것.[31]

유닉스 계열에서의 접근

편집

유닉스 계열 운영체제에서 (ld.so (on BSD) 또는 ld-linux.so (on 리눅스)를 기반으로 한 동적 링커와 함께) 임의적인 라이브러리들은 LD_PRELOAD 환경 변수 내에 있는라이브러리의 경로 이름을 줌으로써 새로운 프로세스에 링크될 수 있다. 이것은 한 프로세스 안에서 전역적으로 또는 개별적으로 세팅될 수 있다.[32]

예를 들면, 배시 셸에서, 이 명령어는 실행 시 링크되는 "test.so" 파일에서 공유 라이브러리와 함께 "prog" 명령어를 실행한다.

LD_PRELOAD="./test.so" prog

이러한 라이브러리는 GCC에 의해서 -fpic or -fPIC 옵션을 통해 링크될 새로운 전역변수를 포함하는 소스 파일을 컴파일하고,[33] -shared 옵션으로 링크함으로써 생성될 수 있다.[34] 이 라이브러리는 프로그램에서 선언된 외부 심볼들에 대한 접근을 갖는다.

또한 디버거 기반 기술도 사용 가능하다.[35]

각주

편집
  1. James Shewmaker (2006). “Analyzing DLL Injection” (PDF). 《GSM Presentation》. Bluenotch. 2008년 12월 3일에 원본 문서 (PDF)에서 보존된 문서. 2016년 2월 11일에 확인함. 
  2. Iczelion (August 2002). “Tutorial 24: Windows Hooks”. 《Iczelion's Win32 Assembly Homepage》. 2008년 8월 1일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  3. Rocky Pulley (2005년 5월 19일). “Extending Task Manager with DLL Injection”. 《CodeProject》. CodeProject. 2009년 2월 6일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  4. Nasser R. Rowhani (2003년 10월 23일). “DLL Injection and function interception tutorial”. 《CodeProject》. CodeProject. 2008년 6월 15일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  5. Ivo Ivanov (2002년 12월 2일). “API hooking revealed”. 《CodeProject》. CodeProject. 2008년 10월 14일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  6. Robert Kuster (2003년 8월 20일). “Three Ways to Inject Your Code into Another Process”. 《CodeProject》. CodeProject. 2008년 7월 20일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  7. “Working with the AppInit_DLLs registry value”. 《Microsoft Help and Support》. 마이크로소프트. 2006년 11월 21일. 2016년 2월 11일에 확인함. 
  8. Raymond Chen (2007년 12월 13일). “AppInit_DLLs should be renamed Deadlock_Or_Crash_Randomly_DLLs”. 《The Old New Thing》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  9. “dllmain.c”. 《ReactOS》. ReactOS Foundation. 2008년 7월 8일. 2016년 2월 11일에 확인함. [깨진 링크(과거 내용 찾기)]
  10. AppInit_DLLs in Windows 7 and Windows Server 2008 R2
  11. Trent Waddington. “InjectDLL”. 2019년 12월 30일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  12. “Dll Injection”. 《DreamInCode.net》. MediaGroup1. 2006년 5월 4일. 2008년 9월 2일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  13. Greg Jenkins (November 2007). “DLL Injection Framework”. 《Ring3 Circus》. WordPress. 2020년 6월 28일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  14. Drew Benton (2007년 8월 17일). “A More Complete DLL Injection Solution Using CreateRemoteThread”. 《CodeProject》. CodeProject. 2016년 2월 11일에 확인함. 
  15. “CreateProcess”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  16. “PROCESS_INFORMATION”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 20일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  17. “GetWindowThreadProcessId Function”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  18. “EnumProcesses”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  19. “GetModuleBaseName”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  20. “VirtualAllocEx”. 《Platform SDK for Windows XP SP2》. Microsoft. 2016년 2월 11일에 확인함. 
  21. “WriteProcessMemory”. 《Platform SDK for Windows XP SP2》. Microsoft. 2016년 2월 11일에 확인함. 
  22. “Outpost Bypassing Self-Protection via Advanced DLL injection with handle stealing Vulnerability”. 《Matousec》. 2006년 12월 1일. 2016년 2월 11일에 확인함. 
  23. “CreateRemoteThread”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  24. “LoadLibrary”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  25. “DllMain”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  26. “SetWindowsHookEx Function”. 《Platform SDK for Windows XP SP2》. 마이크로소프트. 2016년 2월 11일에 확인함. 
  27. “AppInit_DLLs Registry Value and Windows 95”. 《Microsoft Help and Support》. 마이크로소프트. 2005년 3월 1일. 2016년 2월 11일에 확인함. 
  28. “Dll Injection using SetWindowsHookEx() Method”. 《Game Reversal》. 2008년 4월 3일. 2016년 2월 11일에 확인함. 
  29. Ben Botto (2008년 9월 6일). “DLL Injector”. 2009년 2월 7일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  30. “Secure loading of libraries to prevent DLL preloading attacks”. 마이크로소프트. 2011년 6월 10일. 2016년 2월 11일에 확인함. 
  31. Nicolas Falliere (2010년 9월 26일). “Stuxnet Infection of Step 7 Projects”. Symantec. 
  32. Linus Torvalds; David Engel; Eric Youngdale; Peter MacDonald; Hongjiu Lu; Lars Wirzenius; Mitch D'Souza (1998년 3월 14일). “ld.so/ld-linux.so – dynamic linker/loader”. 《UNIX man pages》. 2009년 2월 6일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 
  33. “Code Gen Options”. 《Using the GNU Compiler Collection (GCC)》. Free Software Foundation. 2016년 2월 11일에 확인함. -fpic Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. sqq. 
  34. “Link Options”. 《Using the GNU Compiler Collection (GCC)》. Free Software Foundation. 2016년 2월 11일에 확인함. -shared Produce a shared object which can then be linked with other objects to form an executable. sqq. 
  35. Gregory Shpitalnik (2009년 2월 12일). “Code Injection into Running Linux Application”. 《Code Project》. 2010년 6월 12일에 원본 문서에서 보존된 문서. 2016년 2월 11일에 확인함. 

외부 링크

편집