[UEFI] 기드라 스크립트 검증과 오탐 분석

2026. 2. 19. 16:53·CS/Graduation project

졸업프로젝트의 방향이 어느 정도 잡힌 뒤, 나는 팀원들이 짠 스크립트를 검증해 보는 역할을 맡게 되었다.

 

본격적으로 스크립트가 완성되기 전, 내 역할을 이해하고자 직접 안전한 드라이버를 생성하고, 빌드 후 기드라에서 스크립트를 돌려보며 제대로 탐지되는지 확인해 보았다.

 

 


 

1. 팀원의 간이 스크립트

 

https://ludence8.github.io/%EC%A1%B8%EC%97%85%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8/2026-02-12-UEFI_6.html

 

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

프로젝트 최종 분배  프로젝트 최종 인원 분배는 다음과 같이 결정했다. Ring -2 취약점 분석 및 스크립트 작성, 최종 문서화 DXE Dispatcher 취약점 분석 및 스크립트 작성 Ring 0 취약점 분석 및 스크

ludence8.github.io

페이지의 마지막 ‘’간단한 탐지 스크립트"를 사용했다.

 

해당 스크립트는 검증 없는 함수 호출을 잡아내는 역할을 하며, CALL 명령어를 발견 시, 해당 위치로부터 위로 15줄 이내에 CMP나 TEST 같은 안전성 검증 로직이 존재하는지 체크한다. 만약 검증 로직이 없다면 위험하다고 출력을, 있다면 안전하다고 출력한다.

 

 

 

 

2. 테스트용 드라이버 코드

 

이를 검증하기 위해 아래와 같은 테스트용 드라이버 코드를 작성했다.

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>

typedef EFI_STATUS (EFIAPI *MY_FUNC_PTR)(VOID);
volatile UINT64 mTargetAddress = 0xDEADBEEF;

EFI_STATUS
EFIAPI
SafeDriverEntryPoint(
        IN EFI_HANDLE ImageHandle,
        IN EFI_SYSTEM_TABLE *SystemTable
)
{
        MY_FUNC_PTR FuncPtr;
        DEBUG((DEBUG_INFO, "Safe Driver Loaded\n"));
        FuncPtr = (MY_FUNC_PTR)mTargetAddress;

        if(FuncPtr != NULL && (UINT64)FuncPtr != 0xFFFFFFFFFFFFFFFF){
                FuncPtr();
        }

        return EFI_SUCCESS;
}

임의의 주소(0xDEADBEEF)를 함수 포인터로 가져온 뒤, NULL이 아니고 0xFF..도 아닐 때만 실행하도록 이중 안전장치를 건 코드다. 빌드 후 efi 파일을 추출한 뒤, 이를 기드라에 올려서 앞서 만든 스크립트를 돌려보았다.

 

 

 

 

3. 결과

 

결과는 다음과 같다.

함수 호출 전에 분명 조건문으로 안전성을 확인했기에 안전하다고 뜰 것이라 기대했지만, 스크립트는 이를 위험하다고 탐지했다. 원인을 찾기 위해 기드라의 디스어셈블 코드를 뜯어보았다.

 

 

 

 

 

4. 오탐 분석

 

해당 스크립트에서 오탐이 발견된 이유는 스크립트가 LEA와 CMP의 연쇄 동작을 이해하지 못하기 때문이다.

실제 내가 작성한 드라이버를 기드라로 확인해보면, 아래와 같은 코드가 된다.

 

RAX 값을 이용해 RDX를 만들고, 그 RDX를 통해 비교를 해본 뒤 문제가 없으면 RAX를 실행한다. 하지만 간단하게 작성된 스크립트는 단순히 레지스터 이름을 가지고 비교를 했기에, "어? RAX를 실행하는데 정작 RAX 레지스터 자체로 비교하는 코드가 없네? 오류다!" 라는 결과를 내놓게 되는 것이다.

 

 

실제 잡히는지 확인하기 위해 안전성 부분을 더 간단하게 수정 후 빌드해 봤다.

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>

typedef EFI_STATUS (EFIAPI *MY_FUNC_PTR)(VOID);
volatile UINT64 mTargetAddress = 0xDEADBEEF;

EFI_STATUS
EFIAPI
SafeDriverEntryPoint(...)
{
    MY_FUNC_PTR FuncPtr;
    FuncPtr = (MY_FUNC_PTR)mTargetAddress;
    if (FuncPtr != NULL) {
        FuncPtr();
    }
    return EFI_SUCCESS;
}

단순히 NULL이 아니면 통과하는 조건문만 남긴 코드이다. 다시 빌드 후 기드라 스크립트로 돌려봤다.

 

 

앞선 예시와 다르게, 어셈블리 상에서 TEST RAX, RAX와 같이 RAX 레지스터를 직접 비교하는 명확한 패턴이 생성되었고, 이에 따라 스크립트도 "검증 로직이 있음"으로, 정상적으로 탐지하는 것을 확인할 수 있었다.

 

 

 

 

결론

 

1. P-CODE의 필요성을 깨닫게 되었다. 지금은 테스트 용도로 간단히 작성한 스크립트지만, 각 컴파일러마다 결과물이 다 다르기에 이런 방식으로는 커버할 수 없을 것 같다.

 

2. 취약점 유형을 보며 공부하고, 이에 대한 P-CODE도 보면서 눈에 익혀야 할 것 같다.

'CS > Graduation project' 카테고리의 다른 글

[UEFI] BRLY-2022-016 분석 및 재현 (CommBuffer)  (0) 2026.02.23
CVE-2021-42059 분석 및 실습  (0) 2026.02.19
CVE-2021-39297 분석 및 실습  (0) 2026.02.14
[UEFI] SetVariable()  (0) 2026.02.14
[UEFI] 리눅스(WSL) 환경에서 EDK2 빌드 및 실행  (0) 2026.02.14
'CS/Graduation project' 카테고리의 다른 글
  • [UEFI] BRLY-2022-016 분석 및 재현 (CommBuffer)
  • CVE-2021-42059 분석 및 실습
  • CVE-2021-39297 분석 및 실습
  • [UEFI] SetVariable()
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] 기드라 스크립트 검증과 오탐 분석
상단으로

티스토리툴바