Dynamic-Link 라이브러리 보안

애플리케이션이 정규화된 경로 이름을 지정하지 않고 동적 링크 라이브러리를 동적으로 로드하는 경우 Windows는 Dynamic-Link 라이브러리 검색 순서에 설명된 대로 잘 정의된 디렉터리 집합을 특정 순서로 검색하여 DLL을 찾으려고 시도합니다. 공격자가 DLL 검색 경로의 디렉터리 중 하나를 제어하는 경우 해당 디렉터리에 DLL의 악성 복사본을 배치할 수 있습니다. 이를 DLL 사전 로드 공격 또는 이진 심기 공격이라고도 합니다. 손상된 디렉터리를 검색하기 전에 시스템에서 DLL의 합법적인 복사본을 찾지 못하면 악의적인 DLL을 로드합니다. 애플리케이션이 관리자 권한으로 실행되는 경우 공격자는 로컬 권한 상승에 성공할 수 있습니다.

예를 들어 애플리케이션이 사용자의 현재 디렉터리에서 DLL을 로드하도록 설계되었으며 DLL을 찾을 수 없는 경우 정상적으로 실패한다고 가정합니다. 애플리케이션은 DLL 이름만 사용하여 LoadLibrary 를 호출하므로 시스템에서 DLL을 검색합니다. 안전한 DLL 검색 모드가 사용하도록 설정되어 있고 애플리케이션이 대체 검색 순서를 사용하지 않는 경우 시스템은 다음 순서로 디렉터리를 검색합니다.

  1. 애플리케이션이 로드된 디렉터리입니다.
  2. 시스템 디렉터리입니다.
  3. 16비트 시스템 디렉터리입니다.
  4. Windows 디렉터리입니다.
  5. 현재 디렉터리
  6. PATH 환경 변수에 나열된 디렉터리입니다.

이 예제를 계속하면 애플리케이션에 대한 지식이 있는 공격자가 현재 디렉터리를 제어하고 해당 디렉터리에 DLL의 악의적인 복사본을 배치합니다. 애플리케이션이 LoadLibrary 호출을 발급하면 시스템은 DLL을 검색하고 현재 디렉터리에서 DLL의 악성 복사본을 찾아 로드합니다. 그런 다음 DLL의 악의적인 복사본이 애플리케이션 내에서 실행되어 사용자의 권한을 얻습니다.

개발자는 다음 지침에 따라 DLL 사전 로드 공격으로부터 애플리케이션을 보호할 수 있습니다.

  • 가능한 경우 LoadLibrary, LoadLibraryEx, CreateProcess 또는 ShellExecute 함수를 사용할 때 정규화된 경로를 지정합니다.

  • LoadLibraryEx 함수와 함께 LOAD_LIBRARY_SEARCH 플래그를 사용하거나 SetDefaultDllDirectories 함수와 함께 이러한 플래그를 사용하여 프로세스에 대한 DLL 검색 순서를 설정한 다음 AddDllDirectory 또는 SetDllDirectory 함수를 사용하여 목록을 수정합니다. 자세한 내용은 Dynamic-Link 라이브러리 검색 순서를 참조하세요.

    Windows 7, Windows Server 2008 R2, Windows Vista 및 Windows Server 2008: 이러한 플래그 및 함수는 KB2533623 이 설치된 시스템에서 사용할 수 있습니다.

  • KB2533623이 설치된 시스템에서 LoadLibraryEx 함수와 함께 LOAD_LIBRARY_SEARCH 플래그를 사용하거나 SetDefaultDllDirectories 함수와 함께 이러한 플래그를 사용하여 프로세스에 대한 DLL 검색 순서를 설정한 다음 AddDllDirectory 또는 SetDllDirectory 함수를 사용하여 목록을 수정합니다. 자세한 내용은 Dynamic-Link 라이브러리 검색 순서를 참조하세요.

  • DLL 리디렉션 또는 매니페스트를 사용하여 애플리케이션이 올바른 DLL을 사용하는지 확인하는 것이 좋습니다.

  • 표준 검색 순서를 사용하는 경우 안전한 DLL 검색 모드가 사용하도록 설정되어 있는지 확인합니다. 이렇게 하면 사용자의 현재 디렉터리가 나중에 검색 순서에 배치되므로 Windows에서 악의적인 복사본 전에 합법적인 DLL 복사본을 찾을 가능성이 높아질 수 있습니다. 안전 DLL 검색 모드는 기본적으로 SP2(서비스 팩 2)가 있는 Windows XP부터 사용하도록 설정되며 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode 레지스트리 값으로 제어됩니다. 자세한 내용은 Dynamic-Link 라이브러리 검색 순서를 참조하세요.

  • 빈 문자열("")을 사용하여 SetDllDirectory 를 호출하여 표준 검색 경로에서 현재 디렉터리를 제거하는 것이 좋습니다. 이 작업은 LoadLibrary 호출 전후가 아니라 프로세스 초기화 초기에 한 번 수행해야 합니다. SetDllDirectory는 전체 프로세스에 영향을 줍니다. 여러 스레드가 서로 다른 값으로 SetDllDirectory를 호출하면 정의되지 않은 동작이 발생할 수 있습니다. 애플리케이션이 타사 DLL을 로드하는 경우 신중하게 테스트하여 비호환성을 식별합니다.

  • 안전한 프로세스 검색 모드를 사용하도록 설정하지 않는 한 SearchPath 함수를 사용하여 후속 LoadLibrary 호출에 대한 DLL 경로를 검색하지 마세요. 안전한 프로세스 검색 모드를 사용하도록 설정하지 않으면 SearchPath 함수는 LoadLibrary 와 다른 검색 순서를 사용하며 먼저 지정된 DLL에 대한 사용자의 현재 디렉터리를 검색할 가능성이 높습니다. SearchPath 함수에 대해 안전한 프로세스 검색 모드를 사용하도록 설정하려면 BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE SetSearchPathMode 함수를 사용합니다. 이렇게 하면 현재 디렉터리가 프로세스 수명에 대한 SearchPath 검색 목록의 끝으로 이동합니다. 현재 디렉터리가 검색 경로에서 제거되지 않으므로 시스템에서 현재 디렉터리에 도달하기 전에 DLL의 합법적인 복사본을 찾지 못하면 애플리케이션이 여전히 취약합니다. SetDllDirectory와 마찬가지로 SetSearchPathMode 호출은 프로세스 초기화 초기에 수행되어야 하며 전체 프로세스에 영향을 줍니다. 애플리케이션이 타사 DLL을 로드하는 경우 신중하게 테스트하여 비호환성을 식별합니다.

  • DLL을 검색하는 LoadLibrary 호출을 기반으로 운영 체제 버전에 대해 가정하지 마세요. 애플리케이션이 DLL이 합법적으로 존재하지 않지만 DLL의 악의적인 복사본이 검색 경로에 있는 환경에서 실행 중인 경우 DLL의 악의적인 복사본이 로드될 수 있습니다. 대신 시스템 버전 가져오기에 설명된 권장 기술을 사용합니다.

프로세스 모니터 도구를 사용하여 취약할 수 있는 DLL 로드 작업을 식별할 수 있습니다. 프로세스 모니터 도구는 에서 https://technet.microsoft.com/sysinternals/bb896645.aspx다운로드할 수 있습니다.

다음 절차에서는 프로세스 모니터를 사용하여 애플리케이션에서 DLL 로드 작업을 검사하는 방법을 설명합니다.

프로세스 모니터를 사용하여 애플리케이션에서 DLL 로드 작업을 검사하려면

  1. 프로세스 모니터를 시작합니다.
  2. 프로세스 모니터에 다음 필터를 포함합니다.
    • CreateFile 작업
    • LoadImage 작업
    • 경로에 .cpl 포함
    • 경로에 .dll 포함
    • 경로에 .drv가 포함되어 있습니다.
    • 경로에 .exe 포함
    • 경로에 .ocx가 포함되어 있습니다.
    • 경로에 .scr이 포함되어 있습니다.
    • 경로에 .sys 포함
  3. 다음 필터를 제외합니다.
    • 프로세스 이름이 procmon.exe
    • 프로세스 이름이 Procmon64.exe
    • 프로세스 이름은 시스템입니다.
    • 작업은 IRP_MJ_ 시작됩니다.
    • 작업은 FASTIO_ 시작됩니다.
    • 결과는 SUCCESS입니다.
    • 경로가 pagefile.sys 종료됩니다.
  4. 특정 디렉터리로 설정된 현재 디렉터리로 애플리케이션을 시작합니다. 예를 들어 애플리케이션에 파일 처리기가 할당된 확장명이 있는 파일을 두 번 클릭합니다.
  5. DLL을 로드하기 위해 현재 디렉터리에 대한 호출과 같이 의심스러운 경로가 있는지 프로세스 모니터 출력을 확인합니다. 이러한 종류의 호출은 애플리케이션의 취약성을 나타낼 수 있습니다.