방망이
[프로젝트]UEFI DXE 바이너리 취약점 분석기 11주차 - Ghidra Script 수정 및 검증 본문
[검증 전 확인 및 로직 보강]
검증을 하다보니 이런식으로 드라이버 별 구분이 아니라 프로토콜 별 구분으로 되어서 json 출력 로직을 수정하였다.

또한 드라이버 이름 기반으로 먼저 탐지하고 knownProtocolProvider() 함수에 있는 switch-case를 그 다음으로 보는 방법으로 했었는데, 그 두개의 순서를 바꾸어 자기 자신에 대한 프로토콜 제공자를 매칭하는 오탐을 수정하였다.
Bug를 사용할지 Defect를 사용할지 고민했었는데, Defect로 결정하게 되어 이것도 수정하였다. (블로그 작성 이후에 수정함)
[실행이 안 될 경우 BDS(Boot Device Selection) 페이즈로 넘어가지 못하는 드라이버]
- CpuDxe (1A1E4886-9517-440E-9FDE-3BE44CEE2136)
- CPU 초기화 및 인터럽트 처리를 담당하는 CPU 아키텍처 프로토콜을 제공합니다.
- Timer (C190FE35-44AA-41A1-8AEA-4947BC60E09D)
- 시스템의 기본 타이머 아키텍처를 제공합니다. 스케줄링 및 딜레이 처리에 필수적입니다.
- RuntimeDxe (B601F8C4-43B7-4784-95B1-F4226CB40CEE)
- OS로 진입한 후에도 유지되어야 하는 런타임 서비스 아키텍처 프로토콜을 제공합니다.
- SecurityStubDxe (F80697E9-7FD6-4665-8646-88E33EF71DFC)
- 보안(Security) 아키텍처 프로토콜을 제공합니다. 이미지 검증 등의 기반이 됩니다.
- VariableSmmRuntimeDxe (9F7DCADE-11EA-448A-A46F-76E003657DD1)
- UEFI 환경 변수(Variable) 읽기/쓰기를 위한 아키텍처 프로토콜입니다. 부팅 순서 등 핵심 정보 접근에 필요합니다.
- ResetSystemRuntimeDxe (4B28E4C7-FF36-4E10-93CF-A82159E777C5)
- 시스템 재부팅 및 종료를 담당하는 Reset 아키텍처 프로토콜을 제공합니다.
- MonotonicCounterRuntimeDxe (AD608272-D07F-4964-801E-7BD3B7888652)
- 단조 증가 카운터 아키텍처를 제공하며, 보안 및 식별 작업에 필수적입니다.
- WatchdogTimer (F099D67F-71AE-4C36-B2A3-DCEB0EB2B7D8)
- 부팅 중 무한 루프에 빠지는 것을 방지하는 워치독 타이머 아키텍처입니다.
- Metronome (C8339973-A563-4561-B858-D8476F9DEFC4)
- 매우 짧은 딜레이를 측정하는 Metronome 아키텍처 프로토콜입니다.
- BdsDxe (6D33944A-EC75-4855-A54D-809C75241F6C)
- DXE 페이즈의 최종 목적지로, 이 드라이버가 실행되어야 비로소 부팅 가능한 디바이스를 찾고 OS 로더를 실행하는 BDS 페이즈가 시작됩니다.
- PcRtc (378D7B65-8DA9-4773-B6E4-A47826A833E1)
RealTimeClockRuntimeDxe (B336F62D-4135-4A55-AE4E-4971BBF0885D)
- UEFI PI(Platform Initialization) 스펙에서 명시한 핵심 아키텍처 프로토콜(Architectural Protocols) 중 하나인 Real Time Clock (RTC) 아키텍처 프로토콜을 시스템에 제공합니다.
- EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL이 설치 되어야 부팅이 가능
- QEMU환경 (x86 하드웨어, ARM 등 다른 환경에서는 다름)
- PcRtc만 있으면 프로토콜이 설치 가능하지만
- RealTimeClockRuntimeDxe만 있으면 하드웨어를 못읽어서 제대로 동작을 안함. 즉, PcRtc만 필수
- UEFI PI(Platform Initialization) 스펙에서 명시한 핵심 아키텍처 프로토콜(Architectural Protocols) 중 하나인 Real Time Clock (RTC) 아키텍처 프로토콜을 시스템에 제공합니다.
- ReportStatusCodeRouterRuntimeDxe (D93CE3D8-A7EB-4730-8C8E-CC466A9ECC3C)
- 시스템의 상태와 에러 로깅을 담당하는 상태 코드(Status Code) 아키텍처 프로토콜
위 12개의 드라이버를 앞으로는 '부팅실패드라이버모음'이라고 부르겠다.
[Edk2 v21.02 Depex에서 요구되는 드라이버 및 프로토콜]
| 드라이버 | 프로토콜 |
| AcpiTableDxe | EfiAcpiTableProtocolGuid |
| BdsDxe | EfiBdsArchProtocolGuid |
| CpuDxe | EfiCpuArchProtocolGuid |
| EfiMpServiceProtocolGuid | |
| CpuIo2Dxe | EfiCpuIo2ProtocolGuid |
| DevicePathDxe | EfiDevicePathUtilitiesProtocolGuid |
| HiiDatabase | EfiHiiConfigRoutingProtocolGuid |
| EfiHiiDatabaseProtocolGuid | |
| EfiHiiImageExProtocolGuid | |
| EfiHiiStringProtocolGuid | |
| IoMmuDxe | EdkiiIoMmuProtocol |
| IoMmuAbsentProtocol | |
| Legacy5259 | EfiLegacy8259ProtocolGuid |
| Metronome | EfiMetronomeArchProtocolGuid |
| MonotonicCounterRuntimeDxe | EfiMonotonicCounterArchProtocolGuid |
| PcdDxe | EfiPcdProtocolGuid |
| PcRtc | EfiRealTimeClockArchProtocolGuid |
| PiSmmIpl | EfiMmCommunication2Protocol |
| ReportStatusCodeRouterRuntimeDxe | EfiRscHandlerProtocolGuid |
| ResetSystemRuntimeDxe | EfiResetArchProtocolGuid |
| RuntimeDxe | EfiRuntimeArchProtocolGuid |
| SecurityStubDxe | EfiSecurityArchProtocolGuid |
| SetupBrowser | EdkiiFormBrowserEx2ProtocolGuid |
| EfiFormBrowser2ProtocolGuid | |
| SmbiosDxe | EfiSmbiosProtocolGuid |
| SmmAccess2Dxe | EfiSmmAccess2ProtocolGuid |
| SmmControl2Dxe | EfiSmmControl2ProtocolGuid |
| SmmLockBox | EfiLockBoxProtocolGuid |
| Timer | EfiTimerArchProtocolGuid |
| VariableSmmRuntimeDxe | EfiVariableArchProtocolGuid |
| EfiVariableWriteArchProtocolGuid | |
| WatchdogTimer | EfiWatchdogTimerArchProtocolGuid |
위 표 중에서 부팅실패드라이버모음을 제외하면 아래와 같은 표가 완성된다.
| 드라이버 | 프로토콜 |
| AcpiTableDxe | EfiAcpiTableProtocolGuid |
| CpuIo2Dxe | EfiCpuIo2ProtocolGuid |
| DevicePathDxe | EfiDevicePathUtilitiesProtocolGuid |
| HiiDatabase | EfiHiiConfigRoutingProtocolGuid |
| EfiHiiDatabaseProtocolGuid | |
| EfiHiiImageExProtocolGuid | |
| EfiHiiStringProtocolGuid | |
| IoMmuDxe | EdkiiIoMmuProtocol |
| IoMmuAbsentProtocol | |
| Legacy5259 | EfiLegacy8259ProtocolGuid |
| PcdDxe | EfiPcdProtocolGuid |
| PiSmmIpl | EfiMmCommunication2Protocol |
| SetupBrowser | EdkiiFormBrowserEx2ProtocolGuid |
| EfiFormBrowser2ProtocolGuid | |
| SmbiosDxe | EfiSmbiosProtocolGuid |
| SmmAccess2Dxe | EfiSmmAccess2ProtocolGuid |
| SmmControl2Dxe | EfiSmmControl2ProtocolGuid |
| SmmLockBox | EfiLockBoxProtocolGuid |
하지만 이 13개의 드라이버 중 부팅실패드라이버모음에서 요구되는 드라이버가 존재하여, 없을 경우 연쇄작용으로 부팅실패드라이버모음에 있는 드라이버가 실행이 안될 수 있으므로 이 또한 제외할 경우 최종적으로 아래와 같은 표가 완성된다.
| 드라이버 | 프로토콜 |
| AcpiTableDxe | EfiAcpiTableProtocolGuid |
| CpuIo2Dxe | EfiCpuIo2ProtocolGuid |
| SetupBrowser | EdkiiFormBrowserEx2ProtocolGuid |
| EfiFormBrowser2ProtocolGuid | |
| SmbiosDxe | EfiSmbiosProtocolGuid |
| SmmLockBox | EfiLockBoxProtocolGuid |
즉, 위 표와 같이 총 5개의 드라이버만 남게 된다.
이 중 SmmLockBox는 SMM 드라이버이지만, 이 드라이버가 없을 경우 DXE 드라이버가 영향을 받으므로 포함한다.
UEFITool을 가지고 일부 드라이버를 삭제한 후 진행하려 하는데, NE 버전은 드라이버 삭제가 불가하고 이전 버전은 FV 내부의 체크섬이 깨질 수 있다.
따라서 OVMF.fd 파일을 만드는 방법은
1. UEFITool 0.28.0 버전으로 드라이버를 삭제
2. QEMU로 부팅 확인
이렇게 2단계를 거쳐서 진행하려 한다.
현재 기대되는 결과는 다음과 같다
| 드라이버 | 프로토콜 | 요구한 드라이버 |
| AcpiTableDxe | EfiAcpiTableProtocolGuid | AcpiPlatform |
| CpuIo2Dxe | EfiCpuIo2ProtocolGuid | PciHostBridgeDxe |
| SetupBrowser | EdkiiFormBrowserEx2ProtocolGuid | DisplayEngine |
| EfiFormBrowser2ProtocolGuid | SecureBootConfigDxe RamDiskDxe DriverHealthManagerDxe |
|
| SmbiosDxe | EfiSmbiosProtocolGuid | SmbiosPlatformDxe |
| SmmLockBox | EfiLockBoxProtocolGuid | BootScriptExecutorDxe |
- AcpiTableDxe
- AcpiPlatform 드라이버에서 요구, Bug로 판정
- CpuIo2Dxe
- PciHostBridgeDxe 드라이버에서 요구, Bug로 판정
- SetupBrowser
- DisplayEngine 드라이버에서 요구, Bug로 판정
- SecureBootConfigDxe 드라이버에서 요구, Vulnerability로 판정
- RamDiskDxe 드라이버에서 요구, Bug로 판정
- DriverHealthManagerDxe 드라이버에서 요구, Bug로 판정
- SmbiosDxe
- SmbiosPlatformDxe 드라이버에서 요구, Bug로 판정
- SmmLockBox
- BootScriptExecutorDxe 드라이버에서 요구, Vulnerability로 판정
1. UEFITool 0.28.0 버전으로 드라이버를 삭제
5가지 드라이버를 각각 삭제한 총 5개의 fd 파일을 만들었다.
2. QEMU로 부팅 확인
Edk2 v21.02 빌드는 Ubuntu 24.02 LTS 환경에서 아래 블로그를 참고하며 진행하였다.
아래 사진은 정상적으로 부팅되었을 때 QEMU 화면이다.

