[Anti-Exploit]‘플래시 플레이어’ 겨냥한 ‘제로데이 익스플로잇’ 공격 해부
지난 9월 어도비(Adobe)사는 어도비 플래시 플레이어에 영향을 주는 12개의 취약점을 해결하는 보안 업데이트를 발표했다. 이번 호에서는 이들 12개의 취약점 가운데 임의코드 실행으로 이어질 수 있는 힙 버퍼 오버플로우 취약점(CVE-2014-0556)에 대해 알아보자. 이 취약점은 웹 브라우저나 PDF, MS Office와 같은 문서 파일이 동작할 때 영향을 주며, 공격자는 이들 문서가 동작할 때 힙 버퍼 오버플로우를 발생시켜 악성 행위를 유발시킬 수 있다.
이 글에서는 해당 (CVE-2014-0556)취약점의 상세 분석을 통해 익스플로잇 동작 원리와 안랩 MDS의 익스플로잇 진단 방법에 대해 소개하고자 한다.
개요
어도비 플래시 플레이어에는 힙 버퍼 오버플로우(heap buffer overflow)를 발생시킬 수 있는 취약점이 존재한다. 이 취약점은 특정 함수(copyPixelsToByteArray())가 비트맵데이터 오브젝트(BitmapData object)의 위치(position) 속성을 처리하는 과정에서 인티저 오버플로우(integer overflow)를 발생시키고, 이는 결국 힙 버퍼 오버플로우를 야기시켜 정상적인 구조체 값을 덮어쓰게 되면서 발생하는 취약점이다.
CVE Reference
CVE-2014-0556
Ref1. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0556
취약점 발생 정보
Program: 인터넷 익스플로러에서는 Flash32_14_0_0_176.ocx, 파이어 폭스에서는 NPSWF32_14_0_0_179.dll이 동작할 때 발생
Function: copyPixelsToByteArray() 함수 처리할 때 발생
Parmeters: ByteArray 오브젝트(object)의 위치(position) 값이 32bit 인티저(integer) 공간을 사용하면서 발생
취약점이 발생할 수 있는 프로그램
Adobe Systems Flash Player 11.2.202.400과 이전 버전
Adobe Systems Flash Player 13.0.0.241과 이전 버전
Adobe Systems Flash Player 14.0.0.179와 이전 버전
Adobe Systems AIR 14.0.0.178과 이전 버전
취약점 발생 원인
ByteArray 클래스의 공용 속성인 위치 값에 32bit 인티저(integer) 크기의 데이터를 사용할 수 있기 때문에 비트맵데이터(BitmapData) 클래스의 공용 메소드인 copyPixelsToByteArray() 함수에서 처리하는 두 번째 변수인 ByteArray 오브젝트의 위치 값이 인티저 오버플로우를 발생시킨다. 이 함수에서 인티저 오버플로우가 발생하면, 어도비 플래시 플레이어에서는 힙 버퍼 오버플로우가 발생한다.
ByteArray 클래스는 이진 데이터 읽기/쓰기 및 사용을 최적화 하는 메소드 및 속성을 제공하고, 문제가 되는 위치(position) 속성은 ByteArray 오브젝트에 대한 파일 포인터의 현재 위치를 바이트 단위로 옮기거나 반환하게 하는 역할을 한다. ByteArray 공용 속성에 대한 설명은 어도비사에서 작성한 Ref2에 기술되어 있다.
[그림1] ByteArray 공용 속성에 대한 어도비사의 설명
Ref2. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/ByteArray.html
비트맵데이터 클래스를 사용하면 비트맵 오브젝트의 데이터(픽셀)를 처리할 수 있다. 비트맵데이터 클래스의 메소드를 사용하여 임의의 크기로 투명 또는 불투명 비트맵 이미지를 만들고 런타임 시 다양한 방식으로 이를 조작할 수 있다. 비트맵데이터 메소드를 이용하여 지정된 폭과 높이로 비트맵데이터 오브젝트를 만들 수 있고, 문제가 되는 copyPixelsToByteArray 메소드는 픽셀 데이터의 사각형 영역에서 바이트 배열을 채우는 기능으로 사용된다.
비트맵데이터 공용 메소드에 대한 설명은 어도비사에서 작성한 Ref3에 기술되어 있다.
[그림 2] 비트맵데이터 클래스 공용 메소드에 대한 어도비사의 설명
Ref3. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html
익스플로잇 동작 원리 상세 분석
지금부터 취약점을 발생시키는 액션스크립트(ActionScript)를 통해 취약점 동작 원리에 대해서 상세 분석을 진행하겠다.
분석 환경
Name: Flash32_11_4_402_287.ocx
Version: 11.4.402.287
[그림 3] Flash32_11_4_402_287.ocx가 가상 메모리에 로드된 상태
이 취약점을 상세 분석하기 위해 인터넷 익스플로러를 이용하여 html을 로딩하고, 로딩된 html 파일이 SWF(Small Web Format) 파일을 실행하면서 취약점을 발생시키는 방식을 사용한다.
[그림 4] 취약점을 유발하는 cve_2014_0556.swf 파일을 로딩하는 html 스크립트
취약점 상세 분석
어도비 플래시 파일은 SWF(Small Web Format) 파일로 배포되고, 웹 페이지나 PDF나 마이크로소프트 오피스(Microsoft Office) 등의 문서 포맷에 포함되어 사용된다.
어도비 플래시는 액션스크립트(ActionScript)라고 불리는 객체 지향형 스크립팅(object-oriented scripting) 기능을 제공한다. 플래시 디스플레이 패키지(Flash.display package)의 하나인 비트맵데이터(BitmapData) 클래스는 비트맵(픽셀)을 저장할 때 사용한다. copyPixelsToByteArray()는 비트맵의 정의된 범위에서 픽셀(picxel)을 복사하기 위해 사용하는 함수이다.
CVE-2014-0556 취약점을 일으키는 함수(copyPixelsToByteArray())의 자세한 설명과 사용법은 REF4.에 기술되어 있다.
[그림 5] CopyPixelsToByteArray() 함수에 대한 어도비사의 설명
아래 [그림 6]은 CVE-2014-0556 취약점을 발생시키는 액션스크립트 파일 내용이다. 이 스크립트 파일은 SWF 포맷으로 컴파일 되어 배포되고, 웹 브라우저, PDF나 MS 오피스 같은 문서 파일이 동작할 때 악성 행위를 유발시킬 수 있다.
[그림 6] CVE-2014-0556 취약점을 발생시키는 액션스크립트 파일
취약점이 발생하는 이유는 copyPixelsToByteArray() 함수에서 비트맵데이터 오브젝트를 처리할 때, _local1.position 값이 0xFFFFF000으로 큰 값이 들어왔기 때문이다.
파일 포인터를 저장하는 공간이 4-Byte 언사인드 인티저(unsigned integer, 부호 없는 정수) 값이기 때문에 위치(position) 값이 큰 값이 들어오면 인티저 오버플로우(integer overflow)가 발생한다. 앞서 발생한 인티저 오버플로우는 특정 구조체 값을 덮어쓰게 하여 취약점을 발현시키는 힙 오버플로우를 발생시키는 원인이 된다.
이제 취약점을 발현시키는 SWF 파일이 Flash32_11_4_402_287.ocx 내부에 로딩되어 어떻게 취약점을 유발하는지 어셈블리 레벨에서 살펴 보겠다.
아래 [그림 7]은 copyPixelsToByteArray() 함수의 어셈블리코드이다. 0x409C18D 주소에서 MOV EDX, DWORD PTR DS:[ESI+20] 은 CPU 레지스터 EDX에 취약점을 발생시키는 원인이 되는 ByteArray.position 값인 0xFFFFF000이 입력된다. 이는 [그림 3]에 있는 액션스크립트의 _local1.position = 0xFFFFF000 값이 동적으로 로딩된 것이다.
ByteArray.position 값은 4-Byte 언사인드 인티저(unsigned integer) 크기의 값인 0xFFFFFFFF까지의 값을 입력할 수 있고, 이는 copyPixelsToByteArray() 함수에서 포인터 위치 연산 값과 같이 계산되면서 인티저 오버플로우를 발생시키는 원인이 된다.
[그림 7] Flash32_11_4_402_287.ocx 모듈에서 copyPixelsToByteArray() 함수의 어셈블리코드
아래 [그림 8]에서는 0x0401C81D 주소에서 ByteArray.position 값이 CPU 레지스터 EDX에 0xFFFFF000이 입력된 것을 확인할 수 있다.
[그림 8] CPU 레지스터 EDX에 0xFFFFF000 입력
[그림 9]는 비트맵데이터의 넓이, 높이 값과 이미지 위치 좌표인 x, y 값을 입력 받는 어셈블리코드이다. 취약점을 발생시키는 액션스크립트에서 넓이, 높이 값을 조절하여, 위치 값과 함께 더해지면 인티저 오버플로우가 발생하여 공격자가 원하는 값으로 조작할 수 있게 된다.
입력 받은 가로 세로 크기 곱하기 4 를 한 값이 위치(position) 값과 합해지면서 언사인드 인터저(Unsigned integer) 값인 4byte 값을 넘어가게 되고 공격자가 원하는 값을 변수에 저장할 수 있다.
[그림 9] 비트맵데이터에서 변수 값을 입력받는 코드
[그림 10]은 비트맵데이터 변수로 입력 받은 데이터가 함수로 들어와 동작하는 과정을 설명한다. 공격자는 렉탱글(Rectangle)의 가로, 세로 값을 이용하여 0x03F1C84F 주소에서 JNB 결과를 원하는 값으로 실행할 수 있다.
[그림 10] 공격자의 입력 값을 이용해 jmp 문으로 이동하는 코드
[그림 11]의 0x03F1C85F에서 ByteArray 포인터 값을 ESI에 저장한다. 본 샘플에서 이 값은 0x8BFF00이 입력된다. 이 값에 ByteArray.position 값을 더해서 데이터를 저장할 위치를 입력받게 된다. 하지만 입력된 위치(position) 값이 0xFFFF000으로 큰 값이 입력되었기 때문에 ByteArray 포인터 값인 0x8BFF00에서 위치 값인 0xFFFF000을 더하게 되면 인티저 오버플로우가 발생하고, 이는 공격자가 힙 공간에 데이터를 쓰려고 의도한 주소로 조작이 가능하게 된다. 이 주소는 다른 함수가 사용하는 정상적인 구조체 값이 존재하는 곳이지만 인티저 오버플로우로 인해 공격자가 원하는 주소로 조작된다.
[그림 11] 인터 오버플로우로 인해 공격자가 원하는 값으로 변경되는 코드
아래 [그림 12]는 공격자가 의도하여 조작한 주소를 시작으로 힙 스프레이를 하는 코드이다. 공격자는 정상적으로 사용하는 함수의 구조체 부분을 덮어쓰게 되면 공격자가 의도한 주소를 콘트롤할 수 있게 되고, 악성 쉘코드를 실행하기 위해 ROP(Return Oriented Programming) 체인주소로 이동하여 특정 메모리 공간을 실행 영역으로 바꾼 후에 쉘코드를 실행하는 방식으로 악성 행위를 할 수 있다.
[그림 12] 힙 오버플로우를 발생시켜 정상적인 구조체 데이터를 덮어쓰는 코드
익스플로잇 진단 방법
정적 진단 방법
SWF 파일은 “FWS”나 “CWS” 두 개의 매직 코드로 구분할 수 있다. “CWS”는 압축된 형태를 나타내고, “FWS”는 압축이 풀린 상태를 나타낸다. 이 SWF 파일에서 상기 취약점을 일으키는 액션스크립트(ActionScript)를 추출하기 위해서는 디컴파일(Decompile) 과정을 거쳐야 한다. SWF를 디컴파일하여 액션스크립트를 추출한 후, 이곳에서 취약점을 일으키는 요인을 찾아 진단을 하는 방법으로 정적 진단이 가능하다.
상기 과정을 통해 디컴파일되어 얻은 액션스크립트에서 copyPixelsToByteArray(r, array);가 존재 한다면, copyPixelsToByteArray()의 두 번째 변수에서 Array.position 값이 0xF0000000 보다 큰 값이 존재하면 취약점을 일으킬 수 있는 가능성이 크기 때문에 이를 CVE-2014-0556으로 진단하는 방법으로 정적 진단이 가능하다.
하지만, 상기 정적 진단 방법은 어디까지나 액션스크립가 어지럽혀지거나 더럽혀지지(tainting) 않았다는 전제 하에 진단이 가능하다. 그 이유는 대부분의 악성 액션스크립트는 취약점을 발생시키는 트리거를 진단할 수 없도록 오염시켜 안티바이러스 엔진의 진단을 우회하기 때문이다. [그림 13]은 공격자가 정적 진단 방식을 우회하기 위해 악성 액션스크립트를 오염시킨 샘플 코드의 일부분이다.
[그림 13] 정적 분석을 우회하기 위해 액션스크립트(ActionScript)를 오염(Tainting)시킨 코드
DICA 진단 방법
안랩 MDS의 DICA 엔진에서는 CVE-2014-0556 취약점이 발생원인 되는 인티저 오버플로우(Integer Overflow) 부분을 어셈블리 단계에서 진단한다. 따라서 오염(Tainting) 또는 암호화되어 있는지의 여부와 상관없이 CVE-2014-0556 취약점을 일으키는 악성 SWF 파일이 포함하고 있는 액션스크립트(ActionScript)를 완벽하게 진단한다.
또한, DICA 엔진은 취약점이 발생한 후 ROP(Return Oriented Programming) 체인을 실행하거나 쉘코드를 실행 하는 시점에서 진단하는 알고리즘을 갖고 있기 때문에 쉘코드가 실행되고 어떤 행위가 발생하는지의 유무와 상관 없이 제로데이 익스플로잇(Zero-Day Exploit) 공격을 진단 및 방어할 수 있다. @
- AhnLab네트워크 개발실 임차성 선임연구원