
Administrator 권한 컨텍스트에서 폰트 유효성 검사 실행 리디렉션 기술을 사용하여 커널 모드 코드를 읽고, 쓰고, 실행할 수 있는 Windows 명령줄 유틸리티로, 고급 커널 디버깅 및 시스템 문제 해결을 지원합니다.
r0ak는 Windows 명령줄 유틸리티로, 관리자 권한 외에는 다른 것이 필요 없이 명령 프롬프트에서 커널 모드 코드를 쉽게 읽고, 쓰고, 실행할 수 있게 해줍니다(일부 제한 사항 있음).
r0ak v1.0.0 -- Ring 0 Army Knife
http://www.github.com/ionescu007/r0ak
Copyright (c) 2018 Alex Ionescu [@aionescu]
http://www.windows-internals.com
USAGE: r0ak.exe
[--execute <Address | module.ext!function> <Argument>]
[--write <Address | module.ext!function> <Value>]
[--read <Address | module.ext!function> <Size>]

Windows 커널은 일반적인 시스템에서 수백 개의 드라이버가 실행되고 전역 상태를 포함하는 수천 개의 변수가 존재하는 풍부한 환경입니다. 고급 문제 해결을 위해 IT 전문가는 일반적으로 Windows 디버거(WinDbg), SysInternals 도구와 같은 도구를 사용하거나 자체 도구를 작성합니다. 불행히도 이러한 도구의 사용은 점점 더 어려워지고 있으며, Windows API 및 노출된 기능에 대한 자체 액세스로 인해 제한을 받습니다.
오늘날의 몇 가지 과제는 다음과 같습니다.
이러한 환경에서 커널 상태 분석을 통해 명백해질 수 있는 커널/시스템 수준 문제를 신속하게 해결하고 문제를 진단하기 위해 비상용 임시 방편/핫픽스로 사용할 수 있는 간단한 도구가 커뮤니티에 유용할 수 있다는 것이 분명했습니다.

