2016. 7. 24. 03:09 :: 취약점

안녕하세요 Message입니다.

오늘은 OLE 자동화 배열 취약점 분석을 주제로 포스팅하려 합니다.

초보자의 시각으로 OLE 취약점이 존재하는 웹페이지를 분석하는 글이므로,

삽질 또는 잘못된 내용이 있더라도 너그럽게 봐주시기 바랍니다.

 

 

실습환경은 Windows7 / IE / VMware 환경 입니다.

 

---------------------------------------------------------

1. OLE 자동화 배열 취약점이란?

---------------------------------------------------------

해당 취약점(CVE-2014-6332)은  IE 환경에서 발생하는 취약점 으로서,

갓모드에 진입하여 악성코드를 유포할 수 있는 취약점입니다.

 

Tip. 갓모드(GodMode)

OLE 취약점에서 갓모드는 무엇이든 할 수 있는 상태를 말합니다.

예를 들면, SafeMode에 의해 차단되는 아래와 같은 Shell Code가 동작할 수 있게됩니다.

  ex) set sh=createobject("Shell.Application")

SafeMode 뿐만 아니라 ASLR, DEP, EMET, DFI 등의 보호기술들이 다 소용없게 됩니다.

우리가 보편적으로 알고 있는 갓모드는 윈도우 OS(7, 8.1, 10)에서

아래 그림처럼 제어판의 확장인데, 혼동하면 안되겠습니다.

 

 

---------------------------------------------------------

2. 취약점 발생 원인

---------------------------------------------------------

취약점의 발생 원인은 IE에서 OLE 객체를 처리하는 과정에서 발생합니다.

OLEAUT32.dll 내부의 SafeArrayRedim() API에서 VBScript 배열의 크기를 변경하는 과정에서

충분한 에러처리를 수행하지 않아 버퍼오버플로우가 발생하게 됩니다.

OLE 취약점 발생 원인이나 동작 원리는 보안업체 블로그 등에서 상세히 확인할 수 있으며,

여기서는 실제 OLE 취약점이 존재하는 웹페이지를 살펴봅니다.

취약점에 대한 개념을 먼저 익히시고 보시면 이해하시는데 편하실겁니다.

 안랩 보안이슈 : 갓모드(GodMode) 공격의 시작, 제로데이 익스플로잇

 http://www.ahnlab.com/kr/site/securityinfo/secunews/secuNewsView.do?curPage=1&menu_dist=2&seq=23225

 

 

---------------------------------------------------------

3. 스크립트 살펴보기

---------------------------------------------------------

 

1) 전반부 : 역순으로 나열된 스크립트

OLE 취약점이 존재하는 웹페이지의 특징은 역순으로 배열되어 있는 스크립트 입니다.

이러한 특징은 분석가가 한눈에 알아보기 힘들게 만들기도 하지만

흔하지 않은 특징이라면, 보안솔루션의 탐지 시그니처가 될 수 있습니다.

아래의 그림을 참고하시면, 8~9라인에서부터 역순으로 배열된 스크립트를 볼 수 있습니다.

 

2) 중반부 : 난독화된 스크립트

엄청난 길이의 난독화 되어 있는 스크립트가 나열되어 있습니다.

이걸 복호화 하려면 제실력으로는 힘들것 같습니다.

초보인 저는 다른 방법을 강구해 보아야 겠죠?

 

3) 후반부 : VBScript

난독화된 스크립트를 지나서, 후반부는 VBScript로 구성되어 있습니다.

대부분은 함수의 선언으로 이루어져 있으며

전반부의 스크립트를 실행시키는 코드가 좀더 아랫부분에 존재합니다. (현재 그림에는 안보임)

 

 

---------------------------------------------------------

4. VBScript 스크립트 분석

---------------------------------------------------------

 

1) 역순으로 나열된 스크립트 재배열

이렇게 역순으로 나열된 스크립트를 분명 어디선가 다시 정상적으로 재배열 후에

스크립트를 적용시켜야 정상적으로 동작할겁니다.

그렇다면 textarea 태그에 지정되어 있는 ID값 lshdic200Xpage을 어디선가 사용할겁니다.

분석 초기부터 해당 ID값을 이용하여 추적했다면 좀더 빠른 분석이 가능했겠지만

저는 처음엔 이상한 문자열이네.. 생각하고 그냥 넘어갔더랬습니다.. (삽질++)

 

id값으로 스크립트의 문자열을 검색하면 StrReverse() 함수를 이용하여 텍스트를 역순으로 되돌리고

document.write() 함수를 이용하여 스크립트를 실행시키는 부분을 찾을 수 있습니다.

본래 화면에 문자열을 보이게 만드는 함수지만 스크립트 실행 용도로 사용 가능합니다.

 

정상으로 돌리는 부분을 찾아냈으니 역순으로 배열된 코드를 볼 방법은 여러가지가 생겼습니다.

단순히 document 함수를 alert()로 띄어보는 방법이 있고,

파이썬의 reversed() 함수 또는 for문을 이용해도 간단히 정상 코드를 볼 수 있습니다.

정상코드로 복원하여 alert() 함수로 띄운 내용은 아래와 같습니다.

 

 

 

2) SafeMode 해제, 갓모드로 진입

팝업창의 내용을 살펴보면 Begin() 이라는 함수의 내용입니다.

아래 그림처럼, VBScript가 있었던 후반부에서 Begin() 함수를 실행시킵니다.

사실, 후반부는 함수의 선언이 대부분이고, 한줄 적혀있는 Begin() 실행이 다입니다.

우리가 팝업으로 띄운 스크립트가 사실상 메인의 역할을 하고 있다고 보면 됩니다.

 Tip. 앞으로 등장할 VBScript 문법

 1. <script> </script> : VBscript는 단일 웹페이지에서 여러 개의 <script> </script> 문단을 가질 수 있습니다.

 2. dim arr(num) : 배열선언 / 주의점 : arr(10)으로 선언했을 경우 11개의 배열요소를 가짐(0부터 10까지)

 3. redim Preserve arr(5) : 배열 크기 변경, Preserve 명령 사용 시 이전 배열값은 유지

 4. Sub 서브루틴이름(매개변수) ... End Sub : 반환값 없는 함수

 5. Function 함수이름(매개변수) ... End Function : 반환값 있는 함수 / 함수이름 = 반환값

 6. For start=시작값 to 종료값 step 증감 : 반복횟수를 알고있는 경우 반복문 / 빠져나오려면 exit for 사용

 7. inStr() : 주어진 문자열에서 특정 문자열을 찾아서 그 위치를 반환 / 찾지 못하면 0 값을 반환

 8. IsObject() : 유효한 ActiveX 또는 OLE 자동화 객체를 참조하는지 여부 반환 / Trure or False

 9. cInt() : 인자로 전달된 값을 integer형으로 반환

 10. varType(변수) : 변수의 타입을 상수로 반환 / 부동소수점의 경우 반환값은 4

 11. randomize(number) : number를 사용하여 Rnd 난수 발생기를 초기화하고 새 시드값을 제공

 12. rnd(number) : 0보다 크고너 같고 1보다 작은 난수 값 반환, number의 값은 난수 발생 방법 결정

                                - num < 0 : number를 시드로 하여 매번 같은 수

                                - num > 0 : 순차적으로 생성되는 그 다음의 난수

                                - num = 0 : 가장 최근에 생성한 난수

                                - num = x : 순차적으로 생성되는 그 다음의 난수

 

 

3) Begin 파헤치기(1)

Begin() 함수의 내용을 본격적으로 살펴봅니다. 

먼저 위쪽의 내용을 살펴보면 Navigetor.UserAgent로 얻어낸 값을 instr() 함수를 이용하여

사용자 PC의 WIn64 여부와 IE환경이 맞는지 체크하고 있습니다.

info에 어떤 값이 담기는지 궁금해서 출력해보았습니다.

 

 

이후 BeginInit()과 Create() 함수를 연달아 호출합니다.

각 함수의 역할은 아래와 같습니다.

--------------------------------------------------------------------------------------------------------

1. BeginInit()

- 버퍼오버플로우를 일으키기 위한 배열 2개와 변수 초기화

- aa(5) : OLE취약점 발생시키기 위한 배열1

- ab(5) : OLE취약점 발생시키기 위한 배열2

- a0 : 랜덤초기화 후에, 숫자를 계속 높이며 취약점 발생 조건을 찾는데 사용

- a3 : 랜덤초기화 후에, a0를 계속 증가시키는 증감변수로 사용

 

2. Create()

- 내부의 Over() 함수를 이용하여 취약점 조건 만듬

- 배열 aa와 ab가 8바이트 간격으로 동적 할당 되어 취약점이 발생할 때까지 반복

--------------------------------------------------------------------------------------------------------

 

 

 

Create() 함수 내부에는 Over() 함수가 존재합니다.

해당 함수의 내용은 아래와 같습니다.

 Over()

 - Begininit()에서 초기화한 배열 2개(aa, ab)를 이용하여 취약점을 발생시킴

 - aa배열과 ab배열이 8바이트 차이를 두고 동적 할당 될 경우 취약점 발생 조건이 만족됨

 - redim을 통한 aa의 배열 재할당은 실패하지만, VBScript의 배열 정보가 담긴 SAFEARRAY구조체에서는 확장된 크기값이 저장됨 

 - intVersion 값이 대부분 높으므로 아랫부분의 else 이후에 초점을 맞춰서 해석 진행

 - aa(a1)의 VarType을 체크할 경우, ab(0)에 할당한 부동소수점(1.123456...) 값이 결과값으로 반환됨 => 취약점 발생 성공

 

 

취약점이 발생하려면 aa와 ab가  8바이트를 두고 동적 할당이 되어야 합니다. 

그런데 조건 상태가 복잡하여 표로 나타내 보았습니다.

 a0 = 1 + a3(=2) = 3  / a0는 BeginInit()에서 13+@로 할당됨

 a1 = 3 + 2 = 5

 a2 = a0(=1) + h8000000

 a3 = 2(증감연산자)  / a3는 BeginInit()에서 7+@로 할당됨

위 조건대로 진행될 경우 아래와 같이 type1=h2f66이 성립되어 Over=True가 됩니다.

 

 

4) Begin 파헤치기(2)

Over() 함수를 통하여 취약점이 발생되는 조건을 달성한 뒤에는

VBScript에서 파일생성과 cmd 명령어 실행 등을 자유롭게 수행할 수 있도록

IE의 보호모드(SafeMode)를 해제하는 setnotsafemode() 함수를 실행시킵니다.

해당 함수를 실행시키기 이전에 정상적인 값에 덮어 씌울 myarray 값을 초기화 합니다.

myarray값은 SAFEARRAY구조체의 값에 SafeMode 플래그인 0x1E를 0으로 바꾸어 놓는 값입니다.

-----------------------------------------------------------------

-> 01 00 80 08 01 00 00 00 00 00 00 00 00 00 00 00

-> 00 00 FF 7F 00 00 00

-----------------------------------------------------------------

 

 

setnotsafemode() 함수의 처음에 mydata() 함수를 실행시키게 되는데

아래와 같이 배열을 할당하고, 아무 기능을 수행하지 않는

더미 함수(=testaa)의 주소값을 리턴합니다.

 

여기서 i=teataa를 할당하고 바로 아래에서 null을 할당한 것을 보고 멘붕이 왔습니다.

검색해보니 VBScript에서 Function Object의 주소를 얻는게 불가능하다고 하더군요.

그래서 나온 꼼수가 바로 이것입니다.

i=testaa 구문을 만나면 testaa 값이 스택에 쌓입니다.

이후에 i에 할당하려 하지만 오류가 발생합니다.

그리고 "On Error Resume Next" 구문에 의하여 다음라인의 i=null을 만나게 됩니다.

하지만 i의 값이 null로 대체 되는것이 아니라 스택에 쌓인 인자값,

즉 testaa의 주소값에 vt 플래그만 0x01(null)로 대체 된다고 합니다.

결국은 i에 Function Object Address가 할당됩니다 :)

 

아래는 해외 사이트에서 이것을 테스트한 것을 일부 가져왔습니다.

null을 할당하자 vt 플래그만 대체되어 04350001이 되고, 결국 testaa의 주소값을 나타내게 됩니다.

URL : http://www.secniu.com/how-to-use-vbscript-to-turn-on-the-god-mode/

 

mydata()에서 설정하는 값의 배치가 어려워서 표로 나타내면 아래와 같습니다.

aa(a1), aa(a1+2)의 값과 타입에 값을 입력한 것을 알 수 있습니다.

