Home > 졸업프로젝트 > UEFI DXE 바이너리 취약점 분석기 프로젝트_11

UEFI DXE 바이너리 취약점 분석기 프로젝트_11
UEFI Ghidra

원하는 드라이버만 가지고 빌드해보자

 이번에는 지난 시간에 이어서 .fd 파일 내에 다른 딸려오는 드라이버들을 전부 쫙 빼버리고 내가 원하는 드라이버만 선택하여 빌드해보았다.
우선 fdf, dsc 파일의 변경이 필요하여 복구 과정의 귀찮은 일들을 피하기 위해 기존에 clone을 떠온 폴더를 복제한 새 폴더를 만들고 진행하였다.
제목
먼저 최상위 폴더에 빌드에 집어넣을 폴더를 만든다. 폴더를 만들고 그 폴더 안에 만들 드라이버들의 폴더들을, 그리고 그 안에 .dsc 파일과 .fdf 파일을 만든다.
여기서 .dsc 파일과 .fdf 파일은 C의 Makefile에 대응된다고 보면 생각하면 좋다. 대신 역할의 분리가 좀 있긴 한데, .dsc 파일은 소스 코드들을 가져와서 어떻게 .efi 실행 파일로 만들지에 대한 명세를 담고 있고, .fdf 파일은 .dsc를 통해 만든 .efi 드라이버 파일들을 모아서 어떻게 최종 펌웨어로 올릴지에 대한 명세를 담고 있다.

[Defines]
  PLATFORM_NAME                  = DepexTestPkg
  PLATFORM_GUID                  = 11111111-2222-3333-4444-555555555555
  PLATFORM_VERSION               = 1.0
  DSC_SPECIFICATION              = 0x00010005
  OUTPUT_DIRECTORY               = Build/DepexTest
  SUPPORTED_ARCHITECTURES        = X64
  BUILD_TARGETS                  = DEBUG|RELEASE
  SKUID_IDENTIFIER               = DEFAULT
  FLASH_DEFINITION               = DepexTestPkg/DepexTestPkg.fdf

[LibraryClasses]
  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf

[Components]
  DepexTestPkg/VulnMissingSmm/VulnMissingSmmDxe.inf
  DepexTestPkg/TestCycleA/TestCycleADxe.inf
  DepexTestPkg/TestCycleB/TestCycleBDxe.inf

DepexTestPkg 아래 .dsc 파일이다. 여기서 볼 것은 [Defines] 아래 PLATFORM_NAME, OUTPUT_DIRECTORY, FLASH_DEFINITION, 그리고 [Components]다. PLATFORM_NAME은 해당 패키지 플랫폼 이름을, OUTPUT_DIRECTORY는 저장될 경로를, 그리고 FLASH_DEFINITION의 .fdf 위치를 통해 파일을 읽어 펌웨어로 패키징까지 수행하게 된다. 그리고 [Components] 아래에 내가 만들 드라이버들의 .inf 파일들을 담게 된다.

[FD.DepexTestROM]
BaseAddress   = 0x0
Size          = 0x00100000
ErasePolarity = 1
BlockSize     = 0x1000
NumBlocks     = 0x100

0x00000000|0x00100000
FV = DXEFV

[FV.DXEFV]
# 오직 펌웨어 볼륨을 구성하는 필수 뼈대 3개만 남깁니다.
BlockSize          = 0x1000
FvAlignment        = 16
ERASE_POLARITY     = 1

INF DepexTestPkg/VulnMissingSmm/VulnMissingSmmDxe.inf
INF DepexTestPkg/TestCycleA/TestCycleADxe.inf
INF DepexTestPkg/TestCycleB/TestCycleBDxe.inf

[Rule.Common.DXE_DRIVER]
  FILE DRIVER = $(NAMED_GUID) {
    DXE_DEPEX    DXE_DEPEX Optional      |.depex
    PE32         PE32                    |.efi
    UI           STRING="$(MODULE_NAME)" Optional
  }

동일 경로의 .fdf 파일의 [FV.DXEFV] 안에 필수 드라이버들의 inf 파일들을 적어주면 된다.
이 때 .inf란 파일도 나왔는데, 이건 각 드라이버들의 명세라고 볼 수 있다.
제목
각 드라이버 폴더 내에는 C 코드와 .inf 파일를 만든다.

[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = VulnMissingSmmDxe
  FILE_GUID                      = AAAAAAAA-1111-2222-3333-444444444444
  MODULE_TYPE                    = DXE_DRIVER
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = VulnMissingSmmEntryPoint

[Sources]
  VulnMissingSmmDxe.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiDriverEntryPoint

[Depex]
  gEfiSmmBase2ProtocolGuid

.inf 파일 내에는 드라이버명, GUID, 컴파일 과정 중 C 파일 내에서 처음 읽을 진입점 함수명, C 파일의 위치, 필요한 의존성(Depex)들 등이 담겨있다.

#include <Uefi.h>

EFI_STATUS EFIAPI VulnMissingSmmEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EFI_SUCCESS; 
}

C 코드는 잘 작성하면 되고(…), .inf 파일의 시작점 함수를 잘 포함해주면 된다.

이후 빌드는

build -p DepexTestPkg/DepexTestPkg.dsc -a X64 -t XCODE5

위 명령어처럼 패키지의 .dsc 파일을 기준으로 하여 빌드를 수행하면
제목
빌드가 잘 저장된 것을 볼 수 있고,
제목
FV/DEPEXTESTROM.fd 파일을 UEFITool을 통해 열어보면 전부 다 펼쳐봐도 드라이버가 딱 세 개만 들어있는 것을 볼 수 있다.

현재 전체 파이프라인 처리를 위한 데이터셋(Depex, Logofail, Smm 취약점 전부 넣어서 하나의 fd 파일로 빌드) 생성 방법에 대한 고민중…

자동화 수정 방법

 지금까지는 .efi 파일을 뽑아내지 못하는 문제로 인해 7zip을 통해 .efi 파일을, UEFIExtract를 통해 Depex를 위한 dump directory를 뽑아내는 방식을 취했다. 이 과정에서 뽑아진 드라이버 개수가 7zip과 UEFIExtract 둘에서 서로 다른 문제, 추후 확장성 측면에서의 불편함 등이 있었다.
 위에서 만들었던 테스트 fd파일을 테스트를 위해 자동화 담당 팀원에게 보내줬는데 7zip과 UEFIExtract와 서로 뽑는 방식이 달라 사용할 수 없다고 했다. 그래서 이 부분을 제미나이에게 물어봤더니
제목
굳이 7zip를 쓰지 않고도 .efi 파일을 뽑아낼 수 있다고 했다! 좀 더 알아보니 드라이버명으로 이뤄진 폴더 내 DXE dependency section 폴더 아래에 Depex 코드가, PE32 image section 폴더 아래에 .efi 파일이 있었다. 이 떄 여기서 둘 다 같은 body.bin이란 이름으로 되어있어서 .efi를 찾지 못했던 것이였고, PE32 image section 아래의 body.bin의 확장자를 .efi로 변경했더니 실제로 우리가 원했던 efi 파일이 나온 것을 확인할 수 있었다.
(자세한 것은 자동화 쪽 발표에서….)

제목
수정된 파이프라인 이미지이지만언제또바뀔지모르겠는…