AcpiTableDxe, SetupBrowser, SmbiosDxe, SmmLockBox 드라이버에 대해서는 부팅이 잘 완료 되었으나, CpuIo2Dxe 드라이버가 없을 경우 부팅이 완료되지 않았다.
이유를 찾아보니
CpuIo2Dxe가 없으면 PciHostBridgeDxe 실행이 안되는데, PciBusDxe가 Depex에는 PciHostBridgeDxe를 요구하지 않아서 로드는 되지만, PCI 열거(enumeration) 시점에 EfiPciHostBridgeResourceAllocationProtocol을 찾지 못해 동작에 실패한다. 따라서 CpuIo2Dxe 드라이버가 없을 경우 연쇄 작용으로 PciBusDxe의 동작이 실패하여 최종적으로 부팅에 실패하게 되는 것이다.
정리하자면,
CpuIo2Dxe 없음 → PciHostBridgeDxe 로드 실패 → PciBusDxe가 PCI 장치 열거 불가 → 부팅 불가
따라서 CpuIo2Dxe 드라이버를 제외한 4개의 드라이버에 대해 검증을 하도록 한다.
추가로 앞서 소개한 Depex에서 요구되는 모든 드라이버에 대해 존재하지 않을 때 부팅 여부를 확인해본 결과, 위 4가지 드라이버를 제외한 모든 드라이버가 예상했던 대로 부팅이 완료되지 않았다. -> 4개의 드라이버를 검증 대상으로 하는 근거 검증 완료
간단히 정리하자면 아래와 같다. 사용할 OVMF.fd 파일도 같이 올린다.
현재 펌웨어볼륨 환경 : edk2 v21.02버전
DXE 드라이버 개수 : 101개
DEPEX에서 요구되는 (프로토콜을 설치하는) 드라이버(SMM 드라이버 포함) : 25개
삭제될 경우 부팅이 완료되지 않을 드라이버 (SMM 드라이버 포함) : 20개
-> 없어도 부팅이 완료될 드라이버 5개
1. AcpiTableDxe
2. CpuIo2Dxe
3. SetupBrowser
4. SmbiosDxe
5. SmmLockBox
[검증]
- AcpiTableDxe
- AcpiPlatform 드라이버에서 요구, Bug로 판정 => 정탐

- SetupBrowser
- DisplayEngine 드라이버에서 요구, Bug로 판정 => 정탐
- SecureBootConfigDxe 드라이버에서 요구, Vulnerability로 판정 => 정탐
- RamDiskDxe 드라이버에서 요구, Bug로 판정 => 정탐
- DriverHealthManagerDxe 드라이버에서 요구, Bug로 판정 => 정탐

- SmbiosDxe
- SmbiosPlatformDxe 드라이버에서 요구, Bug로 판정 => 정탐

- SmmLockBox
- BootScriptExecutorDxe 드라이버에서 요구, Vulnerability로 판정 => 정탐

검증 결과 4개의 드라이버에 대해 0%의 오탐률을 확인하였다.
'2026_졸업프로젝트' 카테고리의 다른 글
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 13주차 - P-code Phase1 (0) | 2026.05.12 |
|---|---|
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 12주차 - P-code 이론 (0) | 2026.05.04 |
| Edk2 빌드 (smm 드라이버 포함) (0) | 2026.04.02 |
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 10주차 - Ghidra Script 수정 (0) | 2026.03.29 |
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 9주차 - 취약점 선정 및 Ghidra Script 수정 (0) | 2026.03.18 |
