
CVE-2022-34301 Secure Boot 우회를 Eurosoft 서명 UEFI Shell(esdiags.efi)을 통해 시연하며, mm 명령을 사용하여 gSecurity2를 무효화하고 서명되지 않은 UEFI 애플리케이션을 로드합니다.
Eurosoft Pc-Check UEFI 진단 셸 - 자체 취약 UEFI 애플리케이션 사용(BYOVUA) - 서명된 UEFI 셸 및 gSecurity2 손상을 통한 Secure Boot 우회.
이 저장소는 CVE-2022-34301을 익스플로잇하여 BYOVUA (Bring Your Own Vulnerable UEFI Application) 기법을 시연합니다. CVE-2022-34301은 Eurosoft Pc-Check UEFI 진단 환경의 Secure Boot 우회 취약점입니다.
이 경우 Secure Boot가 신뢰하는 구성 요소는 esdiags.efi로, Eurosoft의 Pc-Check UEFI 하드웨어 진단 제품의 일부로 배포되는 UEFI 셸이며, Microsoft의 UEFI Third Party Certificate Authority가 신뢰하는 인증서 체인으로 서명되어 있습니다. 이 셸이 실행되면 mm (memory modify) 명령어를 노출하여 OS 부팅 전 단계에서 임의 메모리 읽기 및 쓰기 기능을 제공합니다.
이 프리미티브를 사용하여 DXE 코어의 gSecurity2 전역 포인터를 찾아 무효화할 수 있습니다. 그 결과 이후의 UEFI 이미지 검증이 비활성화되어, Secure Boot가 활성화된 상태에서도 서명되지 않은 UEFI 애플리케이션, 즉 부트킷을 로드할 수 있게 됩니다.
BYOVUA는 커널 수준에서 사용되는 BYOVD (Bring Your Own Vulnerable Driver) 기법의 UEFI 버전입니다. 취약점이 있는 서명된 커널 드라이버를 가져오는 대신, 공격자는 Secure Boot를 훼손할 수 있는 기능을 포함한 서명된 UEFI 애플리케이션 - 이 경우 전체 UEFI 셸 - 을 가져옵니다.
애플리케이션이 Secure Boot가 신뢰하는 인증서 체인으로 서명되어 있기 때문에 의심 없이 수용되며, Secure Boot 데이터베이스(db)에 Microsoft UEFI Third Party Certificate Authority를 포함하는 모든 시스템 - 지난 10년간 출시된 거의 모든 UEFI 지원 PC - 에서 신뢰됩니다. 일단 실행되면 내장 명령어를 통해 공격자에게 직접적인 하드웨어 및 메모리 접근 권한을 제공하며, 이는 운영 체제가 로드되기 전에 작동하여 현대 보안 제어(ASLR, DEP, 커널 보호)가 존재하지 않는 환경입니다.
esdiags.efi는 Eurosoft의 Pc-Check UEFI의 일부로 배포되는 UEFI 셸로, PC 제조사, 서비스 조직, IT 팀이 베어메탈 시스템 테스트에 사용하는 부팅 전 하드웨어 진단 제품입니다.
| 속성 | 값 |
|---|---|
| 파일 | EFI/Boot/Bootx64.efi (Microsoft) -> EFI/Boot/esdiags.efi (Shell) |
| 제조사 | Eurosoft (UK) Ltd |
| CVE | CVE-2022-34301 |
| 서명 | Microsoft Corporation UEFI CA 2011 (Third Party) |
| 발견 | Eclypsium (Mickey Shkatov, Jesse Michael) - 2022년 8월 |
| 발표 | DEF CON 30 - "One Bootloader to Load Them All" |
| 폐기 | Microsoft KB5012170을 통해 DBX에 추가됨 (2022년 8월) |
이 취약점은 버그가 아니라 설계 결함입니다. UEFI 셸은 Secure Boot 환경에서 실행되도록 의도되지 않은 합법적인 진단 도구입니다. 그러나 Microsoft가 신뢰하는 인증서로 서명하고 상용 제품의 일부로 배포함으로써, 제조사는 의도치 않게 Secure Boot에 대한 서명된 우회 경로를 만들어냈습니다.
핵심 문제: Secure Boot가 신뢰하는 서명된 바이너리가 내장 명령어를 통해 무제한적인 메모리 읽기/쓰기 기능을 제공합니다. 이 조합은 전체 Secure Boot 신뢰 모델을 무너뜨립니다.
mm (memory modify) 명령어는 시스템 메모리에 대한 직접 읽기 및 쓰기 접근을 제공하는 표준 UEFI 셸 내장 명령어입니다. 이는 UEFI Shell Specification (섹션 5.3)에 문서화되어 있습니다.```
MM Address [Value] [-w 1|2|4|8] [-MEM | -MMIO | -IO | -PCI | -PCIE] [-n]
| 파라미터 | 설명 |
|-----------|-------------|
| `Address` | 대상 메모리 주소 |
| `Value` | 기록할 값 (읽기 전용인 경우 생략) |
| `-w` | 너비: 1, 2, 4, 또는 8 바이트 |
| `-MEM` | 시스템 메모리 접근 |
| `-MMIO` | 메모리 매핑 I/O |
| `-IO` | I/O 포트 접근 |
| `-n` | 비대화형 (다음 주소에 대한 프롬프트 없음) |
---
<div id='gsecurity2'/>
### ***gSecurity2와 보안 아키텍처 프로토콜***
UEFI에서의 보안 부팅 이미지 검증은 UEFI 플랫폼 초기화(PI) 명세에 정의된 [보안 아키텍처 프로토콜](https://uefi.org/specs/PI/1.8/V2_DXE_Architectural_Protocols.html#security-architectural-protocols)을 통해 시행됩니다.
DXE 코어(DxeMain)는 `EFI_SECURITY2_ARCH_PROTOCOL` 구조체를 가리키는 [`gSecurity2`](https://github.com/tianocore/edk2/blob/edk2-stable202608/MdeModulePkg/Core/Dxe/DxeMain.h#L252)라는 전역 포인터를 유지합니다. 이 프로토콜은 단일 함수 포인터인 `FileAuthenticationState`를 포함하며, 이는 UEFI 이미지가 로드될 때마다 `LoadImage()`에 의해 호출됩니다:```c
// EFI_SECURITY2_ARCH_PROTOCOL structure (PI Specification)
typedef struct _EFI_SECURITY2_ARCH_PROTOCOL {
EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
} EFI_SECURITY2_ARCH_PROTOCOL;
// GUID: 94AB2F58-1438-4EF1-9152-18941A3A0E68
LoadImage()가 호출되면 DXE 코어는 다음을 확인합니다:```c
if (gSecurity2 != NULL)
{
Status = gSecurity2->FileAuthenticationState(gSecurity2, DevicePath, FileBuffer, FileSize, BootPolicy
);
if (EFI_ERROR(Status))
{
// Image rejected - signature verification failed
}
}
`gSecurity2 = NULL`로 설정하면 `if` 검사가 실패하고 `FileAuthenticationState`가 호출되지 않습니다. 이미지 검증이 완전히 건너뛰어집니다 - **Secure Boot는 "활성화"된 상태로 유지되지만 더 이상 강제되지 않습니다**. 서명되지 않은 UEFI 애플리케이션을 자유롭게 로드할 수 있게 됩니다.
gSecurity2를 자동으로 찾아 패치하는 목적별 UEFI 애플리케이션을 포함한 이 기법에 대한 심층적인 기술 이해는 동반 프로젝트를 참조하십시오: [Exploitation Technique - UEFI Secure Boot Bypass via gSecurity2 Corruption](https://github.com/TheMalwareGuardian/Exploitation-Technique-UEFI-SecureBoot-Bypass-gSecurity2-Corruption).
---
<div id='BYOVD'/>
### ***커널 BYOVD와의 유사점***
UEFI BYOVUA와 커널 BYOVD 간의 구조적 유사점은 정확히 일치합니다:```
┌──────────────────────────────────────────────────────────────┐
│ UEFI BYOVUA (Secure Boot Bypass) │
│ │
│ Signed Shell ─ mm ─> gSecurity2 = NULL ─> Load unsigned │
│ (trusted by (Security2 Protocol) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ Kernel BYOVD (DSE Bypass) │
│ │
│ Signed Driver ─ IOCTL ─> g_CiOptions = 0 ─> Load unsigned │
│ (trusted by (CI.dll) kernel drivers │
│ DSE / CI) │
└──────────────────────────────────────────────────────────────┘
두 공격 모두 동일한 근본적 결함을 악용합니다. 보안 메커니즘에 의해 신뢰되는 서명된 구성 요소가 바로 그 메커니즘 자체를 비활성화하는 데 필요한 기본 요소를 제공한다는 점입니다.
서명된 esdiags.efi는 EFI 시스템 파티션(ESP)에 배치되고 부팅 옵션으로 구성됩니다. Secure Boot가 신뢰하는 인증서 체인으로 서명되어 있기 때문에, 펌웨어는 문제없이 이를 검증하고 로드합니다.```
EFI System Partition (ESP)
└── EFI/
└── Boot/
└── Bootx64.efi (Microsoft) ← Signed by Microsoft Windows UEFI Driver Publisher
└── Bootxsa.efi (Shell) ← Signed by Eurosoft (UK) Ltd
---
<div id='Phase2'/>
### ***2단계 - Security2 프로토콜 핸들 열거***
UEFI Shell에서 목표는 `EFI_SECURITY2_ARCH_PROTOCOL`(GUID: `94AB2F58-1438-4EF1-9152-18941A3A0E68`)을 노출하는 핸들을 찾고, 해당 프로토콜 인터페이스의 메모리 주소를 얻는 것이다.
> **참고:** `dh -p <GUID>` 명령은 대부분의 EDK2 Shell 빌드에서 원시 GUID를 해석하지 않는다 - 등록된 프로토콜 이름만 인식한다. 아래 접근 방식은 모든 EDK2 Shell 버전에서 작동한다.
**1단계 - SecurityStubDxe 핸들 찾기**
모든 핸들을 나열하고 `SecurityStubDxe`를 찾는다. 이는 두 Security Architectural Protocol을 모두 설치하는 DXE 드라이버이다:```
Shell> dh
출력에서 SecurityStubDxe로 로드된 핸들을 식별합니다:```
10: Image(SecurityStubDxe)
**2단계 - 인접 핸들 검사**
`SecurityStubDxe`는 Security 프로토콜을 별도의 핸들에 설치하며, 일반적으로 바로 다음에 오는 핸들입니다. 이러한 핸들은 Shell이 해당 GUID를 친숙한 이름으로 매핑할 수 없기 때문에 짧은 목록에서 비어 있는 것으로 나타납니다. 상세 모드로 검사하십시오:```
Shell> dh -v 11
Expected output:``` Handle 11 (3EFCEF18) A46423E3-4617-49F1-B9FF-D1BFA9115839 (3EE8C398) 94AB2F58-1438-4EF1-9152-18941A3A0E68 (3EE8C3A0)
핸들 `0x11`에 이 GUID들이 없으면 `0x12`를 시도하십시오 - 정확한 핸들 번호는 펌웨어 빌드마다 다릅니다.
**3단계 - 인터페이스 주소 기록**
두 프로토콜과 그 인터페이스 주소는 다음과 같습니다: