아니라 전 세계적으로 가장 많이 발견되고, 문서형 악성코드 중 가장 취약점이 많은 PDF(Portable Document Format) 전자 문서형 악성코드에 대해 살펴보려 합니다. PDF는 Adobe 사가 1993년 종이 문서를 대체할 목적으로 전자 문서 포맷 PDF 1.0 버전과 이를 작성하고 읽을 수 있는 Acrobat 1.0을 발표하면서 세상에 혜성처럼 등장하였습니다. 이후 여러 번의 업데이트와 중요 기능을 추가하면서 발전을 거듭한 끝에 2008년 “ISO 32000”으로 국제 표준이 되었고, 현재 전 세계적으로 가장 많이 사용되는 전자 문서 포맷으로 자리 잡았습니다. 이렇게 자리를 잡을 수 있던 가장 큰 이유 중 하나가 자동문서 변환 기능을 통하여 이기종 간 동일한 문서 포맷(문서 뷰어)으로 읽을 수 있다는 아주 강력한 호환성 때문입니다. 이는 PDF를 사용하는 사용자에게 편리함을 제공합니다. 하지만 반대로 공격자에게 하나의 공격 포인트를 제공하는 것으로써, 공격자는 이러한 전자 문서의 내용을 읽기 위해 별도의 PDF Viewer 프로그램을 실행하여야 하는 점을 노렸고, 이에 사회공학적 공격 기법*을 결합하여 공격을 시도하였습니다.
* (문서형 악성코드 측면) 사회공학적 공격 방법은 해커가 지인이나 믿을 수 있는 기관 등을 사칭하여 사용자가 의심 없이 문서를 열람하도록 하여 악성코드에 감염시키는 공격 방법
PDF 문서형 악성코드는 다른 악성코드에 비해 비교적 최근에 유행하기 시작한 악성코드로, 2007년 10월 이전에는 존재하지 않았습니다. 하지만 2007년 10월 이후 Adobe PDF 취약점에 대한 “CVE-2007-5020”가 공개된 이후 PDF 취약점을 이용한 공격이 폭발적으로 증가하였습니다. 이렇게 PDF를 이용한 공격이 폭발적으로 증가할 수 있었던 이유는 첫 번째, 전 세계적으로 가장 많이 사용되는 전자 문서에 심각한 취약점이 발견된 것이고, 두 번째, 문서형 악성코드는 사회공학 기법을 활용하기에 최적화되어 있기 때문입니다. 사회공학적 공격 형태는 타 문서형 악성코드와 마찬가지로 파일 또는 이메일에 당시 사회적 이슈를 매개체로 사용자의 호기심을 유발하여 공격을 수행합니다. 지금까지 문서형 악성코드에 자주 사용되었던 대표적인 사회적인 이슈는 다음과 같습니다.
- 정치/선거 주제
- 최근 사건(자연재해, 전쟁, 신제품 출시 등)
- 당시 논란이 되는 주제(코로나19, 결제문서, 뉴스, 연예인 등)
- 가짜 뉴스
문서형 악성코드에서 사용되는 사회공학적 공격 기법을 좀 더 살펴보면, 정치 및 선거 관련한 사회적 이슈, 사용자가 관심을 가질 수 있는 문서의 제목 및 내용으로 위장해 사용자가 의심 없이 전자 문서를 열도록 유도합니다. 이러한 악성 PDF 문서들은 대부분 이메일로 불특정 다수 혹은 특정 기업과 기관에 배포됩니다. PDF 문서형 악성코드는 문서 파일 자체가 악성 행위를 하지 않는 단순 껍데기일 뿐이지만, 이를 실행함으로써 악의적인 행위를 수행하는 스크립트 또는 실행 파일이 PDF 문서와 함께 실행되어 악성코드에 쉽게 노출 및 감염될 수 있으며, PC가 감염되었을 시 사용자는 이 사실조차 인지하지 못하는 경우가 대부분입니다. 더욱 심각한 문제는 PDF 자체는 정상이기 때문에 안티바이러스를 우회하기 쉽다는 것입니다. 현재 안티바이러스가 문서형 악성코드를 잘(?) 탐지하고 있어 다행이지만 점차 지능화되고 있고 더욱 복잡하고 어려운 난독화 기법을 활용하는 PDF 악성코드가 늘어나는 추세로 인해 기존 안티바이러스 제품들의 신뢰성에 의문이 들고 있습니다. 따라서 PDF 문서형 악성코드 탐지에 있어 선행화 되어야 하는 것은 흔히 알고 있는 PE(Portable Executable)형 악성코드를 탐지하는 분석 방법과는 달리 PDF 문서를 의미 단위로 분해하고, 분해된 영역을 분석하여 악성 인자를 찾아낸 후 이를 추출하는 것이 가장 중요합니다.
PDF 문서 포맷 구조와 PDF 특징
PDF 전자 문서의 내부 구조는 각 텍스트, 이미지, 코드 실행(내부함수) 요소들로 구성되어 있습니다. PDF의 구조는 그림 1과 같이 크게 버전 정보를 확인할 수 있는 ‘Header’와 PDF 문서의 내용이 들어있는 ‘Body’ 그리고 객체들이 참조할 때 사용되는 정보가 저장된 ‘Xref Table’, 파일의 구조를 추적할 수 있는 ‘File Trailer’로 구성됩니다. 더 자세한 설명은 아래와 같습니다.
- Header : PDF 파일 버전에 대한 정보가 포함되어 있습니다. 예를 들어 PDF 2.0 문서의 헤더에는 “%PDF-2.0″을 포함합니다.
- Body : 해당 영역은 일반적으로 이미지, 글꼴 및 기타 멀티미디어와 모든 ‘Text Streams’을 포함하는 문서의 모든 객체를 포함하고 있습니다. 일반적으로 사용자에게 표시되는 모든 콘텐츠를 포함하고 있는 영역이며, 압축되어있거나 압축되어있지 않은 텍스트, Streams, 이미지, JavaScript도 포함할 수 있습니다. ‘Streams’에는 ‘Stream’로 시작하여 ‘Endstream’으로 종료되는 영역에 압축 또는 본문의 문자열 정보가 저장되어 있습니다.
- Cross-reference (Xref Table): 파일에서 각 객체(Object)의 위치를 나타내는 목록들이며, 모든 객체의 오프셋과 객체들의 사용 상태를 저장합니다. 문서가 업데이트되면 ‘Xref Table’ 끝에 추가됩니다. 또한, 이 숫자의 마지막은 파일에 있는 총 객체 수를 의미합니다.
- Trailer : PDF 파일의 메타데이터를 가진 객체의 정보를 가지고 있습니다. 뷰어가 문서를 읽어야 하는 위치를 찾을 수 있도록 도와주는 역할을 하며, 파일의 마지막 줄에는 “%%EOF”로 파일의 끝을 표시합니다.
PDF의 구조가 4개로만 구성되어 단순하게 보일 수 있지만, 내부적인 구조는 다양한 형태로 더욱 복잡합니다. 그렇다면 PDF Viewer는 어떻게 PDF 파일을 읽고 표현해 화면에 출력하는지 그리고 PDF에는 어떤 특징이 있을까요?
먼저 PDF Viewer는 PDF 파일을 읽고 구문 분석을 통해 화면에 표시하는데, 먼저 ‘PDF Trailer’ 객체를 탐색해 첫 번째 객체를 찾습니다. 이후 ‘Xref Table’에 포함된 정보들을 조합하여 콘텐츠와 파일 내부를 탐색해 화면에 표시합니다. 또한, 기존 객체가 수정되거나 새 객체가 파일에 추가되면 ‘Xref Table’과 ‘Trailer’에 추가됩니다. PDF에서 ‘Body’에 포함된 정보의 형태에 따라 객체를 직접 객체(Direct Objects)와 간접 객체(Indirect Objects)로 나누어지는데 일반적으로는 숫자로 이루어지며 이를 간접 객체라고 부르고 그 외 객체는 직접 객체라고 부릅니다. 숫자로 이루어진 간접 객체는 직접 객체의 하위에 “Dictionary” “<< >>” 형태로 묶여 표현합니다. 악성 행위는 “Dictionary” 내부에서 동작하며, 압축 필터를 사용해 숨겨져 있는 경우가 대부분입니다.
정상이지만 정상이 아니야~~! (PDF 문서의 구성요소)
그림 1 에서 보듯 대부분의 악성 행위는 ‘Body’ 영역에 은닉되어 활동합니다. ‘Body’ 영역으로부터 PDF의 내용을 구성하는 객체 요소는 표 1과 같으며 ‘Boolean’, ‘Integer and Real numbers’, ‘String’, ‘Names’, ‘Arrays’, ‘Dictionaries’ 및 ‘Streams’의 8가지 개체로 구성되어 있습니다. 특히 ‘Streams’에는 삽입될 수 있는 데이터의 크기가 크고 압축 필터 사용이 가능하므로 가장 중요한 영역이며, 대부분의 악성 행위들은 ‘Names’에서 특정 객체로 수행될 때 악의적인 행위가 실행됩니다. ‘Names’는 하나의 심볼을 의미하며 한 객체에서 유일한 값이기 때문에 2개 이상 존재할 수 없습니다. 그리고 ‘Names’는 가장 먼저 악의적인 행위가 시작되는 지점이며, 관련된 심볼에는 트리거 이벤트를 수행할 때 필요한 ‘/AA’와, 문서가 열릴 때 수행될 작업을 지정하는 ‘/OpenAction’, JavaScript를 동작시키기 위한 ‘/JavaScript’ 등이 있습니다. 또한, ‘Streams’는 연속적인 바이트의 모음(이진 데이터)으로, 길이에 제약이 없어 크기가 큰 이미지 파일이나 페이지 구성하는 핵심적인 객체입니다. 공격자는 PDF의 정상적인 개체를 사용하여 난독화된 문자열과 ‘Streams’ 형태로 ‘Streams’에 데이터를 숨길 수 있습니다.
| Object Names | 설명 |
| Boolean | True, False 표현 |
| Integer and Real numbers |
정수와 실수 |
| Strings | ()괄호 안에 문자열이 표현되며 <> 는 16진수 데이터로 표현함 |
| Names | “/”로 시작되는 고유한 문자 시퀀스 |
| Arrays | “[]” 안에 연속적인 객체 표현 |
| Dictionaries | Key, Value 쌍으로 묶인 연관 테이블 |
| Streams | 연속적인 이진 데이터의 집합이며, 대부분 압축되어있음 |
| Indirect | 고유한 식별자를 이용하여 객체 참조 가능 |
PDF 문서의 정상 기능들을 이용한 악성 행위
앞서 PDF 문서 포맷과 악성 행위를 판단할 수 있는 요소들에 대해 살펴보았고, 지금부터는 PDF 문서에 어떻게 악성코드(악성 스크립트) 은닉시키고, 공격하는지 공격 방법에 대해 알아보도록 하겠습니다.
| 공격 유형 | 설명 |
| JavaScript-based | 자바스크립트 코드를 통해 악의적인 행위를 수행 |
| ActionScript-based | Adobe Flash의 ActionScript를 이용한 악의적인 공격 |
| File Embedding | 이미지 처리 라이브러리 버그, 3D 렌더링 구성요소, XML 기반 악성 Streams, 글꼴 라이브러리 버그 등을 악용 |
① JavaScript-based
JavaScript 기반의 공격은 그림 2 처럼 JavaScript 코드를 사용하여 악의적인 행위를 하는 가장 일반적인 방법입니다. JavaScript 공격 코드들은 PDF 파일 내 여러 객체로 분산되거나 하나의 객체에 포함될 수 있으며, JavaScript 기반 공격은 JavaScript 언어에 제공되는 기능이 많아 공격 방법도 다양해 PDF 파일에서 가장 많이 사용되는 공격입니다. 그중에 JavaScript를 이용하기 위한 공격 방법은 대표적으로 아래와 같이 네 가지가 있습니다.
API-based Overflow : 일반적으로 PDF 내 라이브러리에서 사용하는 API를 악용하는 방법입니다. 버퍼 오버플로 또는 ROP(Return-oriented programming) 기반으로 호출 함수 및 인자를 조작해 악의적인 행위를 수행할 수 있습니다. 대표적인 취약한 API는 “util.printf” 및 “Collab.getIcon”이 있으며, PDF 공격에 가장 처음으로 사용된 API 중 하나입니다.
Use-after-free : 해당 취약점은 해제된 메모리 영역에 다시 할당하여 재사용 함으로써 생기는 문제를 말합니다. 일반적으로 위와 같은 동작은 프로그램을 충돌하게 만들고, 취약한 프로그램에서 임의의 코드 실행해 악의적인 행위를 수행합니다.
Malformed Data : PDF 문서를 열 때 압축된 데이터가 압축이 해제되는 데이터에 의해 발생하는 공격을 말합니다. 가장 대표적인 방법 중 하나이며, 이러한 데이터들은 대부분 PDF 내부의 Streams에 저장됩니다.
Type Confusion : 말 그대로 프로그램 내에서 사용하는 변수 또는 객체를 선언했을 때와 다른 타입으로 사용할 때 발생하는 취약점을 이용한 공격입니다. 이러한 변수 또는 객체를 조작하여 임의의 코드를 실행해 악의적인 행위를 수행합니다.