r0ak는 새 글꼴을 로드하려고 할 때 창 관리자의 신뢰할 수 있는 글꼴 유효성 검사 검사의 실행 흐름을 리디렉션하여 작동합니다. 신뢰할 수 있는 글꼴 테이블의 비교기 루틴을 입력 노드에 저장된 실행 작업 항목(WORK_QUEUE_ITEM)을 예약하는 대체 함수로 대체합니다. 그런 다음 신뢰할 수 있는 글꼴 테이블의 오른쪽 자식(루트 노드 역할)이 사용자 지정 작업 항목이 저장된 명명된 파이프의 쓰기 버퍼(NP_DATA_ENTRY)로 덮어써집니다. 이 항목의 기본 작업자 함수와 해당 매개 변수는 글꼴 로드가 시도되고 비교기 루틴이 실행되어 명명된 파이프 백업 부모 노드를 입력으로 수신하면 PASSIVE_LEVEL에서 전용 ExpWorkerThread에 의해 최종적으로 실행됩니다. 실시간 ETW(Event Tracing for Windows) 추적 이벤트는 작업 항목 실행이 완료되었다는 비동기 알림을 수신하는 데 사용되므로 구조를 해제하고, 커널 모드 버퍼를 해제하고, 정상 작동을 복원하는 것이 안전합니다.
--execute 옵션을 사용할 때 이 함수와 매개 변수는 사용자가 제공합니다.
--write를 사용할 때는 사용자 지정 가젯을 사용하여 커널 메모리의 어느 곳에서나 임의의 32비트 값을 수정합니다.
--read를 사용할 때는 쓰기 가젯을 사용하여 시스템의 HSTI 버퍼 포인터와 크기를 수정합니다(참고: 이는 HSTI 데이터를 요청하는 다른 애플리케이션에 대해 파괴적인 동작입니다. 이는 선택적 Windows 동작이며 이 도구는 긴급 디버깅/실험을 위한 것이므로 이러한 데이터 손실은 허용 가능한 것으로 간주되었습니다). 그런 다음 HSTI 쿼리 API를 사용하여 도구의 사용자 모드 주소 공간에 다시 복사하고 16진수 덤프가 표시됩니다.
빌트인된 Microsoft 서명 Windows 기능만 사용되고 호출된 모든 함수가 KCFG 비트맵의 일부이므로 보안 검사를 위반하지 않으며 디버깅 플래그가 필요하지 않거나 잘못 작성된 타사 드라이버를 사용하지 않습니다.
아니요. 이 도구(및 기본 기술)는 관리자 계정으로 실행 중인 사용자만 얻을 수 있는 SYSTEM 수준의 권한 토큰이 필요하므로 효과를 달성하기 위해 보안 경계가 우회되지 않습니다. 이 도구의 동작과 유틸리티는 Windows의 관리자 계정의 상승된/권한 있는 보안 컨텍스트로 인해 가능하며, 설계상 동작으로 이해됩니다.
물론입니다! 권한 경계 위반이 발생하지 않은 것 같아도 항상 Microsoft에 보안 문제를 제출하는 것이 중요합니다. 그들의 연구원 및 개발자 팀은 외부 연구원이 생각하지 못한 새로운 벡터와 특정 코드 경로에 도달하는 방법을 찾을 수 있습니다.
이에 따라 2014년 11월 Microsoft 보안 대응 센터(MSRC)에 보안 케이스가 제출되었고, 다음과 같은 응답을 받았습니다. "[…] 전통적인 Security Bulletin을 통해 해결할 보안 문제의 범위에 속하지 않습니다. […] 관리자 권한을 전제로 합니다. 이는 아키텍처상 현재 방어 가능한 보안 경계를 정의하지 않는 위치입니다. 따라서 이를 수정하기 위해 추구하지 않을 것입니다."
또한 2015년 4월 Infiltrate 컨퍼런스에서 Insection : AWEsomely Exploiting Shared Memory Objects라는 제목의 발표가 이 문제를 자세히 설명했으며, 참석한 Microsoft 개발자들도 이것이 현재 Windows의 아키텍처 보안 경계를 벗어난다는 데 동의했습니다. 관리자가 Ring 0 메모리를 읽고/쓰고/실행할 수 있는 다른 방법은 말 그대로 수십 가지(더 많지는 않지만)가 있기 때문입니다. 이 도구는 시스템 문제를 디버깅하고 문제를 해결하기 위해 그러한 벡터 중 하나를 쉽게 상품화할 수 있도록 합니다.
이 코드를 라이브러리로 패키징하려면 모든 대화형 명령줄 구문 분석 및 표준 출력을 신중하게 제거해야 하며, 주요 재작성 없이 '킷'은 다음을 필요로 합니다.
이 특정 접근 방식(보다 더 교차 호환 가능하고 SYSTEM 권한이 필요하지 않은 기술과 비교하여)을 사용하는 데 관심이 있는 공격자는 이미 3년 이상 전인 2015년 4월의 개념 증명을 기반으로 자체 코드를 적용했을 것입니다.
Windows Symbol Engine 사용으로 인해 Windows SDK(소프트웨어 개발 키트) 또는 WDK(Windows 드라이버 키트)가 Debugging Tools for Windows와 함께 설치되어 있어야 합니다. 이 도구는 설치 경로를 자동으로 조회하고 해당 디렉토리에 있는 DbgHelp.dll 및 SymSrv.dll을 활용합니다. 이러한 파일은 재배포할 수 없으므로 도구 릴리스에 포함할 수 없습니다.
또는 이러한 라이브러리를 직접 구한 경우 소스 코드를 수정하여 사용할 수 있습니다.
기호 사용에는 인터넷 연결이 필요합니다(로컬로 미리 캐시하지 않은 경우). 또한 적절한 기호 서버와 캐시 위치를 가리키는 _NT_SYMBOL_PATH 변수를 설정해야 합니다.
커널 메모리를 읽고/쓰고/실행할 필요가 있고(액세스할 적절한 커널 변수에 대한 지식이 있는) IT 전문가 또는 기타 문제 해결사는 이미 위의 설정 요구 사항에 매우 익숙할 것으로 가정합니다. SDK가 무엇인지 또는 환경 변수를 설정하는 방법에 대해 묻는 문제를 제기하지 마십시오.
일부 드라이버가 커널 풀을 유출했습니까? ntoskrnl.exe!ExFreePool을 호출하고 유출되는 커널 주소를 전달하는 것은 어떻습니까? 개체 참조는 어떻습니까? ntoskrnl.exe!ObfDereferenceObject를 호출하여 정리하십시오.
커널 DbgPrint 로그를 덤프하고 싶습니까? ntoskrnl.exe!KdPrintCircularBuffer의 내부 순환 버퍼를 덤프하십시오.
시스템의 커널 스택 크기가 얼마나 되는지 궁금하십니까? ntoskrnl.exe!KeKernelStackSize를 확인해 보십시오.
시스템 호출 테이블을 덤프하여 후크를 찾고 싶습니까? ntoskrnl.exe!KiServiceTable을 출력하십시오.
이것은 몇 가지 예에 불과합니다. 모든 Ring 0 주소는 module!symbol 구문을 사용하거나 알려진 경우 커널 포인터를 직접 전달하여 허용됩니다. Windows Symbol Engine이 이를 조회하는 데 사용됩니다.
이 도구는 최신 버전의 Windows 10에만 존재하는 것으로 알려진 특정 커널 변수와 함수를 필요로 하며 64비트 시스템에서만 작동하도록 설계되었습니다. 이러한 제한은 이전 시스템(x86 시스템)에는 이러한 더 엄격한 보안 요구 사항이 존재하지 않으므로 대신 더 전통적인 접근 방식을 사용할 수 있기 때문입니다. 이것은 제가 사용할 수 있도록 만든 개인 도구이며, 간단한 드라이버를 사용할 수 있었던 이러한 이전 시스템이 필요하지 않았습니다. 그럼에도 불구하고 이 저장소는 포팅에 관심이 있는 경우 풀 리퀘스트를 받습니다.
둘째, 사용 사례와 제 필요로 인해 다음 제한 사항이 적용됩니다.
분명히 이러한 제한은 프로그래밍 방식으로 다른 접근 방식을 선택하여 해결할 수 있지만, 명령줄 도구의 필요와 제 사용 사례에 적합합니다. 다시 말하지만, 다른 사람들이 자신의 추가 기능을 기여하려면 풀 리퀘스트를 받습니다.
모든 실행(--read 및 --write 명령 실행 포함)은 PASSIVE_LEVEL의 System Worker Thread 컨텍스트에서 발생합니다. 따라서 사용자 모드 주소를 매개 변수/인수로 전달해서는 안 됩니다.
풀 리퀘스트는 환영합니다. 주요 변경 사항의 경우 먼저 이슈를 열어 변경하고자 하는 사항을 논의해 주십시오.
Copyright 2018 Alex Ionescu. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY ALEX IONESCU ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALEX IONESCU
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the authors and
should not be interpreted as representing official policies, either expressed or implied, of Alex Ionescu.