방망이
[프로젝트]UEFI DXE 바이너리 취약점 분석기 4주차 - Ghidra Script 실습 본문
프로젝트의 진행 방향이 정해졌다.
내가 할 일은 DXE Dispatcher 파트 취약점을 탐지하는 기드라 스트립트를 만들고, 이 스크립트의 성능 확인용으로 간단한 취약점이 포함된 취약점 코드를 생성하는 것이다.
이를 진행하기 위해 공부해야 할 것들은 아래와 같다.
- Ghidra 스크립트 사용법 및 문법 공부
- P-Code에 대한 공부
- Analysis 기법 공부 (Tain Analysis, Fuzzing, Symbolic Execution 등)
- JSON
이번주에 할 공부는 Ghidra 스크립트 사용법이다.
가장 간단하게 이를 알아보기 위해 컴퓨터에 이미 존재하는 UEFI 파일로 실습을 진행해보려고 한다.
[실습]
1. 기드라 스크립트 코드 생성
기본적으로 기드라의 사용 방법과 기능 등에 대해 하나도 모르는 상태라서 이에 대한 큰 틀을 잡기 위해 코드 Import도 해보고, Analyze 기능도 사용해보았다. 스크립트 문법과 로직도 아무것도 모르기 때문에 Gemini의 도움을 받아 스크립트를 생성해서 .efi 파일에 스크립트를 실행해보려고 한다.
기본적이고 간단한 취약점이지만 자주 발견되고 치명적일 수 있는 '리턴 값 미검사 취약점'을 찾는 스크립트를 생성해보자.
DXE 드라이버가 Dispatcher로 LoadImage 함수를 호출하여 이미지 로드를 했을 때, Security Check에 걸려서 Dispatcher가 Error를 리턴했는 데, 드라이버가 그 결과를 확인하지 않고 다음 코드를 실행하게 되는 경우에 대한 탐지 스크립트이다.
이 취약점의 경우 로드되지 않은 메모리 영역을 사용하거나, 초기화되지 않은 포인터를 건드려서 시스템 충돌(BSOD)이 나거나 보안 우회가 발생하게 된다.
아래는 Jython(Java + Python 2.7) 스타일로 작성한 기드라 스크립트이다.
제미나이가 만들어낸 엉터리 로직 스크립트이니 사용하지 않길 바란다.
from ghidra.app.decompiler import DecompInterface
from ghidra.util.task import ConsoleTaskMonitor
from ghidra.program.model.symbol import SymbolType
def run():
print(">>> [Start]... <<<")
# 1. 분석 대상 프로그램 가져오기
# currentProgram은 Ghidra가 제공하는 전역 변수.
prog = currentProgram
fm = prog.getFunctionManager()
# 2. 디컴파일러 인터페이스 설정
# 기계어를 C언어 형태로 변환해주는 도구.
decomp = DecompInterface()
decomp.openProgram(prog)
monitor = ConsoleTaskMonitor()
# 3. 감시할 함수 목록 (UEFI 핵심 서비스)
target_funcs = ["LoadImage", "StartImage", "InstallProtocolInterface", "AllocatePool"]
vuln_count = 0
# 프로그램 내의 모든 함수를 반복.
funcs = fm.getFunctions(True)
for f in funcs:
# 모니터링 취소 확인
if monitor.isCancelled():
break
# 함수 디컴파일 시도 (타임아웃 30초)
res = decomp.decompileFunction(f, 30, monitor)
if not res.decompileCompleted():
# 디컴파일 실패 시 건너뜀
continue
# C언어 형태의 코드 가져오기
markup = res.getDecompiledFunction().getC()
# 코드가 없으면 패스
if not markup:
continue
# 라인 단위로 분석
lines = markup.split('\n')
for line in lines:
line = line.strip()
# 우리가 감시하는 함수가 이 라인에 있는지 확인
for target in target_funcs:
# 함수 이름이 있고, 화살표(->)로 호출하는 패턴인지 확인 (UEFI는 gBS->함수 형태가 많음)
if target in line:
# [취약점 판단 로직]
# 1. 함수를 호출했는데 '=' (대입)이 없는가?
# 2. 같은 라인에 'if' (조건문)이 없는가?
# -> 결과를 안 받고 그냥 실행만 시켰다는 뜻 (위험!)
if "=" not in line and "if" not in line:
# 오탐 줄이기: 주석(//)은 무시
if line.startswith("//"):
continue
print("\n[!]Unchecked Return Value")
print(" - function location : " + f.getName() + " @ " + str(f.getEntryPoint()))
print(" - error code : " + line)
print(" - reason : " + target + " does not check the result.")
vuln_count += 1
print("\n>>> [End] We found a total of %d suspected cases. <<<" % vuln_count)
# 스크립트 실행
if __name__ == "__main__":
run()
2. Ghidra 실습 환경 설정
- C:\Windows\Boot\EFI\ 경로에 있는 bootmgfw.efi(윈도우 부트 매니저)파일을 가져온다.
- 파일 넣기 (Import)
- 준비한 파일을 Ghidra 안으로 가져온다.
- File → Import File 클릭
- 준비해둔 .efi 파일을 찾아 더블 클릭
- 우측 하단의 OK 버튼 클릭
- "Import Results" 창이 뜨면 확인(OK)을 누르면 메인 화면 리스트에 파일 이름이 보임.
- 준비한 파일을 Ghidra 안으로 가져온다.