해당 설정들은 이후에 실행할 readmemo()와 setnotsafemode()의 나머지 부분에서 사용됩니다.

 

 

4) Begin 파헤치기(3)

이제 safemode를 해제할 일만 남았습니다. 하지만 여기서 분석이 안되는 부분이 있었습니다.

 

- 첫번째 의문점입니다.

안랩 보안이슈에서 공개된 내용을 보게 되면

--------------------------------------------------------------------------------------------------------

"기본적으로 IE는 특정한 조건 하에서만 VBScript가 실행되도록 제한하며,

VBScript를 실행하기 전에 OleScript 객체 안에 있는 세이프모드를 확인"

--------------------------------------------------------------------------------------------------------

그렇다면 세이프모드를 해제하기 전까지 실행되고 있는 VBScript는 왜 실행되고 있는것인가?

이 부분에대해서 위의 URL의 초반부에 이러한 내용과 함께 예제가 있더군요.

 

한마디로 Shell.Application과 같은 Create Object 함수의 경우 SafeMode에 의해서 차단된다는...

그래서 아래와 같이 간단히 테스트해본 결과 MsgBoX는 띄워진 반면,

계산기 프로그램은 실행되지 않았습니다.

즉, SafeMode를 해제하는 평범한(?) 스크립트는 Script Engine이 SafeMode를 체크하지 않는다는 결론입니다.

 

 

- 두번째 의문점

CScriptEntryPoint 주소가 왜 더미 Sub에서 8바이트 떨어진 곳에 위치하냐는 점입니다.

아직 왜 그러한지 알아내지 못했습니다. 조금 더 연구가 필요할 것 같습니다.

원래 그런것이니 그렇다고 하면 초보 분석가인 저는 그저 상처받을뿐

이부분에 아시는분은 댓글을 남겨주시면 감사하겠습니다.

 

 

5) 갓모드 진입 후 어떤 행위가..?

갓모드로 진입한 이후에는 runmumaa() 함수를 통하여 원하는 소스코드를 실행시킵니다.

실행흐름을 따라가 보면 아래 그림처럼

runmumaa()는 runurl()을 호출하고

runurl()에서 흐름이 끊기는것처럼 보입니다.

 

하지만 alert() 함수로 for문이 끝난 후에 runurl을 출력해보면

아래와 같이 rechange(t) 함수를 document.write()함수를 통해 실행시키는 것을 볼 수 있습니다. 

 

rechange() 함수에 넘어가는 인자값 t와 난독화가 해제된 문자열을 출력해보면

중반부에 나오는 난독화된 문자열이 드디어 모습을 드러냅니다.

 

 

위의 스크립트의 내용을 정리하면 아래와 같습니다.

---------------------------------------------------------------------------------------------------------------------

1. TEMP 경로에 uninst.gif.vbs 파일 생성 및 echo 기능으로 내용 작성

2. cmd 콘솔에서 vbs 파일을 실행시킬 수 있는 cscript.exe 기능을 이용하여 작성한 vbs 실행

3. 파일명과 인자값 2개(URL, 파일경로) 넘김

4. Get명령어를 이용하여 URL에 접근 후 악성코드 다운로드

5. 악성코드 실행

---------------------------------------------------------------------------------------------------------------------

일단 OLE취약점이 발생하게 되어 SafeMode가 해제되게 되면

이후의 행동은 위에서 분석한 shell 실행 말고도 다양한 행동이 가능할 겁니다.

하지만 이러한 케이스를 많이 접할수록 악성행위들의 패턴에 대해 인지하는데 도움이 많이 될 것 같습니다.

 

 

---------------------------------------------------------

5. 마치며

---------------------------------------------------------

생각보다 포스팅이 길어졌습니다.

분석이라는 것이 개발분야를 알아야 좀더 수월하다는걸 다시 알게됩니다.

중간중간 제가 봐도 이해안되는 문맥의 단절과 설명되지 않는 부분이 많은 것 같습니다...

그럼에도 긴글 읽어주셔서 감사합니다.

틀린점이나 부족한 점은 언제든지 댓글 달아주세요. 감사합니다.

 

posted By Message.

Commit your way to the LORD, trust in him and he will do this. [PSALms 37:5]

 

posted by Red_Message