최근 악의적인 PDF 파일의 수가 크게 증가하고 다양한 유포 경로와 사회적 공학기법에 기반한 신뢰관계를 이용한 유포방법 때문에 악성코드가 사용자의 시스템에 침투할 기회가 기존보다 훨씬 많아졌다. 이러한 상황에서 우선적으로 외부에서 유입되는 PDF 파일의 무결성에 대해서 의심을 해봐야 한다. 그러면 시스템에서 PDF 파일을 실행하기 전에 어떤 방법으로 파일 안에 악의적인 코드가 숨어 있는지 확인해 볼 수 있는지 알아보자.
가장 쉽고 일반적인 방법은 바이로봇 등 안티-바이러스 제품으로 PDF 파일을 진단한 후 사용하는 방법이 있다. 그러나 최근 일부 악성 PDF 파일의 경우 특정 타깃을 목표로 국지적으로 유포되므로 이런 경우에는 안티-바이러스 회사에 의심 파일을 접수해서 확인하는 방법이 있다. 그럼 어떤 PDF 파일을 의심 파일로 추정해서 샘플로 보낼 것인지에 대해서 알아보자.
악성코드 제작자는 악의적인 의도가 포함된 PDF 파일을 유포시키기 위해 여러 가지 방법을 사용한다.
이메일을 통해서 첨부파일을 열어보도록 하거나 본문의 링크 클릭 유도를 통해서 유포한다.
악의적으로 제작된 웹사이트 방문을 유도하거나 해킹된 웹사이트 방문으로 인한 악성코드 실행 및 악성 호스트로의 리다이렉션(redirection) 하는 방법 등을 통해서 유포한다.
메신저를 통해서 파일 또는 링크 클릭을 유도해서 유포한다.
PDF 파일 구조 우선 PDF 파일 구조에 대해서 간단히 알아보자. PDF 파일의 내부는 다음과 같이 돼 있다. 파일 끝부분의 trailer의 /Root 에 의해서 정의된 객체(object 2)에서부터 PDF 내용이 시작한다.
PDF 파일의 구성요소 일반적으로 PDF 파일은 다음과 같은 요소들을 포함하고 있다. PDF 파일은 많은 객체(object)들의 상호참조로 구성돼 있다.
Obj, Endobj
Stream, Endstream
Startxref, Xref
Trailer
PDF 파일의 악성코드 식별 방법 이제 PDF 파일 내에 원치 않는 악성코드가 포함됐는지 확인해 볼 수 있는 방법들을 알아보자. 일반적으로 악의적으로 제작되는 PDF파일은 trailer가 없는 경우가 많다. 대부분의 악의적인 PDF 파일은 1페이지를 가지고 있으며 JavaScript를 포함하고 있다. 다음의 경우에는 Didier Stevens의 PDFiD, Pdf-Parser 와 XORSearch 툴을 사용했지만 다양한 PDFiD 와 Pdf-Parser 툴이 존재하므로 다른 툴을 사용해도 좋다. 해당 툴의 경우 파이선(Python)으로 만들어졌기 때문에 사용하기 위해서는 시스템에 파이선을 설치해야 한다. PDFiD는 단순 스트링 스캐너(String Scanner)이며 Pdf-Parser는 보다 다양한 기능을 제공하는 PDF 구조 파서(Parser)다.
CASE 1
악의적인 PDF 파일은 일반적으로 JavaScript를 사용하므로 해당 파일에 JavaScript가 포함돼 있는지 먼저 확인한다.
91514e4f6d46d059744b4f6f4bf5224d.pdf 파일의 경우 그림 4와 같이 페이지(Page)가 하나이고 OpenAction 과 JavaScript를 포함하고 있음을 PDFiD 툴로 확인할 수 있으므로 의심스러운 파일로 추정할 수 있다. 따라서 해당 JavaScript에 어떤 데이터가 포함돼 있는지 확인해 볼 필요가 있다.
Pdf-parser.py를 이용해 --search 옵션으로 javascript 를 의심 pdf 파일에서 찾는다. 그러면 다음과 같이 object 2에서 Reference 9에 Open Action 과 Javascript가 포함돼 있음을 알 수 있다.
CASE 2
PDF 파일에 Trailer가 없고 페이지가 1개 존재하므로 의심스러우나 JavaScript가 Pdfid로 보이지 않는 경우 Pdfid는 단순한 스트링 스캐너이므로 pdf-parser의 --stats 옵션으로 더 자세한 정보를 확인한다. pdf-parser의 --stats 옵션으로 인한 상태 정보 중 Type이 /EmbeddedFile인 Object를 확인한다.
/EmbeddedFile 타입에는 Object가 9개나 있으므로 --search 옵션으로 /EmbeddedFile 타입을 가진 object의 정보를 가져와서 /Length 의 사이즈가 너무 작지 않는 것을 선택한다. 왜냐하면 악성코드가 동작하기 위해서는 어느 정도 코드 사이즈를 가지기 때문이다.
CASE 3
다음은 다른 Case의 경우를 더 알아보자.
8e987849b7001cb9 9de7fe3eabb30 4b7.pdf 파일은 Trailer가 없고 페이지가 1개이며 Javascript가 존재하므로 매우 의심스러운 파일임을 알 수 있다.
Javascript의 내용을 확인하기 위해 Javascript가 포함돼 있는 Object를 --search 옵션으로 찾는다. 다음과 같이 51, 53 Reference에 Javascript가 포함됐음을 알 수 있다.
Object 53 의 경우 FlateDecode 방식으로 압축돼 있으므로 --filter 옵션으로 압축을 해제해 가독성을 확보한다.
그림 10과 같이 javascript 로 구성돼 있으며 내용이 많으므로 리디렉션 기호(>)를 사용해 파일로 저장하면 분석하기 편리하다. Javascript의 처음 부분인 sh의 데이터를 Hex 값으로 저장한 값과 szXor=29의 16진수인 0x1D로 XOR연산을 하게 되면 그림 11과 같은 데이터가 나온다.
st 데이터는 0x9으로 XOR연산을 하고 sh 데이터는 0x13으로 XOR연산을 한다.
그러면 그림 12, 그림 13과 같은 Javascript가 된다.
그림 12의 sc의 데이터를 s2b 툴로 디코딩을 하면 그림 14와 같다.
특정 파일의 원격지 주소가 스트링(string)으로 나오지 않으므로 해당 바이너리를 어셈블리어로 확인한다. 다음과 같이 jmp 명령어를 이용해 특정 메모리 주소로 이동해서 자체 문서 내 특정 파일을 드랍한다.
XORSearch 툴을 이용하면 특정파일에서 XOR연산을 통해 특정 문자열을 검색할 수 있다. 일반적인 PE 포맷에 포함돼 있는 program 문자열을 XORSearch를 통해서 검색해 봤다. 다음과 같이 0x5DBF 오프셋에 해당 문자열이 존재함을 나타내준다. 0xA1으로 XOR연산을 하면 PE 포맷 구조를 확인할 수 있다. 따라서 해당 PDF 파일이 PE 포맷 파일을 포함하고 있으므로 특정 파일을 드랍하는 악의적인 파일임을 알 수 있다.
<글 : 황재훈 하우리 보안대응센터 코드분석팀 선임연구원(jhhwang@hauri.co.kr)>
[월간 정보보호21c 통권 제118호(info@boannews.com)]
<저작권자: 보안뉴스(www.boannews.com) 무단전재-재배포금지>