환상적인 RPC 인터페이스와 이를 찾는 방법
편집 및 추가 기여: 트리샤 하워드(Tricia Howard)
개요
Akamai 보안 리서치 팀은 지난 몇 달 동안 복잡성이 높고 그간 리서치가 부족했던 MS-RPC 리서치에 큰 노력을 기울였습니다. 이 작업의 결과로 발견된 취약점에 대한 수많은 게시물을 보셨을 것입니다. 예를 들면, srvsvc 및 Wininit.exe가 있습니다. 이 리서치를 통해 축적한 엄청난 양의 데이터와 툴을 보았을 때 한 장소에 저장하는 것이 합리적이었습니다. RPC 툴킷과 같은 곳에 말입니다.
이 오픈 소스 리포지토리에는 툴, 기사, 블로그 게시물, 컨퍼런스 내용, RPC 취약점 정보 등 RPC로 전환해 개념 증명을 악용하는 데 필요한 모든 것이 포함되어 있습니다. 이 리포지토리는 보안팀 직원과 연구자 모두가 RPC 지식에 더 쉽게 접속할 수 있도록 하기 위해 구축되었습니다. 함께 작업하는 것이 더 안전하기 때문입니다. Akamai의 저작물을 읽거나, 툴을 사용하거나, 공유한 적이 있는 모든 분께 감사합니다! 잘 활용해 주셔서 기쁩니다.
툴킷에 포함된 툴 중 하나는 RPC Interface Analyzer로, 이는 보안 전문가가 잠재적으로 취약한 인터페이스에 대한 단서를 빠르고 쉽게 식별할 수 있도록 지원합니다. 이 블로그 게시물은 아직 익숙하지 않은 사용자를 위해 RPC Interface Analyzer의 원래 목적과 조사 결과, RPC에 대한 개요 및 몇 가지 보안 메커니즘에 대해 자세히 안내하기 위한 것입니다.
RPC란 무엇이며, RPC의 보안 메커니즘은 무엇일까요?
RPC(Remote Procedure Call)은 클라이언트가 RPC 서버에 의해 노출되는 절차를 호출할 수 있도록 하는 IPC(프로세스 간 통신)의 한 형태입니다. 클라이언트는 원격 상호 작용에 대한 세부 정보를 코딩할 필요 없이 일반적인 프로시저 호출인 것처럼 함수를 호출합니다. 서버는 동일한 시스템 또는 원격 시스템에서 다른 프로세스로 호스팅할 수 있습니다.
마이크로소프트가 구축한 RPC인 MS-RPC는 Windows에서 작업 예약, 서비스 생성, 프린터 및 공유 설정, 원격에 저장된 암호화된 데이터의 관리 등 다양한 서비스에 많이 사용됩니다. MS-RPC의 광범위한 사용 범위와 RPC가 기법으로서 가지고 있는 원격의 특성은 오늘날 이에 대해 관심을 갖고 논의하고 있으며, RPC를 조사하는 데 많은 리소스를 투입한 이유입니다. 많은 기능이 있으므로 보안 관점에서 많은 관심을 끕니다.
다음 섹션에서는 RPC 보안 콜백에 대해 자세히 살펴보고 자동화를 사용해 이를 분석하는 방법과 보안 및 취약점 리서치를 위한 새로운 단서를 만들어내는 방법도 알아봅니다.
RPC 보안 콜백이란 무엇이며 어떻게 작동할까요?
간단히 말해 보안 콜백은 RPC 인터페이스를 보호하는 여러 방법 중 하나입니다. RPC 서버 개발자가 구축한 사용자 지정 콜백입니다. 이 논리는 개발자가 결정할 수 있으며 개발자가 사용자 기반 접속 제어, 인증, 전송 종류를 적용하거나 서버에서 노출되는 특정 기능에 대한 접속을 금지할 수 있습니다.
결국 콜백은 RPC_S_OK 를 반환해 클라이언트가 서버와의 통신을 허용하도록 하거나 RPC_S_ACCESS_DENIED와 같은 RPC 오류 코드중 하나를 반환해 거부하도록 합니다.
클라이언트의 요청을 수락하거나 거부하는 결정은 일반적으로 아래에서 살펴볼 하나 이상의 속성에 따라 달라집니다.
프로토콜 시퀀스
클라이언트는 TCP, 명명된 파이프, ALPC 등.여러 전송을 통해 서버와 통신할 수 있습니다. 보안 콜백은 '로컬 연결 요청만' '원격 요청만', 'TCP 통신' 등을 필터링할 수 있는 속성이 있는지 확인할 수 있습니다
프로토콜 시퀀스 값은 문서화되지 않지만 RpcCallAttributes 구조 내의 보안 콜백에 전달되고 있는 프로토콜 시퀀스를 다음 값으로 매핑했습니다.
#define ncacn_ip_tcp 1
#define ncacn_np 2
#define ncalrpc 3
#define ncacn_http 4
Ncacn_hvsocket 등의 기타 프로토콜 시퀀스는 문자열 바인딩의 구문 분석을 통해 보안 콜백으로 테스트할 수 있습니다.
인증 수준
클라이언트의 인증 수준 을 확인하는 것은 보안 콜백에서 흔히 발생합니다. 서버는 이런 방식으로 클라이언트에 필요한 최소 인증 수준을 정의할 수 있습니다.
여러 인증 수준이 있으며 각 인증 수준은 이전 수준을 확장합니다.
#define RPC_C_AUTHN_LEVEL_DEFAULT 0
#define RPC_C_AUTHN_LEVEL_NONE 1
#define RPC_C_AUTHN_LEVEL_CONNECT 2
#define RPC_C_AUTHN_LEVEL_CALL 3
#define RPC_C_AUTHN_LEVEL_PKT 4
#define RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
#define RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6
예를 들어, 서버는 통신 데이터가 클라이언트와 서버에만 표시되도록 하기 위해 RPC_C_AUTHN_LEVEL_PKT_PRIVACY 의 인증 수준을 예상하거나, RPC_C_AUTHN_LEVEL_NONE 의 인증 수준으로 인증 없음을 가리킬 것으로 예상합니다.
인증 서비스
인증 서비스 는 인증 수준에서 제공하는 인증 정책의 유효성을 검사하는 서비스를 명시합니다.
인증 서비스 상숫값은 다음과 같습니다.
#define RPC_C_AUTHN_NONE 0
#define RPC_C_AUTHN_DCE_PRIVATE 1
#define RPC_C_AUTHN_DCE_PUBLIC 2
#define RPC_C_AUTHN_DEC_PUBLIC 4
#define RPC_C_AUTHN_GSS_NEGOTIATE 9
#define RPC_C_AUTHN_WINNT 10
#define RPC_C_AUTHN_GSS_SCHANNEL 14
#define RPC_C_AUTHN_GSS_KERBEROS 16
#define RPC_C_AUTHN_DPA 17
#define RPC_C_AUTHN_MSN 18
#define RPC_C_AUTHN_DIGEST 21
#define RPC_C_AUTHN_NEGO_EXTENDER 30
#define RPC_C_NETLOGON 68(문서화되지 않음)
#define RPC_C_AUTHN_MQ 100
#define RPC_C_AUTHN_DEFAULT 0xffffffff
RPC_C_AUTHN_NONE을 예시로 들면 이는 인증을 끄고 RPC_C_AUTHN_WINNT는 NTLM 프로토콜을 사용합니다.
인증 서비스 및 해당 값의 전체 목록은 GitHub 페이지에서 확인할 수 있습니다.
NULL 세션
NULL 세션은 익명 연결입니다. 이 경우 클라이언트는 인증 없이, 즉 사용자 이름이나 비밀번호가 없는 서버와 통신합니다.
대부분의 경우 보안 콜백이 등록되면 서버 등록 시 RPC_IF_ALLOW_CALBACKS_WITH_NO_AUTH 플래그가 제공되지 않을 경우 NULL 세션은 기본적으로 차단됩니다. (여기를 클릭해 다른 케이스에 대해 알아보세요.) 보안 콜백은 NULLl 세션에 대해 확인할 수도 있습니다.
보안 콜백은 이러한 세션에 대한 접속을 차단함으로써 인증되지 않은 사용자로부터 RPC 인터페이스를 보호합니다.
작업 번호(Opnum)
Opnum은 클라이언트가 실행을 요청하는 인터페이스 기능을 나타냅니다. 더욱 정확하게 말하면 Opnum은 RPC 서버의 기능 테이블에 대한 색인입니다.
서버는 Opnum 값을 확인함으로써 원격 클라이언트의 민감한 데이터를 처리하는 기능, 커널 메모리, 사용자 모드 클라이언트를 위한 기능 등과 같은 특정 기능에 대한 클라이언트 접속을 제한하거나 차단할 수 있습니다.
Akamai 보안 연구팀은 이 검사를 사용하는 흥미로운 보안 콜백의 예시 를 블로그에 게시했습니다.
기타 보안 콜백 검사는 다음과 같습니다.
호출자 오리진 - 호출자가 사용자 모드인지 커널 모드인지 확인합니다.
클라이언트 PID - 특정 프로세스만 허용합니다.
문자열 바인딩 - 프로토콜 시퀀스, 네트워크 주소, 엔드포인트 정보 등과 같은 RPC 연결 속성의 유효성을 검사합니다.
위장 서버가 클라이언트의 보안 맥락에서 코드를 실행할 수 있는지 확인합니다
또한 복잡한 검사도 있습니다. 예를 들어, lsasrv.dll의 LsaCapRpcIfCallbackFn 콜백에서 인증 서비스가 Netlogon인 경우 인증 수준은 RPC_C_AUTHN_LEVEL_PKT_integrity보다 낮아야 합니다.
RPC Interface Analyzer - 자세한 설명
RPC Interface Analyzer는 RPC 인터페이스를 조사하기 위한 자동화 툴입니다. 이를 통해 연구자는 IDL(인터페이스 정의) 파일 또는 PE 파일이라는 두 가지 소스에서 RPC 인터페이스를 찾고 분석할 수 있습니다.
IDL 파일
IDL 파일 은 RPC 인터페이스 및 해당 기능을 정의하는 파일입니다. 공개적으로 사용할 수 있는 IDL 파일을 분석함으로써 RPC 인터페이스 및 서버에서 노출하는 함수에 대한 정보와 매개 변수 및 반환 값 종류를 얻을 수 있습니다. 연구원은 이 정보를 사용해 PetitPotam의 케이스처럼 경로 인수를 받는 함수와 같이 잠재적으로 취약한 함수를 찾을 수 있습니다.
Akamai의 IDL 분석기를 실행하려면 다음 명령을 실행합니다.
1. 다음과 같은 idl_scraper 스크립트를 사용해 모든 IDL 파일을 Microsoft 웹사이트에서 머신으로 다운로드합니다.
idl_scraper.py [-h] [-o OUTPUT] [-p PROTOCOL]
2. 그런 다음 idl_parser를 실행하고 다음 IDL 파일을 분석합니다.
idl_parser.py [-h] [-r] input_path [output_path]
RPC 인터페이스 이름, UUID(Universally Unique Identifier), 노출된 함수 이름, 서명이 포함된 CSV 파일이 출력됩니다.
PE 파일
IDL 파일을 분석하는 것은 유용할 수 있지만 공개적으로 사용할 수 있는 IDL 파일에만 접속할 수 있으므로 일부 RPC 인터페이스를 놓칠 수 있습니다. 또 다른 접근 방식은 로컬 파일 시스템인 PE 파일(.exe 또는 .dll 파일)에서 RPC 인터페이스를 찾는 것입니다. 라이브 프로세스를 확인하는 것보다 이 접근 방식을 사용하는 것이 좋습니다. 이렇게 하면 아직 라이브가 되지 않았거나 보호된 프로세스에서 실행 중인 RPC 서버를 놓치지 않기 때문입니다.
RPC PE Analyzer 는 RpcServerRegisterIf 함수(및 그 변형)에 의해 등록된 RPC 인터페이스를 찾고 디스어셈블러가 제공된 경우에 대비해 전달된 인수를 분석합니다. 분석기를 이 함수 없이 기본 모드에서 실행하면 Regex를 사용해 RPC 인터페이스를 찾을 것입니다. 이 강연 은 검색 프로세스에 대해 자세히 설명합니다.
RPC PE Analyzer를 기본 모드로 사용하려면 다음 명령을 실행합니다.
pe_rpc_scraper.py <scrape_path> <output_path>
이 명령은 인터페이스 UUID, 역할(클라이언트 및 서버), 함수 이름 및 주소를 포함하는 기본 출력을 제공합니다.
자세한 내용을 보려면 디스어셈블러 및 (기본값이 아닌 경우의) 경로를 스크립트에 제공할 수 있습니다.
pe_rpc_scraper.py [-d {idapro,radare}] [-P DISASSEMBLER_PATH] <scrape_path> <output_path>
디스어셈플러 옵션을 사용하면 다음과 같은 인터페이스 등록 정보도 추가됩니다.
서버 등록에 제공된 플래그
인터페이스의 보안 콜백 이름 및 주소
RPC 서버의 보안 설명자가 있는 경우 보안 설명자 정보
보안 콜백에 대해 글로벌 캐싱 활성화 여부
이 블로그 게시물과 함께 릴리스되는 최신 기능은 보안 콜백 자체의 분석도 제공합니다.
사용 예시
머신에서 사용할 수 있는 모든 RPC 인터페이스를 검색하려는 경우를 가정해 보겠습니다. RPC PE Analyzer를 실행해 C:\Windows\System32 복사본을 scrape_path로 제공하고 출력을 검토할 수 있습니다.
pe_rpc_scraper.py -d idapro “C:\Users\User\Documents\System32_Copy”
출력은 JSON 포맷이므로 반복하거나 특정 정보 찾기가 쉽습니다. 예를 들면 다음과 같습니다.
DLL 파일에서 모든 RPC 클라이언트 및 서버 찾기
머신에서 모든 RPC 클라이언트 및 서버 찾기
특정 RPC 인터페이스의 클라이언트 찾기
특정 RPC 서버의 RPC 보안 콜백 찾기
인터페이스 수준의 캐싱을 사용하는 RPC 인터페이스 찾기(이러한 캐싱이 문제가 되는 이유에 대한 자세한 내용은 이 블로그 게시물 에서 확인하세요.)
이 출력의 많은 사용 사례 중 몇 가지에 불과합니다. Akamai는 더 많은 사용 사례와 아이디어에 대해 듣게 되어 기쁩니다.
새로운 기능 - 보안 콜백 정보
RpcCallAttributes 구조
RPC_CALL_ATTRICTES는 클라이언트의 요청에 관한 데이터를 보유하는 구조입니다. 서버 측의 인터페이스 보안 콜백은 RpcServerInqCallAttributes 함수를 호출해 이 정보를 얻을 수 있습니다.
typedef struct tagRPC_CALL_ATTRIBUTES_V3_W
{
unsigned int Version;
unsigned long Flags;
unsigned long ServerPrincipalNameBufferLength;
unsigned short *ServerPrincipalName;
unsigned long ClientPrincipalNameBufferLength;
unsigned short *ClientPrincipalName;
unsigned long AuthenticationLevel;
unsigned long AuthenticationService;
BOOL NullSession;
BOOL KernelModeCaller;
unsigned long ProtocolSequence;
RpcCallClientLocality IsClientLocal;
HANDLE ClientPID;
unsigned long CallStatus;
RpcCallType CallType;
RPC_CALL_LOCAL_ADDRESS_V1 *CallLocalAddress;
unsigned short OpNum;
UUID InterfaceUuid;
unsigned long ClientIdentifierBufferLength;
unsigned char *ClientIdentifier;
} RPC_CALL_ATTRIBUTES_V3_W;
보안 콜백이 실행하는 테스트에 대해 이미 언급했습니다. 이러한 값 중 일부를 개별적으로 쿼리할 수 있으며(예를 들어 RpcStringBindingParseW는 프로토콜 시퀀스를 수신하기 위함이며 RpcBindingInqAuthClient는 인증 정보 등을 위함) 또는 모든 것을 보유하며 하나의 함수 호출만 필요한 이 구조를 사용합니다. 실제로 Akamai에서 분석한 대부분의 보안 콜백에서 RpcServerInqCallAttributes 함수를 호출해 RPC_CALL_ATTRIBUTES 구조를 사용하여 모든 속성을 동시에 쿼리합니다. 따라서 보안 콜백의 논리를 이해하려는 경우 이 구조가 매우 흥미롭습니다.
이 구조는 현재 1, 2, 3의 세 가지 버전을 가지고 있으며 각각 이전 버전의 확장이며 ANSI 및 유니코드 버전을 가지고 있습니다. 여기에서 다른 버전과 그 구성을 GitHub 페이지에서 확인할 수 있습니다.
보안 콜백 정보
RPC 툴킷에 새로 추가된 것은 보안 콜백 정보이며 RPC PE Analyzer의 일부입니다. 보안 콜백이 클라이언트 요청을 승인 및 거부하기 전에 수행하는 검사 및 확인을 미리 볼 수 있습니다.
RPC 인터페이스의 보안 콜백, 특히 RPC_CALL_ATTRIBUTES 구조에 대한 접속을 분석하면 인터페이스에 약간의 정보를 제공할 수 있습니다. 이러한 방식으로 특정 인증 프로토콜을 사용하는(또는 사용하지 않는) RPC 인터페이스를 필터링하려는 경우 인증 서비스 속성을 확인하는 보안 콜백을 찾을 수 있습니다. 또한 클라이언트 요청을 허용하고 서버 등록 플래그가 NULL 세션을 허용하기 전에 NULL 세션 을 확인하지 않는 RPC 인터페이스를 쿼리해 잠재적으로 취약한 RPC 인터페이스를 찾을 수 있습니다.
작동 방식은 어떨까요?
각 보안 콜백에 대해 분석가는 다음을 수행합니다.
사용 중인 RPC_CALL_ATTRIBUTES 구조 버전을 찾고 IDA의 로컬 종류에서 관련 구조를 정의합니다.
RpcCallAttribute 로컬 변수를 찾아 RPC_CALL_ATTRIBUTES 구조를 종류로 적용합니다.
이 구조를 사용해 보안 콜백이 수행하는 검사를 구문 분석하고 테스트할 멤버, 비교되는 값 및 연산자(== / != / > / < / 등)를 출력합니다.
어떻게 사용할 수 있을까요?
다음과 같이 사용법은 변경되지 않았습니다. IDA 디스어셈블러 플래그를 사용해 RPC PE Analyzer를 실행할 때마다 각 RPC 인터페이스의 출력에 보안 콜백 정보가 포함됩니다. 이 정보는 RpcCallAttributes 구조 구성원에 접속하는 경우 테스트되는 항목에 해당합니다.
참고: 이 추가 기능은 현재 IDA에서만 사용할 수 있으며 Radare 옵션으로 분석기를 실행하면 보안 콜백 정보가 포함되지 않습니다.
출력이 있으면 이를 사용해 취약한 RPC 인터페이스를 찾고 요구사항에 따라 필터링할 수 있습니다. 예를 들면 다음과 같습니다.
인증 수준인 RPC_C_AUTHN_LEVEL_PKT_PRIVACY만 사용하는 RPC 인터페이스를 가져옵니다.
로컬 연결이 필요한 RPC 인터페이스를 가져옵니다.
커널 모드 호출자만 필요한 RPC 인터페이스를 가져옵니다.
캐싱 취약점과 같이 Opnum을 검사하는 RPC 인터페이스를 가져옵니다.
요약
RPC는 리서치 분야에서 성숙한 기반을 갖추고 있으며, 특히 RPC가 얼마나 오래되고 얼마나 많은 중요 프로세스에 통합되었는지를 고려하게 되었습니다. 우리는 거의 1년 동안 리포지토리에 리소스를 모아왔으며, RPC의 위협 잠재력을 완전히 실현하기 위해 계속 노력을 쏟아야 할 부분이 많습니다. 이 리서치는 아직 대부분 제대로 연구되지 않은 상태이며, 최근 더 많은 주목을 받고 있지만, 공격자들이 악용하는 다양한 방법에 대해 알아봐야 할 부분이 아직 많습니다.
RPC의 본질적인 특성은 모든 잠재적 위험 각도에 대한 리서치를 보증합니다. 지속적인 리서치와 리포지토리에 있는 툴은 이 기법에 더욱 집중할 것이며, 다른 연구자들이 영감을 받아 이 기법에 대해 자세히 살펴볼 수 있기를 기대합니다. RPC 보안을 담당하는 보안팀 직원이든, 다음 목표를 찾는 연구자든, RPC는 지식과 인사이트에 대한 잠재력을 보유하고 있습니다.
시작할 준비가 되셨나요? 리포지토리를 확인하세요. 그리고 발견 사항을 트위터로 Akamai에게 꼭 알려주세요.