
Windows 8.1 및 10에서 WinSxS의 "dccw.exe"를 악용하는 UAC 우회.
이 익스플로잇은 Leo Davidson의 "Bypass UAC" 방법을 변형한 기법을 통해 "dccw.exe"가 "WinSxS"를 관리하는 방식을 악용하여, 동의를 요구하지 않고 관리자 셸을 획득합니다. "x86" 및 "x64" 아키텍처를 지원합니다. 또한 Windows 8.1 9600, Windows 10 14393, Windows 10 15031 및 Windows 10 15062에서 성공적으로 테스트되었습니다.
스크립트를 실행하는 방법을 보려면 사용법 섹션을 참조하세요. 또한 Metasploit에서 실행하여 관리자 권한으로 Meterpreter 세션을 얻을 수도 있습니다.
새로운 Bypass UAC를 개발하려면 먼저 시스템에서 취약점을 찾아야 하며, 더 정확히는 auto-elevate 프로세스의 취약점을 찾아야 합니다. 이러한 프로세스 목록을 얻기 위해 Sysinternals의 Strings라는 도구를 사용했습니다. 그 결과 "sysprep.exe", "cliconfig.exe", "inetmgr.exe", "consent.exe" 또는 "CompMgmtLauncher.exe"와 같은 일부 auto-elevate 프로세스에서 "bypass UAC" 실행을 허용하는 취약점이 있음을(일부는 여전히 존재) 확인할 수 있었습니다. 그래서 우리는 Sysinternals의 Process Monitor(ProcMon)라는 애플리케이션으로 다른 auto-elevate 프로세스가 어떻게 작동하는지 연구하기 시작했지만, "dccw.exe" 프로세스에 초점을 맞췄습니다.
하지만 ProcMon을 시작하기 전에 먼저 Sigcheck라는 또 다른 Sysinternals 애플리케이션으로 해당 애플리케이션의 매니페스트를 확인했습니다. 물론 우리의 경우 "dccw.exe"는 auto-elevate 프로세스입니다.
그런 다음 ProcMon으로 "dccw.exe"의 실행 흐름을 추적하여 이상한 점이 발생하는지 확인할 수 있었고, 우리는 즉시 확인했습니다. 어떤 시점에서 64비트 Windows 머신에서 "dccw.exe"를 64비트 프로세스로 실행하면 "GdiPlus.dll"이라는 특정 DLL을 로드하기 위해 "C:\Windows\System32\dccw.exe.Local\" 디렉터리를 찾습니다. 32비트 Windows 머신에서 실행된 것과 동일하게 말이죠. 반면 동일한 머신에서 32비트로 실행하면 프로세스는 "C:\Windows\SysWOW64\dccw.exe.Local\" 디렉터리를 찾습니다. 그런 다음 해당 디렉터리가 존재하지 않기 때문에 프로세스는 항상 "C:\Windows\WinSxS\" 경로에서 원하는 DLL을 얻기 위한 폴더를 찾으며, 이 폴더의 이름은 다음 구조를 가집니다:
[architecture]_microsoft.windows.gdiplus_[sequencial_code]_[Windows_version]_none_[sequencial_number]
"WinSxS" 디렉터리를 살펴보면 이 구조와 일치하는 폴더가 여러 개 있음을 확인할 수 있습니다. 즉, "dccw.exe"는 이 폴더 중 어느 곳에서든 원하는 DLL을 로드할 수 있습니다. 확실한 것은 애플리케이션이 x86 프로세스로 호출되면 폴더 이름이 "x86" 문자열로 시작하고, x64 프로세스로 실행하면 이름이 "amd64" 문자열로 시작한다는 점입니다.
이러한 상황은 DLL 하이재킹을 수행하고 동의를 요구하지 않고 높은 무결성으로 코드를 실행하는 데 악용될 수 있습니다.
auto-elevate 프로세스 실행 중 오류를 하나 발견하면 그것이 악용될 수 있는지 검증해야 합니다. 이를 위해 원하는 경로에 "dccw.exe.Local" 폴더를 만들고, 그 폴더 안에 "WinSxS"에 있는, 프로세스가 "GdiPlus.dll"을 로드하기 위해 호출할 수 있는 폴더들을 만들었지만 해당 DLL은 넣지 않았습니다.
이제 "dccw.exe"를 실행하면 프로세스가 "dccw.exe.Local" 폴더와 "WinSxS" 폴더 중 하나를 찾았지만 원하는 DLL은 찾지 못해 오류가 발생하는 것을 볼 수 있습니다. 앞서 언급했듯이 이는 공격자가 악용할 수 있는 상황이므로 우리가 기대한 결과입니다.
이 시점에서 우리는 "dccw.exe"를 악용하여 Windows 10에서 Bypass UAC를 수행할 수 있다는 것을 이미 알고 있습니다. 하지만 어떻게 할까요?
UAC를 우회하는 가장 많이 사용되는 방법은 Leo Davidson이 개발한 방법입니다. 그러나 이 방법은 IFileOperation COM 개체를 호출하기 위해 프로세스 인젝션을 수행하므로 일부 안티바이러스 소프트웨어에 탐지될 수 있습니다. 따라서 더 나은 접근 방식은 Cn33liz가 자체 Bypass UAC에서 사용한 Masquerade PEB라는 방법입니다.
또한 Leo Davidson 방법은 빌드 15002부터 UAC를 트리거하므로 최신 Windows 10 버전에서는 IFileOperation이 호출되는 방식을 수정해야 합니다. 따라서 해당 작업을 호출하는 방법은 원본과 동일하지만 "FOF_SILENT", "FOFX_SHOWELEVATIONPROMPT" 및 "FOF_NOERRORUI" 작업 플래그는 제외합니다.
익스플로잇을 실행하기 전에 실패하여 경보를 트리거하지 않도록 몇 가지 사항을 확인하는 것이 중요합니다. 가장 먼저 확인하는 것은 Windows 빌드 버전입니다. 빌드 버전이 7600보다 낮은 일부 버전은 우리의 익스플로잇에 취약하지 않기 때문입니다. 그 다음에는 아직 관리자 권한이 없는지 확인합니다. 관리자 권한이 이미 있다면 스크립트를 실행할 이유가 없습니다. 그런 다음 UAC 설정이 "항상 알림(Always notify)"으로 설정되어 있지 않은지 확인합니다. 해당 값으로 설정되어 있으면 익스플로잇이 쓸모없기 때문입니다. 마지막으로 사용자가 관리자 그룹에 속해 있는지 확인합니다. 그렇지 않으면 익스플로잇이 실패하기 때문입니다.
익스플로잇을 개발할 때 가능한 한 많은 시스템에서 작동하는 것이 중요하며, 여기에는 32비트 Windows 시스템도 포함됩니다. 이를 위해 64비트 시스템에서도 실행할 수 있으므로 32비트 시스템용으로 익스플로잇을 컴파일해야 합니다.
32비트 익스플로잇이 64비트 Windows 머신에서 실행되면 WOW64(64비트 머신에서 32비트 애플리케이션을 실행할 수 있게 해주는 Windows 하위 시스템)가 호출되므로 "dccw.exe"가 작동하는 방식이 약간 다릅니다. 즉, "dccw.exe.Local" 폴더는 "C:\Windows\System32\" 대신 "C:\Windows\SysWOW64\" 디렉터리에서 찾게 되며, 대상 "GdiPlus.dll"도 32비트 DLL이므로 "C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_*" 이름 패턴과 일치하는 폴더에서 찾게 됩니다. 그러나 32비트 Windows 시스템에서 실행되면 익스플로잇은 예상대로 작동합니다.
마지막으로, 100%의 효과를 보장하려면 DLL 하이재킹을 수행할 때 "C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_*" 패턴과 일치하는 모든 경로를 고려해야 한다는 점이 중요합니다.
높은 무결성으로 프로세스를 실행하려면 DLL 하이재킹을 통해 호출될 DLL을 개발해야 합니다. 그러나 보이는 것처럼 단순하지 않습니다. 단순히 그렇게만 하면 "dccw.exe"도 우리 코드도 실행되지 않기 때문입니다. "dccw.exe"는 "GdiPlus.dll"의 일부 함수에 의존하므로 해당 함수의 실행을 구현하거나 정식 DLL로 전달해야 합니다.
가장 좋은 방법은 정식 DLL로 실행을 전달하는 것입니다. 이렇게 하면 DLL의 크기를 줄일 수 있기 때문입니다. 이를 위해 ExportsToC++ 프로그램을 사용하여 "GdiPlus.dll"의 모든 익스포트를 C++ 언어로 포팅했습니다. 문제는 "GdiPlus.dll"이 가진 익스포트 수가 엄청나게 많다는 것인데, 정확히는 631개입니다. 그럼에도 "dccw.exe"는 모두가 아닌 일부만 임포트합니다. "dccw.exe"가 "GdiPlus.dll"에서 어떤 함수를 임포트하는지 알아보기 위해 "IDA Pro"로 리버스 엔지니어링을 수행했습니다. 마지막으로 "GdiPlus.dll"에서 임포트되는 함수는 15개뿐이므로 DLL에 해당 함수만 포함하면 됩니다.
이제 문제가 해결된 것처럼 보이지만 "C:\Windows\WinSxS\"의 특정 "GdiPlus.dll"로 실행을 전달하면 "WinSxS" 내부 폴더의 이름이 Windows 빌드마다 변경되므로 DLL은 일부 시스템에서만 작동합니다. 이 문제를 극복하기 위해 "C:\Windows\System32\GdiPlus.dll"로 실행을 전달하는 아이디어를 생각해 냈습니다. 이 경로는 모든 Windows 10 시스템에서 동일하기 때문입니다.
마지막으로 해야 할 일은 악성 코드를 실행한 후 "dccw.exe"의 실행을 중지하여 해당 프로세스의 창이 열리지 않도록 하는 것입니다.
이제 악성 DLL을 개발했으므로 대상 머신에 드롭해야 합니다. 이를 위해 우리의 DLL은 압축되어 "base64"로 익스플로잇에 인코딩되었으며, 런타임에 디코딩 및 압축 해제되어 원하는 대로 드롭될 수 있습니다.
마지막으로 우리가 제작한 "GdiPlus.dll"은 앞서 언급한 대로 IFileOperation COM 개체를 사용하여 대상 위치에 복사됩니다.
공격자가 시스템을 장악하면 가능한 한 오랫동안 탐지되지 않은 상태를 유지하려고 하며, 이는 수행하는 모든 작업의 흔적을 제거한다는 것을 의미합니다. 따라서 익스플로잇 실행 중 생성된 모든 임시 파일은 더 이상 필요하지 않을 때 제거됩니다.
마지막으로 높은 무결성으로 실행하려는 프로세스를 결정해야 합니다. 우리의 경우 관리자 권한을 획득하면 높은 무결성으로 원하는 만큼 많은 작업을 수행할 수 있으므로 "cmd.exe" 애플리케이션을 선택했습니다. 하지만 실제로는 원하는 애플리케이션이 무엇이든 실행할 수 있습니다.
익스플로잇을 실행하려면 대상 머신이 요구 사항을 충족하는지 확인해야 합니다. 그런 다음 다른 명령줄 스크립트처럼 익스플로잇을 실행하기만 하면 됩니다:
C:\Users\L3cr0f> DccwBypassUAC.exe
이 PoC의 Metasploit 모듈은 Masquerading PEB 대신 DLL 인젝션을 사용하며 다음에서 사용할 수 있습니다:
- Metasploit Framework: https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/bypassuac_injection_winsxs.rb이 익스플로잇은 공격자가 시스템에서 권한을 획득할 수 있는 방법을 보여주기 위해 개발된 것이지 악의적인 목적으로 사용하기 위한 것이 아닙니다. 즉, 누군가 이를 사용하여 범죄 활동을 수행하더라도 저는 어떤 책임도 지지 않습니다.
UAC(사용자 계정 컨트롤, User Access Control)는 Windows Vista에 도입된 기술로, 표준 사용자 권한 및 작업과 관리자 액세스가 필요한 권한 및 작업을 분리하는 방법을 제공합니다. 표준 사용자가 시스템을 사용하다가 권한이 없는 작업을 수행하려고 하면 Windows에서 프롬프트가 나타나 관리자 계정의 암호를 요구합니다. 관리자가 시스템을 사용하다가 동일한 작업을 수행하려고 하면 경고 프롬프트만 표시됩니다. 이 프롬프트는 관리자가 진행하기 전에 작업에 동의하기만 하면 되기 때문에 "동의 프롬프트(Consent Prompt)"로 알려져 있습니다. "동의 프롬프트(Consent Prompt)"를 우회할 수 있는 약점은 보안 경계로 간주되지 않으므로 보안 취약점으로 간주되지 않습니다.
그러나 Microsoft는 또한 "UAC(사용자 계정 컨트롤, User Account Control)는 Microsoft의 전반적인 보안 비전의 핵심 구성 요소입니다"라고 밝히고 있습니다.
출처:
- 보안 취약점의 정의.
- 사용자 계정 컨트롤의 작동 방식.