- 분석 돌리기 (Analyze)
- 리스트에 추가된 파일 이름 더블 클릭 또는 녹색 용 머리 아이콘 (CodeBrowser)을 클릭해서 창을 열기.
- 처음 열면 "Analyze?"라고 묻는 창이 뜨는데, Yes를 누르고 분석을 돌림.
- 화면 우측 하단에 파란색 진행 바가 전부 채워지면 분석 완료
- 스크립트 실행
- 상단 메뉴 Window → Script Manager 클릭
- 매니저 창 우측 상단의 문서+별표 아이콘(Create New Script) 클릭
- Jython 선택 (혹은 Python 선택)
- 파일명 입력 후 OK
- 새로 뜨는 편집창에 스크립트 코드 작성 후 Ctrl + S를 눌러 저장
- 편집창 상단의 녹색 재생 버튼(▶) 클릭
3. 결과 확인
결과를 확인해보면 bootmgfw.efi 파일에는 리턴값 미검사 취약점은 존재하지 않는 것을 알 수 있다.
취약점이 존재할 때 결과가 잘 나오는지 확인해보기 위해 StartImage를 call해서 실행 결과를 보고했으나, 이를 무시하는 명령어를 만들어서 시도해보도록 하자.
StartImage 함수는 실행을 시도한 뒤 결과를 가지고 오는 함수로, 문제가 있는 코드로 실행을 시도한다면 부팅을 멈추어야 하지만, 보안 우회가 발생할 경우 잘못된 코드가 그대로 실행되게 되어 문제를 일으킬 수 있게 된다.
아래 그림처럼 초록색 하이라이트 부분을 변경해보자.

FUN_1004e158 함수를 StartImage 함수로 바꿔치기 하고, 결과가 에러인지 확인하는 TEST RAX, RAX부분도 NOP으로 지우고, 에러일 때 멈추는 JNZ 명령어도 NOP으로 지울 때, 디컴파일 창의 코드도 StartImage 함수를 불러오는 것으로 변경되고 조건문도 없어진 것을 확인할 수 있다.

이 때 스크립트를 다시 실행해보면 아래와 같이 성공적으로 취약점을 잡아내는 것을 확인할 수 있다.
엉터리 로직으로 잡아낸 엉터리 취약점이지만, 직접 코드를 만져보고 실습해본 것에 의의를 두며,
다음주에 해야 할 일은 기드라 스크립트 문법에 대해 공부해볼까 한다.
'2026_졸업프로젝트' 카테고리의 다른 글
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 6주차 - DXE Dispatcher 취약점 및 Ghidra Script 작성 (0) | 2026.02.26 |
|---|---|
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 5주차 - DEPEX 확인법/Ghidra Script 기본 틀 (0) | 2026.02.26 |
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 3주차 - 방향성 탐구 (0) | 2026.02.26 |
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 2주차 - DEPEX/DXE Dispatcher (0) | 2026.02.26 |
| [프로젝트]UEFI DXE 바이너리 취약점 분석기 1주차 - UEFI/DXE/PE (0) | 2026.02.26 |