[UEFI] CommBuffer 검증 우회 (Ring -2)

2026. 2. 24. 06:14·CS/Graduation project

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
'CS/Graduation project' 카테고리의 다른 글
  • [UEFI] gBS(Boot Services)란?
  • [UEFI] SMM/MM Communication Protocol이란?
  • [UEFI] BRLY-2022-016 분석 및 재현 (CommBuffer)
  • CVE-2021-42059 분석 및 실습
tteokbokki-master
tteokbokki-master
공부하며 알아가는 걸 조금씩 정리하고 있어요
  • tteokbokki-master
    용로그
    tteokbokki-master
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • 컴파일러개론
        • Graduation project
      • 프로그래밍 언어
        • HTML & CSS
        • JavaScript
        • React 기초
        • 파이썬 기초
        • TanStack-Query
        • C언어 기초
        • git
        • 리눅스
        • 코딩테스트 공부
      • 개발 지식
      • 언어학
        • 의미론
      • 회고 및 기록
      • 프로젝트
        • TodoList 만들기
        • 학수고대 프로젝트
        • 2025 동계 모각코 (안조용희)
      • 기타
        • [JS-0기] 한입 FE 챌린지
        • 서평
  • 인기 글

  • 글쓰기 / 관리
  • hELLO· Designed By정상우.v4.10.3
tteokbokki-master
[UEFI] CommBuffer 검증 우회 (Ring -2)
상단으로

티스토리툴바