② ActionScript-based
PDF 파일은 Adobe Flash 기술을 지원해 문서 내에 Flash를 사용할 수 있습니다. 하지만 이는 악의적인 Shock Wave Flash(SWF) 파일과 ActionScript 코드를 포함하여 Flash의 취약점을 이용해 그림 3과 같은 형태로 공격이 가능케 합니다. 일반적으로 JavaScript 코드와 함께 사용되며, Adobe Flash에서 주로 사용되는 ActionScript는 취약점이 많고, ActionScript를 통해 JavaScript 코드와 결합 및 활용해 악성 행위를 수행합니다. ActionScript는 아래와 같은 취약점을 통해 악의적인 행위를 수행합니다.

Memory Corruption : 메모리의 특정 포인터 값이 공격자가 제어하는 다른 메모리 영역을 가리키도록 하여 프로그램을 Crash 되게 만들어 공격하는 방식입니다. Flash를 이용한 취약점 중 가장 많이 사용되는 방법입니다.
ByteCode Verification : 공격자는 초기화되지 않은 메모리 영역에서 임의의 코드를 실행할 수 있습니다. 특히 Heap spray 및 초기화되지 않은 메모리 제어를 통해 악의적인 행위를 수행할 수 있습니다.
Corrupted File Loading : 손상된 특정 비디오 파일을 삽입시켜 실행하게 되면 발생 되는 Crash를 통해 악의적인 행위를 수행합니다.
일반적으로 Adobe Reader의 Flash 취약점은 다른 취약점보다 사용하기 어려운데, 이는 ActionScript와 JavaScript 모두 실행시켜 악의적인 행위를 성공시켜야 하기 때문입니다. 이러한 이유로 이 방법은 잘 사용하지 않고, 최근 Flash 기반기술이 사용되지 않음에 따라 Flash를 이용한 공격은 거의 발생하지 않고 있습니다.

