1. CommBuffer 검증 우회란?
CommBuffer(Communication Buffer)란 시스템 관리 모드(SMM, Ring-2)가 일반 운영체제(Ring 0)와 데이터를 주고받기 위해 사용하는 공유 메모리의 포인터이다.
SMM은 외부로부터 전달받은 CommBuffer의 주소가 진짜로 SMRAM 외부의 안전한 OS 구역에 있는지 반드시 확인해야 한다. 만약 이 검증 로직이 누락될 경우, 해커가 OS 환경에서 CommBuffer 포인터 자체를 SMRAM 내부 주소(SMM 드라이버의 코드 영역이나 중요한 인증 플래그 위치 등)로 조작해서 SMI를 발생 시킬 수 있다.
SMI 핸들러가 검증 없이 이 조작된 주소에 처리 결과값을 쓰게 되면, SMM 스스로 자신의 보호된 메모리를 덮어쓰게 되는 치명적인 사고가 발생할 수 있다.
2. 프로토타입 및 구조체
SMM 통신 과정에서 데이터가 어떻게 흘러가고 어디서 검증되어야 하는지 이해하기 위해서 핵심 헤더 파일에 정의된 프로토타입과 각 함수의 역할을 알아야 한다.
2.1. PiMmCis.h
PiMmCis.h는 통신을 받아 처리하는 SMM(또는 MM) 내부 핸들러가 어떤 형태의 인자들을 전달받아야 하는지에 대한 진입점 프로토타입을 정의하는 헤더 파일이다.
// MdePkg/Include/Pi/PiMmCis.h
typedef
EFI_STATUS
(EFIAPI *EFI_MM_INTERRUPT_MANAGE)(
IN CONST EFI_GUID *HandlerType,
IN CONST VOID *Context OPTIONAL,
IN OUT VOID *CommBuffer OPTIONAL, // 데이터의 물리 주소를 가리키는 포인터
IN OUT UINTN *CommBufferSize OPTIONAL
);
여기서 가장 중요한 것은 3번째 인자인 CommBuffer다. 이 포인터를 통해 전달된 주소나 데이터가 안전성을 확보하지 않은 채 곧바로 SMM 메모리 쓰기 로직으로 흘러가는지 체크해야 한다.
2.2. SmmMemLib.h
SmmMemLib.h는 SMM 환경에서 외부 메모리 접근의 유효성을 검증하고 보호하는 데 필수적인 라이브러리 클래스와 함수 원형이 정의된 헤더이다.
// MdePkg/Include/Library/SmmMemLib.h
BOOLEAN
EFIAPI
SmmIsBufferOutsideSmmValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
);
SmmIsBufferOutsideSmmValid() 함수는 SMI 핸들러가 외부에서 전달받은 포인터를 조작하기 전에 반드시 거쳐야 하는 필수 보안 관문이다. 인자로 전달받은 Buffer의 시작 주소부터 Buffer + Length까지의 전체 메모리 영역이, 시스템 부팅 시 하드웨어적으로 보호되도록 정의된 SMRAM 영역과 단 1바이트라도 겹치는지 계산 후, 겹치지 않는다면 TRUE, 겹친다면 FALSE를 반환한다.
3. 패턴 예시
3.1. CommBuffer 자체에 대한 검증 누락
#include <Library/SmmMemLib.h>
#include <Library/BaseMemoryLib.h>
EFI_STATUS
EFIAPI
VulnerableCommBufferHandler (
IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context,
IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize
)
{
// 해커가 CommBuffer를 SMRAM 주소(ex: 0x3F000000)로 셋팅해 보냈다면
// 아래의 CopyMem이나 포인터 대입은 Ring -2 권한으로 SMRAM을 직접 조작하게 됨
if (CommBuffer != NULL && CommBufferSize != NULL) {
UINT32 *ResultPtr = (UINT32 *)CommBuffer;
// 타겟 SMRAM 주소에 0x00000000 (EFI_SUCCESS) 값 쓰기
*ResultPtr = EFI_SUCCESS;
}
return EFI_SUCCESS;
}
위 코드는 SmmIsBufferOutsideSmmValid()를 이용한 메모리 영역 검증이 누락된 상태다. 공격자가 CommBuffer를 SMRAM 주소로 조작해 전달하면, *ResultPtr = EFI_SUCCESS; 구문이 실행될 때 SMM의 최고 권한(Ring -2)으로 보호되어야 할 SMRAM 영역에 임의의 값을 그대로 덮어쓰는 임의 쓰기 취약점이 발생한다.
3.2. 중첩 포인터(Nested Pointer) 검증 누락
// 해커가 전달하는 구조체
typedef struct {
UINT32 Command;
VOID *InnerDataPointer; // 구조체 내부에 또 포인터가 존재함
UINTN InnerDataSize;
} MY_COMPLEX_PAYLOAD;
EFI_STATUS
EFIAPI
VulnerableNestedPointerHandler (
IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context,
IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize
)
{
MY_COMPLEX_PAYLOAD *Payload;
// CommBuffer 자체는 안전하게 검증함 (1차 방어 성공)
if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, *CommBufferSize)) {
return EFI_SECURITY_VIOLATION;
}
Payload = (MY_COMPLEX_PAYLOAD *)CommBuffer;
// 구조체 내부의 Payload->InnerDataPointer 에 대한 2차 SmmIsBufferOutsideSmmValid 검증이 누락됨.
// 해커는 CommBuffer 자체는 일반 메모리에 두되 InnerDataPointer 값을 SMRAM 주소로 셋팅하여
// Confused Deputy Attack을 우회 성공시킬 수 있음
if (Payload->Command == 1) {
CopyMem (Payload->InnerDataPointer, "Secret", 6);
}
return EFI_SUCCESS;
}
VulnerableNestedPointerHandler 함수는 첫 번째 if문에서 CommBuffer 구조체 자체의 위치를 검증하므로 1차 방어에는 성공한다. 하지만 구조체 내부에 존재하는 Payload->InnerDataPointer에 대한 2차 검증이 누락되었다.
공격자가 CommBuffer 자체를 일반 메모리에 할당해 1차 검증을 통과한 뒤 내부의 InnerDataPointer 값만 SMRAM 주소로 조작하면, 하단의 CopyMem 함수가 실행될 때 SMM이 스스로 보호된 메모리를 덮어쓰게 되는 Confused Deputy(혼동된 대리자? 대리인?) 공격이 성립한다.
참고
https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiMmCis.h
edk2/MdePkg/Include/Pi/PiMmCis.h at master · tianocore/edk2
EDK II. Contribute to tianocore/edk2 development by creating an account on GitHub.
github.com
https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/SmmMemLib.h
edk2/MdePkg/Include/Library/SmmMemLib.h at master · tianocore/edk2
EDK II. Contribute to tianocore/edk2 development by creating an account on GitHub.
github.com
'CS > Graduation project' 카테고리의 다른 글
| [UEFI] gBS(Boot Services)란? (0) | 2026.02.24 |
|---|---|
| [UEFI] SMM/MM Communication Protocol이란? (0) | 2026.02.24 |
| [UEFI] BRLY-2022-016 분석 및 재현 (CommBuffer) (0) | 2026.02.23 |
| CVE-2021-42059 분석 및 실습 (0) | 2026.02.19 |
| [UEFI] 기드라 스크립트 검증과 오탐 분석 (0) | 2026.02.19 |