③ File Embedding
그림 4와 같이 PDF 파일 내에 포함된 악의적인 콘텐츠를 삽입한 공격을 의미합니다. 해당 콘텐츠를 디코딩하면 코드가 실행되며, 자동 메모리 Spray가 발생해 취약점이 발생합니다. 공격에 주로 사용되는 파일은 이미지(BMP, TIFF 등)나 글꼴(TFF 등) 등이 있으며, 악성 EXE를 직접 실행하는 방법도 존재하며, 악성 EXE를 실행하면 악성 페이로드(예: VBS)가 추가로 생성될 수 있으며, 최종 목표는 실행된 후 악성코드가 실행된 흔적을 제거하는 것입니다.
PDF 문서형 취약점 및 공격 방식
지금까지 PDF 전자 문서의 포맷 구조 및 악성 행위로 사용되는 기능, 객체 통해 어떻게 공격이 이루어지는지를 살펴보았습니다. 공격자는 크게 3가지의 공격 타입을 이용하였으며, 첫 번째 “자바스크립트” 이용한 공격, 두 번째는 “ActionScript” 공격과 마지막으로 File Embedding을 이용해 PDF 문서를 악용하여 공격을 시도하였습니다.
2008년부터 최근까지 PDF 문서형 악성코드를 이용한 주요 공격 방식과 취약점은 [표 3]과 같으며, 자바스크립트 관련 취약점이 가장 많이 존재합니다. 이는 PDF를 최초로 만든 Adobe사가 “자바스크립트”를 정식으로 PDF 내에서 사용할 수 있도록 지원하기 때문이며, 공격자가 가장 접근하기 쉬운 공격 방법이기 때문이라 판단됩니다. 또한, 주목할 점은 2010년대 이후 Flash가 보안에 취약하다는 사용자들의 인식과 거부감에 따라 Flash의 사용이 줄어들었고, ActionScript 관련 취약점 또한 줄어들었습니다. 이에 최근에 공격자들도 Flash를 이용한 공격 방법을 시도하지 않는 양상을 보이는 것으로 알려졌습니다.
| Exploitation Type | Vulnerability | Vulnerabilities Type |
| JavaScript | CVE-2008-0655 | API Overflow (Collab.collectEmailInfo) |
| CVE-2008-2992 | API Overflow (util.printf) | |
| CVE-2009-0927 | API Overflow (Collab.getIcon) | |
| CVE-2009-1492 | API Overflow (getAnnots) | |
| CVE-2009-3459 | Malformed Data (FlateDecode Stream) | |
| CVE-2009-3953 | Malformed Data (U3D) | |
| CVE-2009-4324 | Use-After-free (media.newPlayer) | |
| CVE-2010-2883 | Overflow (coolType.dll) | |
| CVE-2011-2462 | Malformed U3D Data | |
| CVE-2011-4369 | Corrupted PRC Component | |
| CVE-2013-0640 | API Overflow | |
| CVE-2014-0496 | Use-After-Free (toolButton) | |
| CVE-2015-3203 | API Restriction Bypass | |
| CVE-2017-16379 | Type Confusion (IsAVIconBundleRec6) | |
| CVE-2018-4990 | Use-After-Free (ROP chains) | |
| CVE-2019-7031 | Use-After-Free | |
| CVE-2020-9715 | Use-After-Free (ROP) | |
| CVE-2021-28550 | Use-After-Free | |
| ActionScript | CVE-2009-1862 | Flash (Memory Corruption) |
| CVE-2010-1297 | ||
| CVE-2010-2884 | ||
| CVE-2010-3654 | ||
| CVE-2011-0611 | ||
| CVE-2011-0609 | Flash (Bytecode Verification) | |
| CVE-2012-0754 | Flash (Corrupted MP4 Loading) | |
| File Embedding | CVE-2009-0658 | Overflow (JBIG2) |
| CVE-2010-0188 | Overflow (TIFF) | |
| CVE-2010-1240 | Launch Action (EXE) |
글을 마치며
PDF 문서를 이용한 공격은 대부분 사람의 심리를 이용하여 사회적 공학 기법을 사용한다는 큰 특징을 가지고 있으며, 공격자는 이러한 사회공학적 공격 기법과 PDF 전자 문서의 특징 및 활용성을 잘 조합하여 원격지에서 악성코드 파일을 다운 받게 하거나 PDF에 내장되어 있는 악의적인 임의 코드를 실행하는 공격을 수행합니다. 이는 PDF 파일에 내제된 취약점을 이용한 공격 방법도 있겠지만, 현재 대부분의 PDF 악성코드는 PDF의 정상 기능을 악용하는 방식을 사용하여 공격을 수행한다고 보고되고 있습니다. 이 때문에 안티바이러스가 이를 사전에 탐지하지 못하는 문제점이 발생하고 있습니다. 또한, 향후에는 위의 글에서 다루었던 취약점 및 공격 방법 이외에도 다양한 형태로 제작된 PDF 문서형 악성코드가 출현할 것으로 예상되고 있어 문제의 심각성이 더해지고 있습니다. 따라서 PDF 악성코드 공격에 노출되지 않기 위해서는 항상 최신 버전의 PDF 사용하여야 하며, 출처가 불분명한 이메일에 첨부된 PDF 파일이나 정상 PDF처럼 보인다고 하더라도 의심이 들면 열람하지 않도록 조심해야 합니다. 다음 포스팅에서는 추출된 위험 인자 기반으로 PDF 문서형 악성코드를 분석하고 탐지하는 방법에 대해 살펴보고자 합니다.
참고 문헌
[1] Šrndic, Nedim, and Pavel Laskov. “Detection of malicious pdf files based on hierarchical document structure.” Proceedings of the 20th Annual Network & Distributed System Security Symposium. Citeseer, 2013.
[2] Singh, Priyansh, Shashikala Tapaswi, and Sanchit Gupta. “Malware detection in PDF and office documents: A survey.” Information Security Journal: A Global Perspective 29.3 (2020): 134-153.
[3] Maiorca, Davide, Battista Biggio, and Giorgio Giacinto. “Towards adversarial malware detection: Lessons learned from PDF-based attacks.” ACM Computing Surveys (CSUR) 52.4 (2019): 1-36.
[4] Kang, Ah Reum, et al. “Detection of malicious pdf based on document structure features and stream objects.” Journal of The Korea Society of Computer and Information 23.11 (2018): 85-93.
[5] “PDF 32000-1:2008 Document management — Portable document format — Part 1: PDF 1.7”, Adobe Systems Incorporated, 2008
[6] https://redhidden.tistory.com/10
[7] https://blog.naver.com/chogar/220456641206
[8] https://namu.wiki/w/PDF
[9] https://blog.ahnlab.com/1677
[10] https://nurilab.github.io/2021/05/16/fileformat_pdf/
[11] https://blog.didierstevens.com/

KAIST 사이버보안연구센터 사이버위협분석팀 연구원으로 악성코드 분석 프로그램 및 연구를 수행하고 있다.